vue2 + webpack2 單頁應(yīng)用nginx的集群部署策略

前言

公司新項(xiàng)目是使用springboot作為后端的微服務(wù),前端就讓我自己搗鼓用現(xiàn)在比較火的vue來做的分離前端,邊學(xué)邊做折騰了一個(gè)月,項(xiàng)目也差不多了完成了一個(gè)功能,準(zhǔn)備發(fā)布下測(cè)試環(huán)境了,但是問題來了.服務(wù)器上的后端服務(wù)是接入了cas中央認(rèn)證服務(wù)的單點(diǎn)登錄的(cas接單頁應(yīng)用真的很費(fèi)勁啊,有時(shí)間就寫下來).所以是基于https的,所以和同事商量,那就使用nginx大法搭建一個(gè)全站https吧

vue2項(xiàng)目中的配置

  • 在webpack配置里主要還是config/index.jsassetsPublicPath的設(shè)置
  //config/index.js
  module.exports = {
  build: {
    testEnv: require('./test.env'),
    prodEnv: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/leo-face/',    //配置的是nginx下根目錄新建的一個(gè)leo-face文件夾
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },
  dev: {
    env: require('./dev.env'),
    port: 8089,
    autoOpenBrowser: true,
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {},
    // CSS Sourcemaps off by default because relative paths are "buggy"
    // with this option, according to the CSS-Loader README
    // (https://github.com/webpack/css-loader#sourcemaps)
    // In our experience, they generally work as expected,
    // just be aware of this issue when enabling this option.
    cssSourceMap: false
  }
}

注意: 項(xiàng)目是用vue-cli腳手架搭建的,就有這個(gè)config目錄

  • 構(gòu)建的配置路徑弄好了.就要執(zhí)行相應(yīng)的命令了
npm run build:test
  • 附上packagejsonscript的命令
"build:test": "cross-env NODE_ENV=testing npm_config_preview=true  npm_config_report=true node build/build.js",
  • vue-cli生成的模板是沒有這個(gè)命令的,這是我自己自定義的命令.首先會(huì)找到build/build.js讀取相應(yīng)配置,讀取的還是webpack.prod.conf.js這個(gè)配置,但是我在這個(gè)webpack profile中做了一些修改
 // 調(diào)用方法,判斷引入的后端接口地址
//這樣一來,引入的就上面build.js對(duì)象中的testEnv的配置了
 var env = process.env.NODE_ENV === 'testing'
  ? config.build.testEnv
  : config.build.prodEnv

//plugins的HtmlWebpackPlugin修改
 new HtmlWebpackPlugin({
      filename: process.env.NODE_ENV === 'testing'
        ? 'index.html'
        : config.build.index,
      template: 'index.html',
      favicon: resolveApp('leo-face.ico'),
      inject: true,
      minify: {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      },
      path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
      // necessary to consistently work with multiple chunks via CommonsChunkPlugin
      chunksSortMode: 'dependency'
    }),

//下面是test.env.js的配置
var merge = require('webpack-merge')
var devEnv = require('./dev.env')

module.exports = merge(devEnv, {
  NODE_ENV: '"testing"',
  BASE_API: '"https://testx.xxx.net/leo"',   //整個(gè)應(yīng)用后端請(qǐng)求的地址
}) 
  • 打包環(huán)境配置好了,包也打好了生成的目錄就是這樣的,下圖
WX20170830-222558@2x.png
  • 現(xiàn)在還不能直接去折騰nginx,因?yàn)檫€有個(gè)重要的設(shè)置沒有更改,如果你的項(xiàng)目中使用的vue-router,想部署上服務(wù)器有優(yōu)雅的路徑,那么現(xiàn)在就需要設(shè)置你的router對(duì)象屬性了
//創(chuàng)建路由
export default new Router({
  mode:'history',  
  base: '/leo-face/',
  routes: constantRouterMap
});

參數(shù)我就不說明了,百度,官方一堆介紹

  • 好了下面可以去折騰一下nginx了,由于我在本地已經(jīng)搭建過nginx,也沒有問題,所以就直接上服務(wù)器折騰.

Nginx 相關(guān)配置

  • 服務(wù)器是linux的,和mac的差別不大.但是因?yàn)槲沂怯胔omebrew裝的nginx,只是目錄有點(diǎn)不一樣而已,附上自己三腳貓的畫圖功夫的流程圖.
image.png

https域名入口服務(wù)器的nginx.conf配置,這臺(tái)服務(wù)器是215

  • linux上的nginx/config目錄nginx.conf配置
    //后端服務(wù)負(fù)載策略
    upstream leo {
        server   xxx.xxx.xxx.213:8424 weight=1;
        server   xxx.xxx.xxx.214:8424 weight=1;
    }
  //前端負(fù)載策略
    upstream leo-face {
        server   xxx.xxx.xxx.213:443 weight=1;
        server   xxx.xxx.xxx.214:443 weight=1;
    }

 //server配置
  server {
        listen       443;
        server_name  testx.xxx.net;

        ssl on;

        ssl_certificate      "name.pem"
        ssl_certificate_key  "name.key";

        ssl_session_cache    shared:SSL:10m;
        ssl_session_timeout  10m;
        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;

        ssl_ciphers  HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM;
        ssl_prefer_server_ciphers  on;

        location ~ /leo-face {
            access_log logs/leo-faceacc.log main;
            error_log logs/leo-face.log warn;
            proxy_pass https://leo-face;
            proxy_redirect          off;
            proxy_set_header        Host            $host:443;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout   180;
            proxy_send_timeout      180;
            proxy_read_timeout      180;
            proxy_buffer_size       128k;
            proxy_buffers           4 128k;
            proxy_busy_buffers_size 128k;
            proxy_temp_file_write_size 128k;
            add_header  Nginx-Cache "$upstream_cache_status";
        }

        location ~ /leo {
            access_log logs/leoacc.log main;
            error_log logs/leo.log warn;
            proxy_pass https://leo;
            proxy_redirect          off;
            proxy_set_header        Host            $host:443;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_connect_timeout   180;
            proxy_send_timeout      180;
            proxy_read_timeout      180;
            proxy_buffer_size       128k;
            proxy_buffers           4 128k;
            proxy_busy_buffers_size 128k;
            proxy_temp_file_write_size 128k;
            add_header  Nginx-Cache "$upstream_cache_status";
        }
    }

重啟nginx服務(wù)器訪問測(cè)試nginx的https是否開啟

轉(zhuǎn)發(fā)服務(wù)器nginx.conf的配置

server {
    listen       443;
    server_name  xxx.xxx.xxx.213;

    location /leo-face {
        try_files $uri $uri/ /leo-face/index.html;   
        root   /opt/nginx/html;
        index  index.html index.htm;
    }

    ssl on;

    ssl_certificate      "name.pem"  
    ssl_certificate_key  "name.key";

    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout  10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;

    ssl_ciphers  HIGH:!RC4:!MD5:!aNULL:!eNULL:!NULL:!DH:!EDH:!EXP:+MEDIUM;
    ssl_prefer_server_ciphers  on;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

相關(guān)說明:

  • 213 服務(wù)器的證書可以從入口服務(wù)器215上面拷貝一份過來,保持一致,ssl配置也可以拷貝
  • try_files $uri $uri/ /leo-face/index.html;由于頁面是由js內(nèi)部進(jìn)行加載的,匹配當(dāng)前url的所有地址,沒有頁面重定向到index.html. 官方說明
  • 有人覺得我后臺(tái)服務(wù)為什么沒有配置ssl? 上圖已經(jīng)聲明了,后端springboot微服務(wù)使用的是consul這個(gè)分布式服務(wù)發(fā)現(xiàn)和共享配置的解決方案,在應(yīng)用啟動(dòng)時(shí)讀取了consul配置中心開啟的springboot應(yīng)用內(nèi)置tomcat容器的ssl配置..并且證書放在應(yīng)用包中.

發(fā)布

  • 配置全部都完成了,接下來就是關(guān)鍵的點(diǎn)了.發(fā)布你的前端應(yīng)用,記得前面打包好的文件了吧.
    • 在nginx負(fù)載轉(zhuǎn)發(fā)出去的應(yīng)用服務(wù)器上(文章中是213,214倆臺(tái)服務(wù)器)的nginx/html目錄下新建一個(gè)leo-face目錄.把文件拷貝進(jìn)去.
    • 現(xiàn)在你的訪問目錄就應(yīng)該像這樣https://test.xxx.net/leo-face
    • 啟動(dòng)nginx或者重啟nginx,nginx -s reload
  • 新建文件夾的名稱是因?yàn)橹按虬鼤r(shí)webpack中配置了assetsPublicPath的路徑就是這個(gè)名字,所以在index.html引入的js,css地址前綴也會(huì)帶這個(gè)名稱
  • 好了,現(xiàn)在訪問一下看看,OK~ 完美...
https main.png

會(huì)遇到的問題

  • nginx入口服務(wù)器 配置相同域名多個(gè)訪問路徑時(shí).是有匹配規(guī)則的,比如我把leo-face放在leo下就不能訪問到/leo-face這個(gè)地址了
  • 如按照文章中的順序無法接入成功,則 先可以配置基于http單點(diǎn)應(yīng)用服務(wù)器的nginx是否可以正常訪問前端應(yīng)用.后面再將https入口服務(wù)接入負(fù)載轉(zhuǎn)發(fā)到應(yīng)用服務(wù)器上

以上內(nèi)容就是這個(gè)前端的單頁應(yīng)用發(fā)布測(cè)試環(huán)境的所有步驟了.但是發(fā)布正式環(huán)境可能還不是完全一致

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容