vlambda博客
学习文章列表

使用nginx的负载均衡机制实现用户无感更新服务

点击上方 码农沉思录 ,选择“设为星标”
优质文章,及时送达
用户请求的转发是接口服务在部署时必须要做的一步。
请求转发的步骤大约分为如下几步:
  1. 域名解析到转发服务器

  2. 转发服务器会根据权重(weight)、备用(backup)配置转发到统一网关

  3. 如果统一网关存在灰度的配置,需要根据身份或者头信息过滤请求

  4. 转发到具体的业务服务

目前市面上优秀的 请求转发有很多种,比如: NginxF5KongTengine等,其中 Tengine是阿里巴巴基于 Nginx进行封装,我们本章的内容基于 Nginx进行讲解,我们先来准备下 nginx的测试环境。
准备环境
如果你的测试环境没有安装 Nginx,下面我通过两种方式来说下具体的安装过程。
way安装环境
如果你是 OSX系统,可以直接使用 brew管理工具进行安装,这种方式比较简单,自动从远程服务器下载最新稳定的版本进行解压、配置环境等。
 
   
   
 
  1. # 安装nginx

  2. ~ brew install nginx

静静等待~
安装完成后,我们先来修改下端口号(brew安装包把默认的监听端口号改为了 8080,一般在使用解压的方式安装时监听端口都是 80)。
我们需要先找到 nginx.conf这个文件的位置:
 
   
   
 
  1. ~ sudo find / -name nginx.conf

  2. /usr/local/etc/nginx/nginx.conf

找到文件后,我们通过 sudo vi/usr/local/etc/nginx/nginx.conf命令来修改默认的端口号,位置如下:
 
   
   
 
  1. server {

  2. listen 80;

  3. server_name localhost;

  4. #...

  5. }

修改后保存退出。
最后不要忘记重启 Nginx服务。
 
   
   
 
  1. ~ brew services restart nginx

解压包方式

首先去 nginx 官方提供 http://nginx.org/download 的下载地址去挑选自己中意的版本,下面以 1.17.7 版本示例:
  • http://nginx.org/download/nginx-1.17.7.tar.gz

点击下载完成后解压安装即可(注意编译环境,可能会缺少一些依赖库,本机安装对应的依赖就可以了)
 
   
   
 
  1. # 解压nginx

  2. tar -xvf nginx-1.17.7.tar.gz

  3. # 进入目录

  4. cd nginx-1.17.7

  5. # 配置

  6. ./configure --prefix=/usr/local/nginx

  7. # 编译

  8. sudo make

  9. # 安装

  10. sudo make install

  11. # 进入nginx执行目录

  12. cd /usr/local/nginx/sbin

  13. # 启动nginx

  14. ./nginx

安装完成如果访问 http://127.0.0.1 可以看到 Welcometo nginx!字样,说明我们已经安装成功了。
实例项目
为了演示更新服务用户无痛感知,我们先来创建一个简单的 SpringBoot示例项目,在项目内添加一个测试接口,项目 pom.xml依赖如下所示:
 
   
   
 
  1. <dependencies>

  2. <dependency>

  3. <groupId>org.springframework.boot</groupId>

  4. <artifactId>spring-boot-starter-web</artifactId>

  5. </dependency>

  6. </dependencies>

示例接口
创建一个名为 TestController的测试控制器,如下所示:
 
   
   
 
  1. /**

  2. * 测试控制器

  3. *

  4. * @author 恒宇少年

  5. */

  6. @RestController

  7. @RequestMapping(value = "/test")

  8. public class TestController {

  9. @Autowired

  10. private ServerProperties serverProperties;


  11. @GetMapping

  12. public String hello() {

  13. return "请求分发到了,端口号:" + serverProperties.getPort() + "的服务,接口访问成功.";

  14. }

  15. }

配置转发
我们测试所需要的请求接口已经准备好了,接下来需要在访问 nginx时将请求转发到我们测试的接口,配置转发时需要用到 nginx的两个关键字,分别是 upstreamlocation
  • upstream:服务器组,配置请求分发到组内多台服务器。

  • location:转发的路径前缀,如:"/user/",当我们访问 http://127.0.0.1/user/1时,就会执行该 location的转发业务。

upstream转发流程如下图所示:
配置upstream
nginx.conf文件 http内添加转发的 服务器组(upstream),如下所示:
 
   
   
 
  1. # 负载配置

  2. upstream test {

  3. server 127.0.0.1:8080 weight=1;

  4. server 127.0.0.1:9090 weight=2;

  5. server 127.0.0.1:9000 backup;

  6. }

配置location
在上面已经配置好了服务器组,我们需要把名为 test的服务器组作为代理的方式配置在 location,在 locationserver下新增一个 location,如下所示:
 
   
   
 
  1. # 配置"/lb/"路径的请求全部转发到本地8080端口

  2. location /lb/ {

  3. proxy_pass http://test/;

  4. proxy_set_header Host $host;

  5. proxy_set_header X-Real-IP $remote_addr;

  6. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  7. proxy_connect_timeout 50;

  8. proxy_read_timeout 50;

  9. proxy_send_timeout 50;

  10. }

重启nginx
我这里是使用 brew的方式安装的 nginx,所以重启的命令如下所示:
 
   
   
 
  1. brew services restart nginx

如果你是 安装包的方式安装:
 
   
   
 
  1. # 进入安装包目录

  2. cd /usr/local/nginx/sbin

  3. # 重载

  4. ./nginx -s reload

权重配置
nginx中有一个权重的概念,根据权重值的大小来控制请求流量,当权重的配值越大时,流量分发就会越多,我们在 test服务器组内配置权重解释:
  • server127.0.0.1:8080weight1; 权重占比为 1/3,每3次请求会转发1次到这台服务器上。

  • server127.0.0.1:9090weight2; 权重占比为 2/3,每3次请求会转发2次到这台服务器上。

备用配置
当我们在 upstream内的 server尾部添加 backup时,表示这台服务器是备用服务器,只有其他服务器都停机时才会启用,我们更新时其实就利用的这一点。
运行测试
为了演示方便我们直接将本章测试项目 package打包后,通过 --server.port来指定运行的端口号来模拟多台服务器的场景。
 
   
   
 
  1. # 启动127.0.0.1:8080服务器

  2. java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=8080

  3. # 启动127.0.0.1:9090服务器

  4. java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=9090

  5. # 启动127.0.0.1:9000备用服务器

  6. java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=9000

注意:使用多个终端窗口运行服务。
nginx.conf> server中配置 location的转发条件为 /lb/路径前缀,所以我们访问 http://127.0.0.1/lb/test (由于 nginx监听的端口号是 80,所以通过 nginx访问转发时不需要携带端口号)就会被转发到 test服务器组内的服务器上。

测试点:权重转发

 
   
   
 
  1. curl http://localhost/lb/test

  2. 端口号:8080,接口访问成功.


  3. curl http://localhost/lb/test

  4. 端口号:9090,接口访问成功.


  5. curl http://localhost/lb/test

  6. 端口号:9090,接口访问成功.


  7. curl http://localhost/lb/test

  8. 端口号:8080,接口访问成功.

根据访问的结果来看, 8080端口号的服务是每3次中请求了 1,而 9090则是每3次中请求了 2,这一点正是符合我们配置的权重( weight),测试通过。

测试点:备用生效

我们把 80809090这两个服务都停掉,再次访问 http://127.0.0.1/lb/test 。
 
   
   
 
  1. curl http://localhost/lb/test

  2. 端口号:9000,接口访问成功.


  3. curl http://localhost/lb/test

  4. 端口号:9000,接口访问成功.


  5. curl http://localhost/lb/test

  6. 端口号:9000,接口访问成功.

可以看到我们的备用服务器启用了,已经把全部的请求流量转发到 9000这台服务上,测试通过。
总结
当我们把 80809090都停掉时,备用服务器会启用,这时我们就可以来更新 80809090这两个服务的运行代码,更新完成后重启,只要 80809090这两台服务器有一台处于运行状态, nginx就不会把流量分发到备用的 9000,以此类推把全部的服务都更新完成。

使用nginx的负载均衡机制实现用户无感更新服务 使用nginx的负载均衡机制实现用户无感更新服务 使用nginx的负载均衡机制实现用户无感更新服务
点个在看吧,证明你还爱我