开发中,由于XXOO原因,测试和生产环境是同一个,而且决策者不推荐使用CI(Jenkins),在开发中,需要较为频繁发布新版本,测试人员提出服务不能间断,此处不谈测试/生产为同一个环境或者需求是多么不合理,针对此需求,总结一个笨方法:
Env:2台host,A部署Nginx + APP,B部署APP
在A的nginx配置目录放三个配置文件:nginx.conf.a,nginx.conf.b,nginx.conf.ab,分别将请求分发到对应的服务提供者a/b/ab。
初始状态:nginx.conf.ab
0. 更新a服务
|- 用nginx.conf.b替换nginx.conf
|- 重新加载nginx配置
|- 更新a
|- 验证a
1. 更新b服务
|- 用nginx.conf.a替换nginx.conf
|- 重新加载nginx配置
|- 更新b
|- 验证b
2. ab负载均衡
|- 用nginx.conf.ab替换nginx.conf
|- 重新加载nginx配置
脚本如下,部分环境可能有区别,自行适配,如:本文登陆远程host方式为将本机的key放到目标host,如果是user/pass,可以使用sshpass组件来实现 。。。
deploy.sh
#!/bin/bash
server_a="a_ip"
server_b="b_ip"
delay=45
echo "Deploy begin ..."
echo "Redeploy a begin ..."
ssh root@$server_a 'bash -s'< deploy-reloadNginx.sh b
scp -r CoachService root@$server_a:~/projects/
ssh root@$server_a 'bash -s'< deploy-build.sh
echo "Sleep ${delay}s ..."
sleep ${delay}s
a_status=`curl -s -o /dev/null -w "%{http_code}" "http://$server_a:8080/heartbeat"`
if [ $a_status -eq 200 ]
then
echo "Deploy a success ..."
echo "Redeploy b begin ..."
ssh root@$server_a 'bash -s'< deploy-reloadNginx.sh a
scp -r CoachService root@$server_b:~/projects/
ssh root@$server_b 'bash -s'< deploy-build.sh
echo "Sleep ${delay}s ..."
sleep ${delay}s
b_status=`curl -s -o /dev/null -w "%{http_code}" "http://$server_b:8080/heartbeat"`
if [ $b_status -eq 200 ]
then
echo "Deploy b success ..."
ssh root@$server_a 'bash -s'< deploy-reloadNginx.sh ab
echo "Deploy complete ..."
else
echo "Deploy b failed ..."
fi
else
echo "Deploy a failed ..."
fi
deploy-reloadNginx.sh
#!/bin/bash
echo "Overwrite nginx.conf with nginx.conf.$1 ..."
\cp "/etc/nginx/nginx.conf.$1" /etc/nginx/nginx.conf
echo "Reload nginx ..."
nginx -s reload
deploy-build.sh
#!/bin/bash
echo "Package service ..."
export M2_HOME=/maven/home
export PATH=$M2_HOME/bin:$PATH
cd /project/path
mvn clean package -Dmaven.test.skip=true
echo "Replace the old package ..."
cp target/app-0.0.1-SNAPSHOT.jar /var/coach/app.jar
echo "Restart service ..."
service app-service restart --spring.profiles.active=production