部署

    • server
    • db
    • slb
    • 监控

    推荐ubuntu 14.10 LTS

    登录远端服务器

    ssh root

    创建用户

    • useradd创建登录用户
    • passwd设置用户登录密码

    赋予sudo权限

    如果有必要使用sudu权限,请修改

    复制root行改为sang即可

    1. # User privilege specification
    2. root ALL=(ALL:ALL) ALL
    3. sang ALL=(ALL:ALL) ALL
    1. # su - sang
    2. $ ls
    3. $
    4. $ pwd
    5. /home/sang
    6. $

    安装必备软件

    如果上面没有复制给sang账户sudo权限,请切换到root账户操作

    1. sudo apt-get update
    2. sudo apt-get install git

    安装nginx

    1. sudo apt-get install nginx

    开机启动(http://www.jianshu.com/p/2e03255cfabb)

    1. sudo apt-get install sysv-rc-conf
    2. sudo sysv-rc-conf nginx on

    准备工作目录

    1. mkdir -p workspace/github
    2. cd workspace/github

    安装nodejs

    安装nvm

    1. $ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.0/install.sh | bash
    2. % Total % Received % Xferd Average Speed Time Time Time Current
    3. Dload Upload Total Spent Left Speed
    4. 100 7766 100 7766 0 0 28614 0 --:--:-- --:--:-- --:--:-- 28656
    5. => Downloading nvm as script to '/home/sang/.nvm'
    6. => Appending source string to /home/sang/.bashrc
    7. => Close and reopen your terminal to start using nvm
    8. $ source ~/.bashrc
    9. $ nvm
    10. Node Version Manager

    安装nodejs lts版本

    1. $ nvm install 4
    2. Downloading https://nodejs.org/dist/v4.3.2/node-v4.3.2-linux-x64.tar.xz...
    3. ######################################################################## 100.0%
    4. Now using node v4.3.2 (npm v2.14.12)
    5. Creating default alias: default -> 4 (-> v4.3.2)
    6. $ node -v
    7. v4.3.2

    使之成为默认

    1. $ nvm alias default 4.3
    2. default -> 4.3 (-> v4.3.2)
    1. $ npm -v
    2. 2.14.12

    只要大于2.9.1即可,如不是,请npm i -g npm@2.9.1

    安装nrm

    测速

    1. $ nrm test
    2. * npm ---- 274ms
    3. cnpm --- 6868ms
    4. taobao - 716ms
    5. edunpm - 5598ms
    6. eu ----- Fetch Error
    7. au ----- Fetch Error
    8. sl ----- 1234ms
    9. nj ----- 2228ms
    10. pt ----- Fetch Error

    切换源

    1. $ nrm use npm
    2. Registry has been set to: https://registry.npmjs.org/

    部署nodejs应用

    基础

    • git clone
    • npm i
    • pm2 start

    修改nginx

    1. cat /etc/nginx/sites-enabled/default
    2. upstream backend_nodejs {
    3. server 127.0.0.1:3019 max_fails=0 fail_timeout=10s;
    4. #server 127.0.0.1:3001;
    5. keepalive 512;
    6. }
    7. listen 80 default_server;
    8. listen [::]:80 default_server ipv6only=on;
    9. #root /usr/share/nginx/html;
    10. root /home/sang/workspace/oschina/base2-wechat-jssdk/public;
    11. index index.html index.htm;
    12. # Make site accessible from http://localhost/
    13. server_name nodeonly.mengxiaoban.cn at35.com;
    14. client_max_body_size 16M;
    15. keepalive_timeout 10;
    16. # First attempt to serve request as file, then
    17. # as directory, then fall back to displaying a 404.
    18. #try_files $uri $uri/ =404;
    19. # Uncomment to enable naxsi on this location
    20. # include /etc/nginx/naxsi.rules
    21. proxy_set_header X-Real-IP $remote_addr;
    22. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    23. proxy_set_header Host $http_host;
    24. proxy_set_header X-NginX-Proxy true;
    25. proxy_redirect off;
    26. proxy_next_upstream error timeout http_500 http_502 http_503 http_504;
    27. proxy_set_header Connection "";
    28. proxy_http_version 1.1;
    29. proxy_pass http://backend_nodejs;
    30. }
    31. }

    注意

    • upstream backend_nodejs定义的代理转发的api地址
    • location /下面的proxy_pass,从upstream里取
    • root下面放的是静态资源,比如express下的public目录
    1. sudo nginx -s reload

    购买普通阿里云服务器的时候,本机默认自带的系统盘大小为20G,但是这样的大小是不满足部署产品服务器的需求,
    所以可以购买阿里云数据盘,一半大小为200G

    • 首先使用root用户查看系统版本,本文是在centos中部署使用

      在终端中使用下面命令查看系统版本

    1. $ lsb_release -a
    2. LSB Version: :core-4.1-amd64:core-4.1-noarch
    3. Distributor ID: CentOS
    4. Description: CentOS Linux release 7.2.1511 (Core)
    5. Release: 7.2.1511
    6. Codename: Core

    确定系统版本之后在终端中确认系统盘情况(注:使用root用户):

    1. $ fdisk -l
    2. Disk /dev/xvda: 21.5 GB, 21474836480 bytes, 41943040 sectors
    3. Units = sectors of 1 * 512 = 512 bytes
    4. Sector size (logical/physical): 512 bytes / 512 bytes
    5. I/O size (minimum/optimal): 512 bytes / 512 bytes
    6. Disk label type: dos
    7. Disk identifier: 0x0009e68a
    8. Device Boot Start End Blocks Id System
    9. /dev/xvda1 * 2048 41943039 20970496 83 Linux
    10. Disk /dev/xvdb: 214.7 GB, 214748364800 bytes, 419430400 sectors
    11. Units = sectors of 1 * 512 = 512 bytes
    12. Sector size (logical/physical): 512 bytes / 512 bytes
    13. I/O size (minimum/optimal): 512 bytes / 512 bytes
    14. Disk label type: dos
    15. Disk identifier: 0xd0c73cf7
    16. Device Boot Start End Blocks Id System
    17. /dev/xvdb1 2048 419430399 209714176 83 Linux

    首先确认在阿里云中购买了数据盘,上面的Disk /dev/xvda是自带的系统盘,/dev/xvda1表示已经挂载并且在使用中,Disk /dev/xvdb是数据盘,
    上面的情况是已经挂载好的,如果没有挂载情况,只显示Disk /dev/xvdb: 214.7 GB, 214748364800 bytes, 419430400 sectors,表示未被
    使用

    • 将未被分区挂载的数据盘进行分区挂载
    1. $ fdisk /dev/xvdb

    根据提示,输入”n”,”p”,”1”,两次回车,”wq”,分区开始,很快就会结束

    • 查看新的分区:
    1. $ fdisk -l

    此时应该显示/dev/xvdb已被分区, like this:

    1. Device Boot Start End Blocks Id System
    2. /dev/xvdb1 2048 419430399 209714176 83 Linux
    • 格式化新的分区

    以ext3为例:使用“mkfs.ext3 /dev/xvdb1”命令对新分区进行格式化,格式化的时间根据硬盘大小有所不同。
    (也可自主决定选用其它文件格式,如ext4等)

    1. $ mkfs.ext3 /dev/xvdb1

    需要等一段时间等待格式化完毕

    • 添加新的分区信息
    1. $ echo '/dev/xvdb1 /mnt ext3 defaults 0 0' >> /etc/fstab
    • 查看分区

    出现/dev/xvdb1 /mnt ext3 defaults 0 0 说明成功

    • 挂载新的分区
    1. $ mount -a
    • 查看分区的情况
    1. $ df -h
    2. Filesystem 1K-blocks Used Available Use% Mounted on
    3. /dev/xvda1 20510332 2031552 17413872 11% /
    4. devtmpfs 934320 0 934320 0% /dev
    5. tmpfs 942004 0 942004 0% /dev/shm
    6. tmpfs 942004 98724 843280 11% /run
    7. tmpfs 942004 0 942004 0% /sys/fs/cgroup
    8. /dev/xvdb1 206292664 1065720 194724852 1% /mnt

    /dev/xvdb1已经成功启用,挂载成功

    pm2

    https://github.com/Unitech/pm2

    1. $ npm install pm2 -g # Install PM2
    2. $ pm2 start app.js # Start, Daemonize and auto restart application
    3. $ pm2 start app.js -i 4 # Start 4 instances of application in cluster mode
    4. # it will load balance network queries to each app
    5. $ pm2 start app.js --name="api" # Start application and name it "api"
    6. $ pm2 start app.js --watch # Restart application on file change
    7. $ pm2 start script.sh # Start bash script
    8. $ pm2 list # List all processes started with PM2
    9. $ pm2 monit # Display memory and cpu usage of each app
    10. $ pm2 show [app-name] # Show all informations about application
    11. $ pm2 logs # Display logs of all apps
    12. $ pm2 logs [app-name] # Display logs for a specific app
    13. $ pm2 stop all # Stop all apps
    14. $ pm2 stop 0 # Stop process with id 0
    15. $ pm2 restart all # Restart all apps
    16. $ pm2 reload all # Reload all apps in cluster mode
    17. $ pm2 gracefulReload all # Graceful reload all apps in cluster mode
    18. $ pm2 delete all # Kill and delete all apps
    19. $ pm2 delete 0 # Delete app with id 0
    20. $ pm2 scale api 10 # Scale app with name api to 10 instances
    21. $ pm2 reset [app-name] # Reset number of restart for [app-name]
    22. $ pm2 startup # Generate a startup script to respawn PM2 on boot
    23. $ pm2 save # Save current process list
    24. $ pm2 resurrect # Restore previously save processes
    25. $ pm2 update # Save processes, kill PM2 and restore processes
    26. $ pm2 generate # Generate a sample json configuration file
    27. $ pm2 deploy app.json prod setup # Setup "prod" remote server
    28. $ pm2 deploy app.json prod # Update "prod" remote server
    29. $ pm2 deploy app.json prod revert 2 # Revert "prod" remove server by 2
    30. $ pm2 module:generate [name] # Generate sample module with name [name]
    31. $ pm2 install pm2-logrotate # Install module (here a log rotation system)
    32. $ pm2 uninstall pm2-logrotate # Uninstall module
    33. $ pm2 publish # Increment version, git push and npm publish

    主要的特点:

    • 内建负载均衡(使用Node cluster 集群模块)
    • 后台运行
    • 0秒停机重载,我理解大概意思是维护升级的时候不需要停机.
    • 具有Ubuntu和CentOS 的启动脚本
    • 停止不稳定的进程(避免无限循环)
    • 控制台检测
    • 提供 HTTP API
    • 远程控制和实时的接口API ( Nodejs 模块,允许和PM2进程管理器交互 )

    pm2部署简单应用

    1. npm install -g pm2

    使用pm2部署简单的项目

    1. $ pm2 start app.js --name "heheda" -i 0 --watch
    • pm2 start app.js : 使用pm2启动app.js

    • -i 0 : 使用最大进程数启动

    • —name : 指定一个你喜欢的名字

    • —watch : 开启监视模式,如果代码有变动pm2自动重启

    查看pm2部署

    1. pm2 ls

    pm2自动部署远程服务器

    目前我们部署服务器的方式是使用oschina托管项目,然后在服务器中安装git将项目克隆到服务器中,然后
    使用pm2部署项目,如果项目有任何的修改,就会需要跑到几个服务器中pull代码,然后pm2 reload项目,
    蛋疼的要死。
    现在就使用pm2的远程部署方式,解决这个蛋疼的问题!

    准备工作

    将本地机器和线上服务器建立ssh信任,免密码登陆

    • 生成git ssh公钥(本地机器和服务器操作一样)
    1. $ git config --global user.name "heheda"
    2. $ git config --global user.email "heheda@mail.com"
    3. $ ssh-keygen -t rsa -C "heheda@mail.com"

    连续三次回车,这样生成的ssh公钥添加到github

    • 查看生成的ssh公钥
    1. $ ls ~/.ssh/
    2. authorized_keys id_rsa id_rsa.pub known_hosts

    理论上已经生成ssh公钥,在用户主目录下的.ssh中生成的id_rsa.pub就是生成的公钥
    authorized_keys文件是通过授权的ssh公钥,在使用ssh协议进行远程访问的时候,如果该机器的ssh公钥在
    这个文件中,那么能直接进行访问

    • 将ssh公钥拷贝到服务器
    1. $ scp ~/.ssh/id_rsa.pub username@ip:用户主目录/.ssh/authorized_keys

    执行这个命令是将本地的id_rsa.pub拷贝到服务器的.ssh/目录下并命名为authorized_keys
    这样就能不需要密码访问远程服务器了
    上一步已经将服务器的ssh公钥添加到 github 中了,这样服务器中clone项目也不需要密码

    1. {
    2. /**
    3. * Deployment section
    4. * http://pm2.keymetrics.io/docs/usage/deployment/
    5. */
    6. "deploy" : {
    7. "yourprojectname" : {
    8. "user" : "node",
    9. "host" : ["ip"],
    10. "ref" : "origin/master",
    11. "repo" : "git.oschina.net",
    12. "path" : "/your/deploy/folder/",
    13. "post-deploy" : "npm install ; pm2 start bin/www --name 'hz-frontend' --watch",
    14. "env" : {
    15. "NODE_ENV": "dev"
    16. }
    17. }
    18. }
    19. }
    • user : 你登陆到远程主机的用户名
    • host : 服务器的ip地址
    • ref : 部署的分支
    • repo : github或oschina中托管的地址
    • path : 部署到服务器的目录
    • post-deploy : 部署时的命令

    执行部署

    • 首次在服务器中部署(服务器中没有需要部署的项目,需要将代码克隆到服务器)
    1. pm2 deploy ecosystem.json yourprojectname setup

    上面命令是将项目从github或oschina中克隆到指定path中,需要注意一下的是,pm2 将目录结构分为 :

    |current | shared |source |

    • 克隆好之后执行安装和启动

    官方推荐在部署的项目中也使用ecosystem.json进行启动项目 :

    1. {
    2. "apps" : [{
    3. // Application #1
    4. "name" : "hz-mq",
    5. "script" : "index.js",
    6. "args" : "--toto=heya coco -d 1",
    7. "watch" : true,
    8. "node_args" : "--harmony",
    9. "merge_logs" : true,
    10. "cwd" : "/Users/zxy/work/hz-mq",
    11. "env": {
    12. "NODE_ENV": "development",
    13. "AWESOME_SERVICE_API_TOKEN": "xxx"
    14. },
    15. "env_production" : {
    16. "NODE_ENV": "production"
    17. },
    18. "env_staging" : {
    19. "NODE_ENV" : "staging",
    20. "TEST" : true
    21. },
    22. "exec_mode" : "cluster_mode"
    23. }