标题说的java全栈项目特指前端采用vue/react/angular等前端框架,后端采用java技术栈开发的项目。
一直以来我走的技术路线都是全栈路线,从2014-2015年左右特别火的MEAN(mongodb+expressjs+angularjs+nodejs)框架到现在的vue+java技术栈,包括服务器部署和运维都是自己在做。说到项目部署,之前用过很长一段时间简单但不粗暴的screen
命令,比如screen -L -S some_awesome_project_name
、screen -r pid
和screen -list
都是常用的几个,当然还有ctrl+a+d
,这个是退出项目的日志终端但是不杀掉该进程的命令,这套部署方案没什么不好,只是功能太少,只适合于demo项目或者测试环境,正式项目或者对项目质量要求比较高的场景下并不适合。然后用过一小段docker技术栈,docker从2013年发布起就非常火,周边生态也越来越壮大,基于容器的各种持续集成和持续交付的架构方案也出现很多,现在最火的要数kubernete了。但是缺点就是比较耗资源,一个镜像文件少则800M,多则几个g。当然如果项目预算比较充足,采用docker容器集群作为架构方案的话,也就不在乎资源问题了,如果是单机的话,还是有种杀鸡用牛刀的感觉。虽然docker和kubernete是时下最热门的技术,但是考虑自己公司的情况和项目的实际需求,我最终还是决定用pm2部署。
服务器初始化
写了一个脚本,分享出来。
#!/bin/bash
# install jdk
sudo apt-get update
sudo apt-get install -y openjdk-8-jdk
java -version
# install mvn
cd ~
wget https://mirrors.ocf.berkeley.edu/apache/maven/maven-3/3.5.4/binaries/apache-maven-3.5.4-bin.tar.gz
sudo tar -xvzf apache-maven-3.5.4-bin.tar.gz
sudo mv apache-maven-3.5.4 /opt
sudo ln -s /opt/apache-maven-3.5.4/bin/mvn /usr/bin/mvn
mvn -version
# install nodejs and pm2
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y build-essential
node -v
npm -v
sudo npm install -g pm2 --registry=https://registry.npm.taobao.org
pm2 l
# install git
sudo apt install -y git
ssh-keygen -t rsa -C $1
cat ~/.ssh/id_rsa.pub
使用方式是命令行执行:
./setup.sh "anythingcanputhere"
解释一下:
- 参数"anythingcanputhere"会替换脚本里的
$1
,用于生成ssh公私钥 - 第一部分是安装jdk,Oracle的jdk越来越不好安装了,以后用openjdk好了。
apt-get install
后面加上-y
可以一直执行到完,不会提示你确认yes or no而中断执行了 - 第二部分是安装maven,注意
sudo ln -s /opt/apache-maven-3.5.4/bin/mvn /usr/bin/mvn
这行命令是新建软连接,如果没有这步,后面执行pm2 deploy
命令的时候会提示找不到mvn
命令而退出 - 第三部分是安装nodejs和pm2
- 第四部分是安装git和生成ssh公私钥。服务器需要用
git
命令从代码仓库拉取代码。生成公私钥以后,需要把~/.ssh/id_rsa.pub
文件里的内容拷贝到你的代码仓库的设置 -> SSH公钥
里。如果你的代码仓库里没有这台服务器的ssh公钥,拉取代码就会失败
配置文件
执行pm2 deploy
部署命令时需要指定配置文件。分享一个例子:
const ENV = {
"env_dev": {
"PROFILE": "dev"
},
"env_prod": {
"PROFILE": "prod"
},
"env_test": {
"PROFILE": "test"
}
};
module.exports = {
apps: [
{
"name": "pm2-demo-project",
"script": "/usr/bin/java",
"args": [
"-Xms128m",
"-Xmx256m",
"-Djava.security.egd=file:/dev/./urandom",
"-jar",
"pm2-demo-project/target/pm2-demo-project-0.0.1-SNAPSHOT.jar"
],
"exec_interpreter": "",
"exec_mode": "fork",
...ENV
},
],
deploy: {
test: {
host: ['192.168.1.103'],
user: 'wubin',
ssh_options: "StrictHostKeyChecking=no",
ref: 'origin/test',
repo: "git@code.xxx.com:wubin/pm2-demo-project.git",
path: "/home/demo/deploy/demo/pm2-demo-project",
"post-deploy": "sh deploy.sh test",
}
}
};
解释一下:
-
apps
部分是配置启动某个应用的命令,包括可执行文件和参数,以及自定义的环境变量 -
deploy
部分是服务器的信息。如果到这里还需要执行一步命令:
ssh-copy-id -i ~/.ssh/id_rsa.pub wubin@192.168.1.103
即设置免密码登录。这样就不必每次部署都要输入服务器密码了,这不是必须的,只是为了更方便。post-deploy
是配置实际启动服务的命令
下面我们看看deploy.sh
里有什么:
#!/bin/bash
mvn clean install
pm2 reload ecosystem.config.js --env $1
解释一下:
-
$1
接受执行脚本时的第一个传参,--env
指定了当前的环境是配置文件里的env_dev
、env_prod
和env_test
的其中之一,注意传参的时候把前缀env_
去掉,相应的自定义环境变量就会生效 -
pm2 reload
表示重启配置文件里的apps
属性的服务。如果原来就没有,那就会启动。需要注意的是,如果之前没有采用pm2 deploy
的方式部署,而是手动在服务器执行pm2 start
命令并且项目代码的路径不是/home/demo/deploy/demo/pm2-demo-project
的话,必须先用pm2 delete
命令把已经存在的服务删掉,否则pm2 reload
重启的jar包还是之前路径下的jar包
部署
理解了上面的内容,部署就容易了:
- 第一步需要初始化部署路径下的目录结构,包括拉取代码,只需初始化一次:
pm2 deploy ecosystem.config.js test setup
- 第二步执行:
pm2 deploy ecosystem.config.js test update
输出示例:
➜ pm2-demo-project git:(test) pm2 deploy ecosystem.config.js test update
--> Deploying to test environment
--> on host 192.168.1.103
fatal: no upstream configured for branch 'test'
○ deploying origin/test
○ executing pre-deploy-local
○ hook pre-deploy
○ fast forward test
已经位于 'test'
您的分支与上游分支 'origin/test' 一致。
来自 code.xxx.com:wubin/pm2-demo-project
* branch test -> FETCH_HEAD
Already up-to-date.
○ executing post-deploy `sh deploy.sh test`
[INFO] Scanning for projects...
// 省略
.
.
.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] pm2-demo-project 0.0.1-SNAPSHOT .................... SUCCESS [ 0.422 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 20.120 s
[INFO] Finished at: 2020-05-21T13:43:09+08:00
[INFO] ------------------------------------------------------------------------
[PM2] Applying action reloadProcessId on app [pm2-demo-project](ids: 0)
[PM2] [pm2-demo-project](0) ✓
○ hook test
○ successfully deployed origin/test
--> Success
pm2是非常好用的部署工具,但有时也会遇到一些小坑。有任何疑问,欢迎一起探讨。
网友评论