美文网首页
pm2:从小白到写出一键部署前后端工程

pm2:从小白到写出一键部署前后端工程

作者: 贺贺v5 | 来源:发表于2021-06-30 17:43 被阅读0次

    背景

    基于公司KPI自我学习进步,以及我本人是负责后台管理系统开发维护的大环境背景下,我决定研究并开发了,拖拽生成代码的工具,目前完成的功能有: 拖拽生成 Table 页面和拖拽自动生成 Form 表单。

      1. 拖拽生成 Table 页面
      • 拖拽组件,从菜单栏到中间区域,或者同区域内更换位置,不同区域可以更换,只是目前,没有一个组件是会同时可以出现在 2 个区域的,所以此功能暂时无法看到;
      • 单击编辑属性
      • 右击删除
      • 生成代码
        • 可直接复制
        • 可生成文件并下载 zip 包
      1. 拖拽自动生成 Form 表单
        拖拽生成 form 表单,从左侧菜单栏中,将 form 元素拖到中间区域,可根据右上角的「N 列布局」输入你想要的 N 列布局,中间区域的各个 form 表单元素,可自由拖拽更换位置。可以点击这里来使用。此功能第一个版本可以看到的有:
      • 可以生成是单列,双列或者 N([1,10]) 列
      • 可以拖拽生成组件
      • 添加普通校验:必填
      • 单击编辑属性
      • 右击删除
      • 生成代码
        • 可直接复制
        • 可生成文件并下载 zip 包
      • 解决拖拽过程中定位不准确的 bug

    简介

    该项目前后端分离,前端是react写的,后端是node写的一个非常小的服务,用于生成目录文件,以及压缩zip包来下载生成的代码。写这个项目也主要是为了自己走一遍前端从开发到部署的所有流程。

    本人主业是前端工程师,node是自己感兴趣想学的,所以写的只能说功能上还能用,代码质量渣的xx。

    学习步骤

    项目目录介绍


    image.png

    原始农业

    刚开始,只为满足功能,能跑起来就OK。
    纯手工部署。步骤如下:

    前端部分

    先登录服务器,将,代码git clone 下来,然后cd service目录下执行npm install

    # 在本地项目执行命令
    # 正确来说,应该在服务器上执行这个命令,鉴于我的阿里云服务器内存很小,就在本地执行。但是基于工作经历来说,我们有的线上项目,大型后,在线上服务器进行build也会很慢,有时候还会卡死,所以在本地build也没什么薄饼。
    npm run build
    
    # 拷贝(在本地执行)
    # 服务器上的路径,/srv/front,直接将文件夹重命名为front
    # 注意:一定要在该项目目录下进行
    scp -r build root@ssh root@47.105.**.**:/srv
    
    # 在服务器执行
    # 登录服务器
    ssh root@47.105.xxx.xxx
    cd /srv/
    # 删除旧的文件
    rm -rf front/
    # 重命名build为front
    mv build front
    

    后端部分

    # 登录远程服务器
    ssh root@47.105.xxx.xx
    
    # 更新代码
    cd /srv/bms-code-auto-generate
    git pull origin master
    
    # 远程启动后端,如果已经启动着,需要先关闭再重新启动
    nohup node index.js &
    # 关闭后端服务
    ps aux | grep node
    kill -9 pid
    

    近代农业

    等完成部署后,就发现这样每次都很麻烦,因为不想每次更新了代码,再去手动重启一遍node,这时候想起来了pm2,它可以在监控到文件更新后,去自动重启服务,所以就想着应用上pm2。

    PM2 是一个守护进程管理器,它将帮助您管理和保持您的应用程序 24/7 在线。
    nodejs的高级生产流程管理器。

    也有其他解释:

    而pm2是基于nodejs开发的进程管理器,适用于后台常驻脚本管理,同时对node网络应用有自建负载均衡功能。官方的说法,pm2 是一个带有负载均衡功能的Node应用的进程管理器,个人认为,并不准确,因为pm2支持多种语言,只是对于除node之外的其他进程无负载均衡的能力。 - 知乎

    第一版 简单使用pm2 去启动index.js文件

    在服务器上。

    # 启动后端服务,pm2版本,
    ## 全局安装pm2
    npm install -g pm2
    ## 改用pm2来启动程序--watch表示,监控程序运行状态,一旦:服务异常:自动重启;服务发生变化:自动重启
    pm2 start index.js --watch
    

    这样启动的node进程,有个问题,就是我的下载文件xxx.zip文件是保存在tmp目录下,每当我一点下载的时候,node进程就会重启。

    image.png

    重启的时候有时候会导致下载链接失败。


    image.png

    这是在请教做node的同学时的聊天截图继续,所以moduleName一个是cvb,下载的zip文件名确是666600.zip,有点对不上,因为不是同一个时间段的,是后来写文的时候翻看的聊天记录。

    后来发现,去掉--watch不会重启,并且下载链接不会报错,但是,这时候,又出现了一个问题,就是,当代码有更新时,node服务并不会自动重新启动,这就又回到了“原始农业”时代,我觉得应该监控文件是可配置的,这时候发现,得去学习一下pm2啦,于是我去翻看了pm2的官方文档,找到了ignore_watchecosystem.config.js文件。

    于是有了,在/service/目录下添加文件:ecosystem.config.js

    image.png
    将代码更新到服务上去后,可以使用命令pm2 start ./service/ecosystem.config.js 进行启动,这样启动的就比较方便了。

    备注

    pm2起的项目路径这样的:


    image.png

    在其中是会包含current和source的。我们需要手动,在source下,添加git仓库的地址,项目源码是在这里面的。

    current -- 当前服务运行的文件夹(是source的软链接)
    share -- log pid 等共享数据 (我目前的项目中没有这个文件)
    source -- clone 下来的源代码
    -- 简书友

    现代农业

    虽然上面的后端部署方式有了很大的改进,但是还是有个弊端就是,需要每次登陆服务器并且去手动拉代码,这样很麻烦。

    于是写了一个一键部署的命令。

    后端 v1.0

    在原有的文件:ecosystem.config.js中进行扩展。

    module.exports = {
        apps: [
            {
                name: 'generate',
                script: './index.js',
                // instances: 1,
                watch: true,
                ignore_watch: ['[/\\]./', 'node_modules', 'tmp']
            }
        ],
        deploy: {
            daily: {
                user: 'root',
                host: ['47.105.xx.xx'],
                ref: 'origin/node',
                repo: 'git@github.com:springHyc/bms-code-auto-generate.git',
                path: '/srv/hehe/bms-code-auto-generate3',
                'post-deploy': 'git pull && cd service &&   npm install && npm run daily',
                env: {
                    NODE_ENV: 'daily'
                }
            }
        }
    };
    

    配合package.json中添加命令:

    "scripts": {
            "daily": "NODE_ENV=daily  pm2 startOrRestart ecosystem.config.js"
        },
    

    这样直接在本地运行:pm2 deploy ./service/ecosystem.config.js daily,即可完成,自动拉取最新的代码,并且完成重启目的。

    在第一次执行前,应该进入目录/srv/hehe/bms-code-auto-generate3中,手动新建mkdir source这个文件夹,不然后报错。

    image.png

    然后还要将/srv/hehe/bms-code-auto-generate3目录下clone项目git clone origin git@github.com:***c/bms-code-auto-generate.git,再将项目名称更改为source

    后端 v2.0

    上面的方式,仍然不太好,因为在本地运行的时候,ecosystem.config.js文件是放在./service/目录下的,我们能不能将ecosystem.config.js文件放在根目录下呢?继续研究试验...

    在根目录下新建ecosystem.config.js文件:

    // 在v1.0版本和v2.0版本中,我们将命令的名字做了更改。
    module.exports = {
        apps: [
            {
                name: 'node-generate',
                script: './index.js',
                cwd: './service/',
                watch: false,
                log_date_format: 'YYYY-MM-DD HH:mm Z'
            }
        ],
        deploy: {
            daily: {
                user: 'root',
                host: ['47.105.**.**'],
                ref: 'origin/node',
                repo: 'git@github.com:springHyc/bms-code-auto-generate.git',
                path: '/srv/hehe/bms-code-auto-generate3',
                'post-deploy': 'git pull && cd service && npm install && cd ../ && npm run deploy-node',
                env: {
                    NODE_ENV: 'daily'
                }
            }
        }
    };
    
    

    配合package.json中添加命令:

    "deploy-node": "NODE_ENV=daily pm2 startOrRestart ecosystem.config.js",
    "deploy-end": "pm2 deploy ecosystem.config.js daily",
    

    这样在本机根目录下执行npm run deploy-end即可完成,自动拉取最新的代码,并且完成重新部署的目的。

    前端

    至于前端代码,我们没有做build相关的优化,所以前端代码的打包很简单,只需要build,然后将build出来的build/目录拷贝到服务器的某个位置,like: /srv/hehe/bms-code-auto-generate3/build,然后配置好ngnix代理即可。

    手动部署的命令是:

    # 在本地项目执行命令
    # 正确来说,应该在服务器上执行这个命令,鉴于我的阿里云服务器内存很小,就在本地执行。但是基于工作经历来说,我们有的线上项目,大型后,在线上服务器进行build也会很慢,有时候还会卡死,所以在本地build也没什么薄饼。
    npm run build
    
    # 拷贝(在本地执行)
    # 服务器上的路径,/srv/front,直接将文件夹重命名为front
    # 注意:一定要在该项目目录下进行
    scp -r build root@ssh root@47.105.**.**:/srv/hehe/bms-code-auto-generate3
    

    那我们能不能写个命令让它自动执行呢?可以啊

    就是这个,在package.json中添加命令:

    "deploy-front": "npm run build && scp -r build root@47.105.**.**:/srv/hehe/bms-code-auto-generate3",
    

    那现在我们执行npm run deploy-front就可以部署前端啦。

    那现在有想了,我们可不可以把前后端部署命令合并成一个命令呢?分开都麻烦啊☹️

    于是就有了这个命令,在package.json中添加命令:

    "deploy": "npm run deploy-end && npm run deploy-front"
    现在我们执行npm run deploy就可以自动部署前后端啦。


    前端部署还有一种方式,是直接在服务器上build的,由于我们有内部包的限制,外网无法访问通,所以上面我一直采用的是本地build的方式。

    服务器上build方式为:

    // ecosystem.config.js文件中添加
    deploy: {
            daily2: {
                user: 'root',
                host: ['47.105.**.**'],
                ref: 'origin/node',
                repo: 'git@github.com:springHyc/bms-code-auto-generate.git',
                path: '/srv/hehe/bms-code-auto-generate3',
                'post-deploy': 'git pull && npm i --registry=http://shuqudata.registry.com && npm run build',
                env: {
                    NODE_ENV: 'daily2'
                }
            }
        }
    // package.json中添加
     "deploy-front-remote": "pm2 deploy ecosystem.config.js daily2",
    

    然后执行npm run deploy-front-remote即可。
    这个地方注意,build后,build文件路径在/source/根目录下,要进行nginx配置才可以访问。

    备注

    为什么我会把项目/srv/hehe/bms-code-auto-generate3放在这个目录上呢,因为这是个从无到有的尝试过程,我原本在/srv/是手动起着一套前后端的,我不想破坏正在启动着的应用。

    • 服务上ngnix配置
    # 路径:/etc/nginx/sites-enabled/
    # 文件名:hehe-bms (其实是随便起的,只是为了试验)
    server {
            listen       8080;
            server_name  47.105.**.**;
    
        location /api {
                proxy_pass  http://localhost:3003; // 后端地址
            }
    
        location / {
            root /srv/hehe/bms-code-auto-generate3/build/; // 前端路径
            index index.html index.htm;
                try_files $uri $uri/ /index.html;
            }
    }
    

    注意,nginx配置修改后,一定要重启nginx,不然不生效。重启命令nginx -s rolad,想要学习有关nginx的命令请看我的总结

    • ecosystem.config.js
    module.exports = {
        apps: [
            {
                name: 'node-generate',
                script: './index.js',
                cwd: './service/',
                watch: false,
                log_date_format: 'YYYY-MM-DD HH:mm Z'
            }
        ],
        deploy: {
            daily: {
                user: 'root',
                host: ['47.105.**.**'],
                ref: 'origin/node',
                repo: 'git@github.com:springHyc/bms-code-auto-generate.git',
                path: '/srv/hehe/bms-code-auto-generate3',
                'post-deploy': 'git pull && cd service && npm install && cd ../ && npm run deploy-node',
                env: {
                    NODE_ENV: 'daily'
                }
            }
        }
    };
    
    
    • package.json
    {
        "name": "bms-code-auto-generate",
        "version": "0.2.0-alpha0.1",
        "private": true,
        "scripts": {
            "dev": "node scripts/start.js",
            "build": "node scripts/build.js",
            "test": "node scripts/test.js",
            "deploy-node": "NODE_ENV=daily pm2 startOrRestart ecosystem.config.js",
            "deploy-end": "pm2 deploy ecosystem.config.js daily",
            "deploy-front": "npm run build && scp -r build root@47.105.**.**:/srv/hehe/bms-code-auto-generate3",
            "deploy": "npm run deploy-end && npm run deploy-front"
        },
    ...
    }
    
    • pm2 命令
    命令 含义
    pm2 stop id/name 暂停
    ps aux | grep node 查看node进程
    pm2 list 查看pm2启动列表
    pm2 start index2.js --watch 启动项目
    pm2 logs 查看日志
    pm2 restart app_name 杀死并重新启动进程。restart = stop+start
    pm2 reload app_name reload实现了0秒的停机时间重新加载.reload = 重新读取配置文件
    pm2 stop app_name
    pm2 delete app_name
    pm2 flush | pm2 flush <api> 清空 PM2 管理的当前应用程序日志
    pm2 monit 监控CPU/内存

    相关文章

      网友评论

          本文标题:pm2:从小白到写出一键部署前后端工程

          本文链接:https://www.haomeiwen.com/subject/lrmrultx.html