背景基于Springboot应用以war包的形式运行在Tomcat容器中,当更新war包时会有一段时间服务返回404,这对于线上服务是不可接受的 。4层的负载均衡可以自动将80端口关闭的节点下线,但由于内网服务器位于堡垒机后方,根据公司规定不能自行配置SSH服务,所以无法执行远程脚本 。所以只能通过别的方式实现 。
实验素材
文章插图
- Nginx 作为web server和7层负载均衡
- tomcat * 2 作为应用后端
- gitlab-ce 代码版本控制
- jenkins 发布平台
实际操作创建springboot项目参考Springboot使用内置和独立tomcat以及其他思考 。
编写同一个接口的不同版本
// tag v1@RestControllerpublic class HelloController {@GetMApping("/hello")public String hello() {return "V1";}}
// tag v2@RestControllerpublic class HelloController {@GetMapping("/hello")public String hello() {return "V2";}}
打包mvn clean package -Dmaven.test.skip=true
创建两个tomcat容器Docker run -itd --name tomcat-active -v /tmp/tomcat/active:/usr/local/tomcat/webapps -p 32771:8080 tomcatdocker run -itd --name tomcat-standby -v /tmp/tomcat/standby:/usr/local/tomcat/webapps -p 32772:8080 tomcat
将war包拷贝到容器中可能是docker toolbox的问题,无法挂载目录,所以只好把war包手动拷贝进去 。docker cp ~/workspace/spring-demo/target/spring-demo-0.0.1-SNAPSHOT.war tomcat-active:/usr/local/tomcat/webapps/docker cp ~/workspace/spring-demo/target/spring-demo-0.0.1-SNAPSHOT.war tomcat-standby:/usr/local/tomcat/webapps/
访问两个容器中的服务稍等片刻两个容器中的服务会自动部署,就可以分别通过相应的端口访问了,简单压测一下QPS可以达到2000+且没有报错 。$ wrk -c 20 -d 10 -t 4 http://192.168.99.100:32771/spring-demo-0.0.1-SNAPSHOT/helloRunning 10s test @ http://192.168.99.100:32771/spring-demo-0.0.1-SNAPSHOT/hello4 threads and 20 connectionsThread StatsAvgStdevMax+/- StdevLatency10.20ms8.70ms 122.66ms81.20%Req/Sec554.18167.661.04k63.25%22088 requests in 10.02s, 2.43MB readRequests/sec:2203.76Transfer/sec:247.89KB$ wrk -c 20 -d 10 -t 4 http://192.168.99.100:32772/spring-demo-0.0.1-SNAPSHOT/helloRunning 10s test @ http://192.168.99.100:32772/spring-demo-0.0.1-SNAPSHOT/hello4 threads and 20 connectionsThread StatsAvgStdevMax+/- StdevLatency11.30ms14.24ms 186.52ms92.95%Req/Sec557.54207.911.24k67.17%22025 requests in 10.03s, 2.42MB readRequests/sec:2196.36Transfer/sec:247.05KB
配置Nginxupstream ha {server 192.168.99.100:32771;server 192.168.99.100:32772 backup;}server {listen80;server_name_;location / {proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;proxy_passhttp://ha/spring-demo-0.0.1-SNAPSHOT/;}}
注意:默认情况下只会转发GET/HEAD/PUT/DELETE/OPTIONS这种幂等的请求,而不会转发POST请求,如果需要对POST请求也做转发,就需要加上non_idempotent配置,整体配置如下upstream ha {server 192.168.99.100:32771;server 192.168.99.100:32772 backup;}server {listen80;server_name_;location / {proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header non_idempotent;proxy_passhttp://ha/spring-demo-0.0.1-SNAPSHOT/;}}
注意proxy_next_upstream http_502 http_504 http_404 error timeout invalid_header;这行,这里就是表示把访问当前的upstream返回了这些状态码的请求转发到upstream中的下一台机器,在我们现在的应用场景下,当war包发布时,正在更新war包的tomcat会返回404,也就是对应http_404,如果不配置这行,是不会做转发的 。但这样简单的配置还会有一个问题,那就是Nginx不会把出问题的后端从upstream中摘除,也就是说请求还会访问到这个正在更新中的realserver,只是Nginx会再把请求转发到下一台好的realserver上,这样会增加一些耗时 。目前有三种方式可以实现对Nginx负载均衡的后端节点服务器进行健康检查,具体参考Nginx负载均衡
通过Nginx压测基本测试
- 两个tomcat节点均正常的情况下压测
$ wrk -c 20 -d 10 -t 4 http://192.168.99.100:32778/helloRunning 10s test @ http://192.168.99.100:32778/hello4 threads and 20 connectionsThread StatsAvgStdevMax+/- StdevLatency57.36ms32.06ms 335.36ms71.29%Req/Sec89.2948.20390.0085.25%3577 requests in 10.05s, 562.30KB readRequests/sec:355.77Transfer/sec:55.93KB
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- ASCII 码不同的两种空格及潜在问题:32 和160
- 机器学习概念和经典算法,我用大白话给你讲清楚了!入门必看
- 赵云和张飞的关系好吗 赵云为什么不和刘备,关羽,张飞结拜呢?
- 不会这些东东,不敢说你会nginx?
- 努尔哈赤是李成梁义子吗 努尔哈赤和李成梁是什么关系
- 李莲英长相奇丑 李莲英和太后的关系
- 建盏挑选技巧,天目茶盏和建盏是个概念吗
- 耶律和萧氏 耶律休哥和萧太后的关系
- 和曹冲一样聪明的神童 少年天才曹原
- 喝龙井茶的好处和坏处,喝毛尖茶的坏处