欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

node.js怎樣自動(dòng)化部署項(xiàng)目

小編給大家分享一下node.js怎樣自動(dòng)化部署項(xiàng)目,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

保山網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)!從網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開發(fā),運(yùn)營維護(hù)。成都創(chuàng)新互聯(lián)從2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)。

一、功能設(shè)計(jì)

9.9元的阿里云服務(wù)器真的很慢,但還是足夠折騰完這個(gè)項(xiàng)目。
用3個(gè)目錄來模擬不同的環(huán)境。

目錄存放
project存放所有的項(xiàng)目,比如本系統(tǒng)的前后端代碼。
pre-dir預(yù)發(fā)環(huán)境,當(dāng)然是用來測試的。
pro-dir生產(chǎn)環(huán)境,測試沒問題,部署上線。

一圖勝千言。

node.js怎樣自動(dòng)化部署項(xiàng)目

二、系統(tǒng)頁面

我的任務(wù)

接到一個(gè)新的需求,可以新建一個(gè)需求,并創(chuàng)建開發(fā)分支。

node.js怎樣自動(dòng)化部署項(xiàng)目

發(fā)布隊(duì)列

開發(fā)結(jié)束之后,便可以到發(fā)布隊(duì)列中,部署到預(yù)發(fā)環(huán)境進(jìn)行測試。 測試通過指定Cookie 就可以訪問到測試的代碼。最終再進(jìn)行線上部署。

 node.js怎樣自動(dòng)化部署項(xiàng)目

項(xiàng)目信息

node.js怎樣自動(dòng)化部署項(xiàng)目 

二、技術(shù)棧

前端技術(shù)棧
Vue + elementUI,具體代碼在Github,感興趣的可以看下并點(diǎn)個(gè)star哈~?
服務(wù)端技術(shù)棧
非常常見的Node.js(Koa2) + MySQL + redis + Pm2。
具體代碼在Github,感興趣的可以看下并點(diǎn)個(gè)star哈~?

三、Redis和Session配置

// utils/Store.js
const 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看起來更優(yōu)雅,也是通過中間件

// 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配置了,因?yàn)椴皇呛苁煜?,一直在試錯(cuò)、踩坑。不過還好終于成功了!
前后端項(xiàng)目通過Nignx提供服務(wù),Node服務(wù)通過Nginx轉(zhuǎn)發(fā),主要是為了驗(yàn)證各種環(huán)境。
如果不設(shè)置Cookie,默認(rèn)訪問的就是線上環(huán)境,設(shè)置Cookie 就會走到預(yù)發(fā)布測試環(huán)境,用于測試。

# cookie 取TEST 賦值給$proxy_node
map $cookie_TEST $proxy_node {
  default "";
  "1"   "1";
  "2"   "2";
  "3"   "3";
}

# 發(fā)布管理系統(tǒng)前端設(shè)置
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;
  }
}

# 發(fā)布管理系統(tǒng)后端設(shè)置
# 反向代理到node服務(wù)
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項(xiàng)目前端設(shè)置
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設(shè)置

解決跨域,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');

    // 這個(gè)響應(yīng)頭的意義在于,設(shè)置一個(gè)相對時(shí)間,在該非簡單請求在服務(wù)器端通過檢驗(yàn)的那一刻起,
    // 當(dāng)流逝的時(shí)間的毫秒數(shù)不足Access-Control-Max-Age時(shí),就不需要再進(jìn)行預(yù)檢,可以直接發(fā)送一次請求。
    ctx.set('Access-Control-Max-Age', 3600 * 24);
    if (ctx.method == 'OPTIONS') {
      ctx.body = 200; 
    } else {
      await next();
    }
  }
}

登錄

這個(gè)系統(tǒng)屬于強(qiáng)制登錄的,登錄統(tǒng)一進(jìn)行了處理。

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已經(jīng)過期~',
        data: '',
        err_code: 1,
        success: false,
      };
    }

    if (redisData && redisData.uid) {
      console.log(`登錄了,用戶uid為${redisData.uid}`);
      await next();
    }
  }
}

七、操作shell腳本

舉個(gè)例子,創(chuàng)建項(xiàng)目分支

let path = ''; // 項(xiàng)目路徑
// 創(chuàng)建分支
const branch_name = `branch_${new Date().getTime()}`;
cp.execSync(`/data/dandelion-server/shell/createBranch.sh ${path} ${branch_name}`);
#!/bin/bash

cd $1
git pull origin master
git checkout -b $2
git push --set-upstream origin $2

八、連接數(shù)據(jù)庫

config.js配置文件

let dbConf = null;
const DEV = {
  database: 'dandelion',  //數(shù)據(jù)庫
  user: 'root',  //用戶
  password: '123456',   //密碼
  port: '3306',    //端口
  host: '127.0.0.1'   //服務(wù)ip地址
}

const PRO = {
  database: 'dandelion',  //數(shù)據(jù)庫
  user: 'root',  //用戶
  password: '123456',   //密碼
  port: '3306',    //端口
  host: 'xx.xx.xx.xx'   //服務(wù)ip地址
}
dbConf = PRO; //這個(gè)可以通過判斷區(qū)分開發(fā)環(huán)境
module.exports = dbConf;

數(shù)據(jù)庫連接文件

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層調(diào)用了~

const {query} = require('../common/mysql');

class UserModel {
  constructor() {}

  /**
   * @description: 根據(jù)pid和did創(chuàng)建一個(gè)分支
   * @param {pid} 項(xiàng)目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為服務(wù)器IP

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

以上是“node.js怎樣自動(dòng)化部署項(xiàng)目”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:node.js怎樣自動(dòng)化部署項(xiàng)目
轉(zhuǎn)載源于:http://aaarwkj.com/article40/jjghho.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司標(biāo)簽優(yōu)化、品牌網(wǎng)站建設(shè)虛擬主機(jī)、網(wǎng)站排名面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

綿陽服務(wù)器托管
熟妇高潮一区二区在线观看| 欧美一级免费黄片在线播放| 日本一区二区高清网址| 亚洲日本韩国视频久久精品| 日韩欧美人妻中文字幕| 亚洲av乱码一区二区三| 美日韩黄色大片免费看| 免费看欧美黄片在线看| 国产aaa级日本一区二区三区| 国产亚洲综合另类色专区| 国产日韩精品一区二区三区在线 | 亚洲国产精品中文字幕一区久久| 欧美亚洲午夜一二综合| 国产精品久久久av大片| 国产精品黑丝美女91| 97门久欧美日韩久久| 国产精品一区二区剧情熟女| 亚洲黄色成人免费观看| 欧美丰满熟妇视频在线| 日本一区二区三区在线观看视频| av中文字幕亚洲一区二区| 亚洲国产精品性色av| 欧美亚洲另类不卡在线| 夫妻过性生活视频播放| 蜜桃网站视频免费观看 | 日本av二区三区在线| 国产爆操美女在线观看| 日本一区二区三区免费精品| 91九色在线免费观看| 成人午夜性色福利视频| 亚洲国产日韩精品自拍av| 久久成人激情免费视频| 2023天天操夜夜操| 日韩中文字幕乱码一区| 国产av不卡精品影片| 熟妞人妻精品一区二区视频| 日韩精品一区二区三区电影在线播放 | 国内精品免费视频不卡| 激情欧美一区二区三区精品| 自拍日韩亚洲一区在线| 亚洲黄色片大奶子水多|