jackieli123723 / jackieli123723.github.io

✅lilidong 个人博客
9 stars 0 forks source link

node+nginx+express+pm2+vue2全家桶部署遇到的坑记录 #29

Open jackieli123723 opened 6 years ago

jackieli123723 commented 6 years ago

遇到的问题

1.打包策略的白屏解决方案

npm run build 是先把dist删除然后在用express启动服务会导致打包过程中项目白屏-用一个临时目录来杜绝这类现象--/dist--copy--/deploy

2.静态图片资源的端口代理转发

http://118.190.17.174:5000/static/img/banner2@2x.a5a86fd.png(显示)
http://118.190.17.174:808/static/img/banner2@2x.a5a86fd.png(不显示)
pm2启动的是5000端口要转发到808端口需要设置
location / {
   proxy_set_header Host 5000;
 }
然后重启  [root@ali-ly-basic-data-118 sbin]# ./nginx -s reload
http://118.190.17.174:5000/static/img/banner2@2x.a5a86fd.png(显示)
http://118.190.17.174:808/static/img/banner2@2x.a5a86fd.png(显示)

3.静态资源的压缩

要把打包处理的css和js文件静态资源开启gzip
必须指定server_name 用一个解析域名
server {
         listen 808;
          server_name test.dataworker.ilongyuan.com.cn;(必须指定)
 }

----
   upstream ly-mall-c {
                # Nodejs app upstream
                server 127.0.0.1:5000;
                keepalive 64;
    }

   server {
                listen 808;
                server_name test.dataworker.ilongyuan.com.cn;
                location / {
                        # Proxy_pass configuration
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        #proxy_set_header Host $http_host;
                        proxy_set_header Host 5000;
                        proxy_set_header X-NginX-Proxy true;
                        proxy_http_version 1.1;
                        proxy_set_header Upgrade $http_upgrade;
                        proxy_set_header Connection "upgrade";
                        proxy_max_temp_file_size 0;
                        proxy_pass http://ly-mall-c/;
                        proxy_redirect off;
                        proxy_read_timeout 240s;
                }

        }

4.pm2的长时间监听

用一个脚本来重启
pm2 start deploy.js --name longyuan-mall-c --watch

┌─────────────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬───────────┬────────┬──────────┐
│ App name        │ id │ mode │ pid   │ status │ restart │ uptime │ cpu │ mem       │ user   │ watching │
├─────────────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼───────────┼────────┼──────────┤
│ longyuan-mall-c │ 0  │ fork │ 24352 │ online │ 118     │ 12m    │ 0%  │ 32.4 MB   │ worker │ enabled  │

5.图片的闭合标签

img 遵守html5的闭合不然打包出来上线后该图片一直报错找不到

6.pm2配置NODE_ENV=production 关闭devTool

//main.js
//添加
const isDebug_mode = process.env.NODE_ENV !== 'production';
Vue.config.debug = isDebug_mode;
Vue.config.devtools = isDebug_mode;
Vue.config.productionTip = isDebug_mode;

//pm2启动
NODE_ENV=production pm2 start deploy.js --name longyuan-mall-c --watch

7.node实现静态资源压缩和日志监听

 var port = process.env.PORT || 5000;
 var express = require('express');
 var fs = require('fs');
 var path = require('path');
 var app = express();

//Content-Encoding:gzip node压缩静态资源
 var compression = require('compression');
 app.use(compression());

 // 引入log4j,并且加载配置文件
 var log4js = require('log4js');
 log4js.configure('logconfig/log4j.json');
 app.use(log4js.connectLogger(log4js.getLogger("http"), {
   level: 'trace'
 }));

 var logger = log4js.getLogger('deploy.js');
 // 引入log4j,并且加载配置文件

 app.use(express.static(path.join(__dirname, '/dist')));

 //quick and dirty vue server-side routing
 app.get('*', (req, res) => {
   // console.log(res);
   logger.info('成功返回了dist打包路由');
   res.send(fs.readFileSync(path.join(__dirname, '/dist/index.html'), 'utf8'));
 })

 app.listen(port, () => {
   console.log(`代码部署成功访问端口http://localhost:${port}`);
   logger.info(`代码部署成功访问端口http://localhost:${port}`);
 });

 //更改端口$ PORT=9000 node deploy.js

8.linux中node变量

[worker@aws-bigdata-csdata-viewer ~]$ whereis node
node: /home/worker/softs/node-v6.10.2-linux-x64/bin/node
[worker@aws-bigdata-csdata-viewer ~]$ cd /home/worker/softs/node-v6.10.2-linux-x64/bin
[worker@aws-bigdata-csdata-viewer bin]$ ll
total 29796
lrwxrwxrwx 1 worker worker       35 Apr 20  2017 fis-velocity -> ../lib/node_modules/jello/bin/jello
lrwxrwxrwx 1 worker worker       35 Apr 20  2017 jello -> ../lib/node_modules/jello/bin/jello
-rwxrwxr-x 1 worker worker 30503659 Apr  4  2017 node
lrwxrwxrwx 1 worker worker       38 Apr  4  2017 npm -> ../lib/node_modules/npm/bin/npm-cli.js
[worker@aws-bigdata-csdata-viewer bin]$ ./node npm -v
3.10.10
[worker@aws-bigdata-csdata-viewer bin]$ ./node npm install -g pm2

//切换root
[worker@ali-ly-basic-data-118 ~]$ sudo su
[root@ali-ly-basic-data-118 worker]#

-rwxrwxr-x 1 worker worker 5202242 May 25  2016 nginx
[worker@aws-bigdata-csdata-viewer sbin]$ ./nginx -s reload
nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /home/worker/nginx/conf/nginx.conf:1
nginx: [alert] kill(27078, 1) failed (1: Operation not permitted)
[worker@aws-bigdata-csdata-viewer sbin]$ sudo su
[root@aws-bigdata-csdata-viewer sbin]# ./nginx -s reload
[root@aws-bigdata-csdata-viewer sbin]# sudo worker
sudo: worker: command not found
[root@aws-bigdata-csdata-viewer sbin]# ll
total 5084
-rwxrwxr-x 1 worker worker 5202242 May 25  2016 nginx
[root@aws-bigdata-csdata-viewer sbin]# su worker
[worker@aws-bigdata-csdata-viewer sbin]$

注意环境变量的用户权限
先找到node
在 ./node npm -v(前面添加./node 才能执行然后后面的就不用添加了)

9.linux使用npm切换淘宝镜像cnpm

使用淘宝npm镜像

镜像使用方法(三种办法任意一种都能解决问题,建议使用第三种,将配置写死,下次用的时候配置还在):

1.通过config命令

npm config set registry https://registry.npm.taobao.org 
npm info underscore (如果上面配置正确这个命令会有字符串response) 
2.命令行指定

npm –registry https://registry.npm.taobao.org info underscore 
3.编辑 ~/.npmrc 加入下面内容

registry = https://registry.npm.taobao.org

使用cnpm

使用cnpm替代默认的npm:

npm install -g cnpm –registry=https://registry.npm.taobao.org

10.vue-cli脚手架安全策略

//config/index.js

  build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../dist/index.html'),
    assetsRoot: path.resolve(__dirname, '../dist'),
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    productionSourceMap: false,
    // 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: true,
    productionGzipExtensions: ['js', 'css']
  },

在http里gzip压缩传输可以极大的优化资源下载速度(试验值:800k -> 200k);

以前的做法一般都是在http服务器上面打开动态的gzip, 这样服务器会消耗CPU的资源来进行gzip压缩。

在vue-cli生成的项目配置文件里面config/index.js

  // 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'],
按提示先在项目里执行npm install --save-dev compression-webpack-plugin, 然后将productionGzip的值改为true.

这样我们在执行 npm run build 的时候生成的dist/static/js目录里面会产生与js文件对应的.gz包, 将这些文件一起上传到服务器。接下来需要进行nginx的 gzip_static配置

首页先确保nginx 已安装 gzip_static 模块,具体安装自行google, 然后在nginx.conf里添加,并重启nginx

  location ~* \.(js|css)$ {
    gzip_static on;
  }
到此配置结束,可以访问看效果了。

11.Nginx端口代理坑(域名可以走系统端口 ip不能走系统端口)

//域名解析要到部署的服务器上(server默认80)

修改脚本文件权限

[worker@aws-bigdata-csdata-viewer rms]$ chmod 775 front_ly_rms_onlineTest.sh
-rwxrwxr-x  1 worker worker       769 Nov 28 14:25 front_ly_rms_onlineTest.sh

//pm2 改变端口启动

PORT=4900 pm2 start deploy.js --name longyuan-rms-front --watch

6000 | x11 [X] | X 窗口系统服务
-- | -- | --

http://118.190.17.174:4900(ip不能用系统端口就可访问)
http://118.190.17.174:6000(ip方式不能用linux系统端口)
http://test.rms.ops.dragonest.com(用不用系统都可以看用域名访问)

[系统端口]('https://www.cnblogs.com/bethal/p/5736857.html')

12.个性化版权webpack

//注入的文件头上添加
<%= htmlWebpackPlugin.options.systemInfo %> 

//prod.js
      new HtmlWebpackPlugin({
            filename: process.env.NODE_ENV === 'testing'
                ? 'index.html'
                : config.build.index,
           // systemInfo: htmlSystemInfo((Date.now())),    
            template: 'index.html',
            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.staticPath,
            // necessary to consistently work with multiple chunks via CommonsChunkPlugin
            chunksSortMode: 'dependency'
        }),

13.pm2 本地centos虚拟机记录问题

eg:1.生成配置文件

[root@localhost vue-longyuan-store-front]# pm2 start deploy.js --name longyuan-vue-mall-admin 
[PM2] Starting /home/worker/node-server/vue-longyuan-store-front/deploy.js in fork_mode (1 instance)
[PM2] Done.
┌─────────────────────────┬────┬──────┬───────┬────────┬─────────┬────────┬─────┬──────────┬──────┬──────────┐
│ App name                │ id │ mode │ pid   │ status │ restart │ uptime │ cpu │ mem      │ user │ watching │
├─────────────────────────┼────┼──────┼───────┼────────┼─────────┼────────┼─────┼──────────┼──────┼──────────┤
│ longyuan-vue-mall-admin │ 0  │ fork │ 24715 │ online │ 0       │ 0s     │ 0%  │ 3.2 MB   │ root │ disabled │
└─────────────────────────┴────┴──────┴───────┴────────┴─────────┴────────┴─────┴──────────┴──────┴──────────┘

eg:2.加watch参数后没一会进程挂了

 Use `pm2 show <id|name>` to get more details about an app
[root@localhost vue-longyuan-store-front]# pm2 start deploy.js --name longyuan-vue-mall-admin --watch
[PM2][ERROR] Script already launched, add -f option to force re-execution
┌─────────────────────────┬────┬──────┬──────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name                │ id │ mode │ pid  │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
├─────────────────────────┼────┼──────┼──────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ longyuan-vue-mall-admin │ 0  │ fork │ 6884 │ online │ 133     │ 0s     │ 0%  │ 25.5 MB   │ root │ enabled  │
│ longyuan-vue-mall-api   │ 1  │ fork │ 6890 │ online │ 76      │ 0s     │ 0%  │ 27.1 MB   │ root │ enabled  │

[root@localhost vue-longyuan-store-front]# pm2 list
p┌─────────────────────────┬────┬──────┬───────┬──────────┬─────────┬────────┬─────┬────────┬──────┬──────────┐
│ App name                │ id │ mode │ pid   │ status   │ restart │ uptime │ cpu │ mem    │ user │ watching │
├─────────────────────────┼────┼──────┼───────┼──────────┼─────────┼────────┼─────┼────────┼──────┼──────────┤
│ longyuan-vue-mall-admin │ 0  │ fork │ 22720 │ stopping │ 648     │ 0      │ 0%  │ 0 B    │ root │ enabled  │
│ longyuan-vue-mall-api   │ 1  │ fork │ 22726 │ stopping │ 591     │ 0      │ 0%  │ 0 B    │ root │ enabled  │

解决办法把watch 参数干掉 (有可能是node版本或者pm2或者虚拟机的bug没深究)

eg:3.两种模式启动

fork:pm2 start api.js -x --name longyuan-vue-admin-api
cluster : pm2 start deploy.js --name longyuan-vue-amin -i max -e err.log -o out.log

[root@localhost vue-longyuan-store-front]# pm2 start api.js -x --name longyuan-vue-admin-api
[PM2] Starting /home/worker/node-server/vue-longyuan-store-front/api.js in fork_mode (1 instance)
[PM2] Done.
┌────────────────────────┬────┬─────────┬───────┬────────┬─────────┬────────┬─────┬───────────┬──────┬──────────┐
│ App name               │ id │ mode    │ pid   │ status │ restart │ uptime │ cpu │ mem       │ user │ watching │
├────────────────────────┼────┼─────────┼───────┼────────┼─────────┼────────┼─────┼───────────┼──────┼──────────┤
│ longyuan-vue-admin-api │ 1  │ fork    │ 24890 │ online │ 0       │ 0s     │ 0%  │ 10.8 MB   │ root │ disabled │
│ longyuan-vue-amin      │ 0  │ cluster │ 24793 │ online │ 0       │ 8m     │ 0%  │ 28.9 MB   │ root │ disabled │
└────────────────────────┴────┴─────────┴───────┴────────┴─────────┴────────┴─────┴───────────┴──────┴──────────┘
jackieli123723 commented 6 years ago

另外用静态资源分离dist目录来打包用node做服务器启动

const express = require('express')
const path = require('path')
const opn = require('opn')

const server = express()
const host = 'http://localhost:8082'
server.use('/assets', express.static(path.resolve(__dirname, './assets')))
server.use('/dist', express.static(path.resolve(__dirname, './dist')))

server.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, './index.html'));
})

server.listen(8082, () => {
  console.log(`server started at ${host}`)
  opn(host)
})