首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >node服务及前端应用部署

node服务及前端应用部署

作者头像
一粒小麦
发布2019-08-09 15:39:34
2K0
发布2019-08-09 15:39:34
举报
文章被收录于专栏:一Li小麦一Li小麦
6-7月基本上在写node。现在终于开始部署了。

开发一个服务和全面部署还是有很大差距的。主要体现在三个方面。

  • 故障恢复:崩了怎么办?
  • 多核利用:node单进程如何使用?
  • 多进程如何共享端口?

本文案例取自在笔者腾讯云服务器上的实践。上线部署在大公司里其实是专人操作的,一个产品从构思到发布,许许多多的坑要踩。

对于前端(伪全栈)来说,想要流畅的上手部署。命令行知识还是基础。其次是及时收藏不会的知识点。第三是多在服务器上玩玩,只要胆大心细,玩不坏的。

上传文件到服务器

本地的话可以用cp(copy)命令。但是上传怎么办?

scp(最原始)
# 上传文件
scp docker-compose.yml 用户名@ip地址:/root/sourse/
# 上传文件夹
scp -r 文件 root@ip地址:文件夹目录
从git拉取

实际工作中,我有可能从git上拉取代码。那就给服务器装一个git吧。

腾讯云centos 7安装git:https://cloud.tencent.com/developer/article/1404128

推荐从git拉取。

服务器安装mongodb

下载

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.4.9.tgz

解压

tar -xvzf mongodb-linux-x86_64-3.4.9.tgz

重命名

mv mongodb-linux-x86_64-3.4.9 mongodb

配置命令到全局

vi /etc/profile
# 增加 注意,这里的路径是你安装的路径
export PATH=$PATH:/mongodb/bin
# 重载
source /etc/profile

在mongodb下创建文件夹:

mkdir /data/db
mkdir log

启动mongod

mongod --dbpath=/mongodb/data/db --fork --logpath=/mongodb/data/logs

启动成功。

远程连接到服务器

腾讯云

在robot3T中

进程守护

线程和进程的关系:

https://www.liaoxuefeng.com/wiki/1016959663602400/1017627212385376

cluster

众所周知,一个蹩脚后端写的程序,bug贼多。时不时奔溃是常见的事情。

先写一个会报错的程序,它有十分之一的几率执行一个不存在的方法 aaa,也就是有10%的几率报错:

// app.js
const Koa=require('Koa')
const app =new Koa();

app.use(async (ctx,next)=>{
    Math.random()>0.9?aaa():2
    await next();
    ctx.response.type='text/html';
    ctx.response.body='<h1>hello</h1>';
})

if(!module.parent){
    app.listen(3000,()=>{
        console.log('服务已启动');
    })
}else{
    module.exports=app;
}

很简单是不。因为这不是主要的。

在根目录下新建一个 cluster.js

const cluster=require('cluster');
const os=require('os');
const process=require('process');

const numCpus=os.cpus().length;
console.log(`服务器cpu核心数`,numCpus)

let workers={}
if(cluster.isMaster){
    // 主进程分支
    // 当被进程杀死时,自动重启该核心进程
    cluster.on('death',function(worker){
        worker=cluster.fork();
        workers[worker.pid]=worker;
    })
    // 复制多个进程
    for(let i=0;i<numCpus;i++){
        let worker=cluster.fork();
        workers[worker.pid]=worker;
    }
}else{
    // 工作进程
    const app =require('./app');
    // 注册一个测试中间件
    app.use(async (ctx,next)=>{
        console.log('worker'+cluster.worker.id)+',PID:'+process.pid;
        next();
    });
    app.listen(3000);
}

// 杀死进程时(ctrl+c)
process.on('SIGTERM',function(){
    for(let pid in workers){
        process.kill(pid)
    }
    process.exit(0);
})

require('./test')

然后再写一个定时器,定时发http请求

// 根目录下test.js
const http=require('http');
setInterval(async ()=>{
    await http.get('http://localhost:3000');
},500);

运行 node cluster.js就可以看到先是主进程。然后生成了多个4个进程(4核心)。

cluster是一个node原生模块,它允许多个进程共享一个3000端口而不冲突。当一个故障发生时,其它进程也会把这个死掉的进程重启。因此看上去是个"永不崩溃"的守护服务。

fork模式

fork模式是通过子进程来守护的。

// fork.js
const child_process=require('child_process');
require('./test.js');
const fork=[];

// 开启2个子进程
for(let i=0;i<2;i++){
    let worker_process=child_process.fork('app.js',[3000+i]);
    worker_process.on('close',function(code){
        console.log('子进程已退出,退出码'+code);
    });
    fork.push(worker_process);
}

process.on('SIGTERM',function(){
    fork.forEach(()=>{
        worker_process.kill();
    });
    process.exit(0)
});

显然缺点是需要启动多个端口。无法共享。

PM2

pm2在这里不是什么环境指标。而是一个软件。

  • 内建负载均衡(使用node cluster集群模块/子进程)
  • 线程守护。keep-alive
  • 0秒停机重载,维护时不需要停机
  • 跨平台支持(Linux,Windows,macOS)
  • 控制台检测 https://id.keymetrics.io/api/oauth/login#/register
  • 提供http的api

pm2常用命令:

# 安装
sudo npm i pm2 -g

# --watch:坚挺文件变化
# 2表示启动多少实例
pm2 start app.js --watch i 2
# 根据机器cpu核心数最大限度利用资源
pm2 start app.js -i max

# 查看运行的进程
pm2 list

# 关闭
pm2 stop xxx
pm2 stop all

完全可以在项目中建一个process.yml配置文件。

apps:
  - script : app.js
    intance : 2
    watch : true
    env : 
      NODE_ENV : production

然后 pm2 start process.yml

### Nginx配置

我有一个前端文件,想要分离部署。怎么办?

前端项目配置

nginx的主配置文件在 /etc/nginx/nginx.conf。其中有这么两行可以配置一下:

# Virtual Host Configs
include /etc/nginx/conf.d/*.config;
include /etc/nginx/sites-enabled/*;

实际上我们不会去动主配置文件。不妨在 /etc/nginx/sites-enabled新建一个test.conf

server {
    listen 80;
    server_name test.djtao.com;
    location / {
        root /root/applications/test;
        index index.html index.htm;
    }
}
端口被占用解决

配置完成后,就可以重启和重载nginx了。

# 验证 Nginx 配置 
nginx -t
# 重新启动 Nginx 
service nginx restart
nginx -s reload

正常情况应该是这样:

如果出现如下报错:

Job for nginx.service failed because the control process exited with error code. See “systemctl status nginx.service” and “journalctl -xe” for details

尝试:

1.systemctl status nginx

2.netstat -tnlp

3.ps -ef | grep nginx

4.pkill -9 被占用的端口号(如23890)
反向代理

所谓反向代理,是跨域问题的究极解决方案。

前端需要调用后端接口。假设这个是跨域的(不同端口,不同二级域名,比如说3000)

server {
        listen 80;
        server_name test.djtao.net;
        location / {
            root /applications/test;
            index index.html index.htm;
        }
        location /api {
            proxy_pass  http://127.0.0.1:3000;
            proxy_redirect     off;
            proxy_set_header   Host
            proxy_set_header   X-Real-IP
            proxy_set_header   X-Forwarded-For
            $host;
            $remote_addr;
            $proxy_add_x_forwarded_for;
        }
    }

这样我们在3000端口的后端就代理到test.djtao.net下了。

History模式下的nginx配置

众所周知,nginx不配置。history路由刷新后会报404。加上这么一句:

location / {
            root /applications/TaoDoc/fe/dist;
            index index.html index.htm;
            try_files $uri $uri/ /index.html;
        }
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 一Li小麦 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 上传文件到服务器
    • scp(最原始)
      • 从git拉取
      • 服务器安装mongodb
        • 远程连接到服务器
        • 进程守护
          • cluster
            • fork模式
              • PM2
                • 前端项目配置
                  • 端口被占用解决
                    • 反向代理
                      • History模式下的nginx配置
                      相关产品与服务
                      数据库
                      云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档