亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

如何自動化部署項目?折騰服務器之旅~

2024-05-06 16:49:59
字體:
來源:轉載
供稿:網友

本篇文章講的不是如何把一個項目部署上線,而是如何自動化上線。

開發了一個需求管理和發布系統。

通過這個系統,可以創建需求、創建發布計劃、創建分支、部署到測試環境、部署到生產環境、正式上線、合并代碼等。

一、功能設計

9.9元的阿里云服務器真的很慢,但還是足夠折騰完這個項目。
用3個目錄來模擬不同的環境。

 

目錄 存放
project 存放所有的項目,比如本系統的前后端代碼。
pre-dir 預發環境,當然是用來測試的。
pro-dir 生產環境,測試沒問題,部署上線。

 

一圖勝千言。

自動化部署項目,服務器

二、系統頁面

我的任務

接到一個新的需求,可以新建一個需求,并創建開發分支。

自動化部署項目,服務器

發布隊列

開發結束之后,便可以到發布隊列中,部署到預發環境進行測試。 測試通過指定Cookie 就可以訪問到測試的代碼。最終再進行線上部署。

 自動化部署項目,服務器

項目信息

自動化部署項目,服務器

二、技術棧

前端技術棧
Vue + elementUI,具體代碼在Github,感興趣的可以看下并點個star哈~?
服務端技術棧
非常常見的Node.js(Koa2) + Mysql + Redis + Pm2。
具體代碼在Github,感興趣的可以看下并點個star哈~?

三、Redis和Session配置

 

// utils/Store.jsconst Redis = require("ioredis");const { Store } = require("koa-session2"); class RedisStore extends Store {  constructor() {    super();    this.redis = new Redis();  }   async get(sid, ctx) {    let data = await this.redis.get(`SESSION:${sid}`);    return JSON.parse(data);  }   async set(session, { sid = this.getID(24), maxAge = 1000 * 60 * 60 } = {}, ctx) {    try {      console.log(`SESSION:${sid}`);      // Use redis set EX to automatically drop expired sessions      await this.redis.set(`SESSION:${sid}`, JSON.stringify(session), 'EX', maxAge / 1000);    } catch (e) {}    return sid;  }   async destroy(sid, ctx) {    return await this.redis.del(`SESSION:${sid}`);  }} module.exports = RedisStore;
// 入口文件const session = require("koa-session2");const Store = require("./utils/Store.js");// session配置app.use(session({  store: new Store(),  key: "SESSIONID",}));

 四、Router配置

為了Router看起來更優雅,也是通過中間件

// 1、middleware配置文件const routers = require('../routers');module.exports = (app) => {  app.use(routers());}// 2、index.js入口文件const middleware = require('./middleware');middleware(app);// 3、routers 注冊文件const Router = require('koa-router');const router = new Router();const koaCompose = require('koa-compose');// 接口入口const {insertDemand} = require('../controllers/demand/insertDemand');const {deleteDemand} = require('../controllers/demand/deleteDemandByDid');const {updateDemand} = require('../controllers/demand/updateDemandByDid');// 加前綴router.prefix('/api');module.exports = () => {  // 新增需求  router.get('/insertDemand', insertDemand);  // 刪除需求  router.get('/deleteDemand', deleteDemand);  return koaCompose([router.routes(), router.allowedMethods()]);}

五、nginx配置

最頭痛的就是nginx配置了,因為不是很熟悉,一直在試錯、踩坑。不過還好終于成功了!
前后端項目通過Nignx提供服務,Node服務通過Nginx轉發,主要是為了驗證各種環境。
如果不設置Cookie,默認訪問的就是線上環境,設置Cookie 就會走到預發布測試環境,用于測試。

# cookie 取TEST 賦值給$proxy_nodemap $cookie_TEST $proxy_node {  default "";  "1"   "1";  "2"   "2";  "3"   "3";}# 發布管理系統前端設置server {  listen    80;  server_name test.xue.com;  if ($proxy_node = ''){    set $dollar "/data/pro-dir/dandelion/dist/";  }  if ($proxy_node = "1") {    set $dollar "/data/pre-dir/dandelion/dist/";  }  location / {    root $dollar;    index index.html;    try_files $uri $uri/ /index.html;  }}# 發布管理系統后端設置# 反向代理到node服務server {  listen    80;  server_name m.xue.com;  if ($proxy_node = ''){    set $dollar "/data/pro-dir/study-demo/";  }  if ($proxy_node = "2") {    set $dollar "/data/pre-dir/study-demo/";  }  location / {    root $dollar;    index index.html;  }}# demo項目前端設置server {  listen    80;  server_name api.xue.com;  location / {    if ($proxy_node = "") {      set $from 3001;      proxy_pass http://47.107.188.55:3001;    }    if ($proxy_node = "3") {      set $from 3002;      proxy_pass http://47.107.188.55:3002;    }  }}

六、一些中間件

常用的HTTP設置

解決跨域,OPTIONS請求,攜帶Cookie憑證等問題。

module.exports = () => {  return async (ctx, next) => {    ctx.set('Access-Control-Allow-Origin', 'http://test.xue.com');    ctx.set('Access-Control-Allow-Credentials', true);    ctx.set('Access-Control-Allow-Headers', 'content-type');    ctx.set('Access-Control-Allow-Methods', 'OPTIONS, GET, HEAD, PUT, POST, DELETE, PATCH');    // 這個響應頭的意義在于,設置一個相對時間,在該非簡單請求在服務器端通過檢驗的那一刻起,    // 當流逝的時間的毫秒數不足Access-Control-Max-Age時,就不需要再進行預檢,可以直接發送一次請求。    ctx.set('Access-Control-Max-Age', 3600 * 24);    if (ctx.method == 'OPTIONS') {      ctx.body = 200;     } else {      await next();    }  }}

登錄

這個系統屬于強制登錄的,登錄統一進行了處理。

const Store = require("../../utils/Store");const redis = new Store();module.exports = () => {  return async (ctx, next) => {    // 白名單    if (ctx.request.url === '/api/login') {      return await next();    }     const SESSIONID = ctx.cookies.get('SESSIONID');    if (!SESSIONID) {      return ctx.body = {        mes: '沒有攜帶SESSIONID~',        data: '',        err_code: 1,        success: false,      };    }    const redisData = await redis.get(SESSIONID);    if (!redisData) {      return ctx.body = {        mes: 'SESSIONID已經過期~',        data: '',        err_code: 1,        success: false,      };    }    if (redisData && redisData.uid) {      console.log(`登錄了,用戶uid為${redisData.uid}`);      await next();    }  }}

七、操作shell腳本

舉個例子,創建項目分支

let path = ''; // 項目路徑// 創建分支const branch_name = `branch_${new Date().getTime()}`;cp.execSync(`/data/dandelion-server/shell/createBranch.sh ${path} ${branch_name}`);
#!/bin/bashcd $1git pull origin mastergit checkout -b $2git push --set-upstream origin $2

八、連接數據庫

config.js配置文件

let dbConf = null;const DEV = {  database: 'dandelion',  //數據庫  user: 'root',  //用戶  password: '123456',   //密碼  port: '3306',    //端口  host: '127.0.0.1'   //服務ip地址}const PRO = {  database: 'dandelion',  //數據庫  user: 'root',  //用戶  password: '123456',   //密碼  port: '3306',    //端口  host: 'xx.xx.xx.xx'   //服務ip地址}dbConf = PRO; //這個可以通過判斷區分開發環境module.exports = dbConf;

數據庫連接文件

const mysql = require('mysql');const dbConf = require('./../config/dbConf');const pool = mysql.createPool({ host: dbConf.host, user: dbConf.user, password: dbConf.password, database: dbConf.database,})let query = function( sql, values ) {  return new Promise(( resolve, reject ) => {    pool.getConnection(function(err, connection) {      if (err) {        reject( err )      } else {        connection.query(sql, values, ( err, rows) => {          if ( err ) {            reject( err )          } else {            resolve( rows )          }          connection.release()        })      }    })  })}module.exports = {  query,}

就可以在model層調用了~

const {query} = require('../common/mysql');class UserModel {  constructor() {}  /**   * @description: 根據pid和did創建一個分支   * @param {pid} 項目id   * @param {did} 需求id   * @param {branch_name} 分支名   * @return: 分支信息   */  async insertBranchInfo(sqlParams) {    const sql = 'insert branch_info (pid, bid, branch_name, pub_time) values(?,?,?,?)';    console.log(sql)    let data = await query(sql, sqlParams, (err, result) => {      return result;    });    return data;   }}

九、域名

沒有買域名,通過本地修改hosts(可以直接用工具)

47.107.188.xx為服務器IP

47.107.188.xx test.xue.com
47.107.188.xx api.xue.com
47.107.188.xx m.xue.com

 總結

算是第一次自己搭建一個完整的項目,從前端到后端。

尤其是后端,作為一個前端小白,從學習如何使用服務器,到Linux/Vim/Shell/Nignx/Pm2/Redis/Session/Mysql/Koa2。沒有像以前一樣,直接拿別的項目看,而是一步一個腳印的學習,雖然也都是皮毛,但是感覺自己的知識體系豐富了很多。也去了解了很多持續集成的知識,當然我做的小項目還是比較簡單的啦~ 喜歡就點個贊鼓勵一下吧,(^__^) 嘻嘻……
詳細的使用都在前端項目、后端項目,感興趣的可以看下并點個star哈~?

 以上所述是小編給大家介紹的自動化部署項目詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩精品在线电影| 91精品久久久久久久| 欧美日韩美女在线| 国产精品久久久久国产a级| 最近免费中文字幕视频2019| 亚洲精品第一国产综合精品| 日韩久久免费电影| 久久国产精品电影| 国产亚洲人成a一在线v站| 亚洲成人网久久久| 久久91亚洲精品中文字幕| 亚洲精品成人网| 91久久久亚洲精品| 亚洲一区二区国产| 国产欧美在线视频| 亚洲天堂av电影| 国产精品一久久香蕉国产线看观看| 这里只有精品久久| 国产亚洲视频在线观看| 精品福利在线观看| 中文字幕欧美视频在线| 欧美激情va永久在线播放| 2019中文字幕全在线观看| 精品久久久视频| 色多多国产成人永久免费网站| 日本中文字幕不卡免费| 欧美人与性动交| 国产一区二区三区在线视频| 按摩亚洲人久久| 久久伊人免费视频| 国产精品91视频| 亚洲国产私拍精品国模在线观看| 国产精品三级久久久久久电影| 亚洲第一天堂无码专区| 久久久久久高潮国产精品视| 久久精品视频免费播放| 88xx成人精品| 欧美性一区二区三区| 午夜精品一区二区三区在线视频| 亚洲精品网址在线观看| 国产女同一区二区| 日韩久久午夜影院| 久久艳片www.17c.com| 亚洲精品久久久久久久久久久久久| 日韩美女免费观看| 91精品国产91久久久久| 欧美性xxxx| 91精品在线一区| 久久亚洲精品国产亚洲老地址| 久久九九精品99国产精品| 亚洲综合日韩中文字幕v在线| 国产一区二区三区在线视频| 日韩电影免费在线观看| 亚洲精品一区av在线播放| 在线观看国产精品91| 国产精品99久久99久久久二8| 96sao精品视频在线观看| 18性欧美xxxⅹ性满足| 亚洲精品美女久久久久| 久久全球大尺度高清视频| 亚洲精品国产欧美| 国外成人在线直播| 欧美在线激情视频| 7777免费精品视频| 亚洲一区美女视频在线观看免费| 国产精品综合不卡av| 久久久久久久香蕉网| 久久久av网站| 日韩视频在线观看免费| 美日韩精品视频免费看| 精品久久久999| 北条麻妃久久精品| 国产精品h在线观看| 欧美日韩在线视频一区| 大胆人体色综合| 亚洲激情视频在线观看| 欧美巨乳美女视频| 色噜噜亚洲精品中文字幕| 亚洲性线免费观看视频成熟| 国产精品中文字幕在线| 在线播放精品一区二区三区| 欧美日韩亚洲成人| 色诱女教师一区二区三区| 国产精品成人久久久久| 亚洲欧美综合v| 中文字幕亚洲一区在线观看| 久久精品精品电影网| 欧美理论在线观看| 欧美成人精品在线视频| 日韩有码在线播放| 国产一区二区日韩精品欧美精品| 国产999精品视频| 日韩av免费在线看| 日本伊人精品一区二区三区介绍| 亚洲精品国产精品自产a区红杏吧| 亚洲国产天堂网精品网站| 日本午夜在线亚洲.国产| 国产成人综合精品在线| 亚洲精品电影网在线观看| 国产在线观看不卡| 欧美大片欧美激情性色a∨久久| 欧美麻豆久久久久久中文| 亚洲影视九九影院在线观看| 日韩欧美在线视频日韩欧美在线视频| 欧美大片在线影院| 久久免费高清视频| 精品美女国产在线| 久久久久久久影视| 欧美日韩美女在线| 国产精品视频公开费视频| 亚洲精品自在久久| 久久色精品视频| 国产精品欧美在线| 91久久精品久久国产性色也91| 久久久久久亚洲精品| 日韩动漫免费观看电视剧高清| 亚洲男人天堂网站| 亚洲在线观看视频网站| 国产视频综合在线| 国产精品自拍小视频| 国产成人精品视频| 日韩成人在线视频观看| 亚洲自拍小视频免费观看| 国产精品香蕉国产| 色偷偷av一区二区三区| 国产精品狼人色视频一区| 97精品视频在线观看| 日韩经典中文字幕在线观看| 美女999久久久精品视频| 欧美日韩成人精品| 韩国三级电影久久久久久| 国产精品揄拍一区二区| 久久久久国色av免费观看性色| 午夜精品一区二区三区在线视频| 成人激情电影一区二区| 欧美激情xxxx性bbbb| 国产精品视频网| 中文在线资源观看视频网站免费不卡| 欧美亚洲成人免费| 日韩精品在线私人| 91高清免费在线观看| 日韩激情视频在线| 久久精品国产96久久久香蕉| 国产91对白在线播放| 精品国产户外野外| 亚洲激情免费观看| 日韩欧美一区二区三区| 国产日本欧美一区二区三区| 亚洲人精选亚洲人成在线| 欧美成在线视频| 成人精品视频在线| 色偷偷9999www| 日韩欧中文字幕| 色婷婷av一区二区三区在线观看| 亚洲国产一区二区三区四区| 在线日韩精品视频| 狠狠色噜噜狠狠狠狠97| 一区二区三区视频免费| 狠狠色狠狠色综合日日五| 国产999精品久久久| 热久久美女精品天天吊色| 97超级碰在线看视频免费在线看| 中日韩午夜理伦电影免费| 亚洲成人中文字幕|