美文网首页DevOpsSpring Boot 核心技术框架建设收集
使用nginx的负载均衡机制实现用户无感更新服务

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

作者: 恒宇少年 | 来源:发表于2020-01-09 08:59 被阅读0次

    知识改变命运,撸码使我快乐,2020继续游走在开源界

    点赞再看,养成习惯

    给我来个Star吧,点击了解基于新一代接口服务框架 “ApiBoot” 的前后分离( “Vue + ElementUI” )管理平台基础解决方案脚手架示例。

    前言

    用户请求的转发是接口服务在部署时必须要做的一步。

    请求转发的步骤大约分为如下几步:

    1. 域名解析到转发服务器
    2. 转发服务器会根据权重(weight)、备用(backup)配置转发到统一网关
    3. 如果统一网关存在灰度的配置,需要根据身份或者头信息过滤请求
    4. 转发到具体的业务服务

    目前市面上优秀的请求转发有很多种,比如:NginxF5KongTengine等,其中Tengine是阿里巴巴基于Nginx进行封装,我们本章的内容基于Nginx进行讲解,我们先来准备下nginx的测试环境。

    准备环境

    如果你的测试环境没有安装Nginx,下面我通过两种方式来说下具体的安装过程。

    使用Brew安装Nginx

    如果你是OSX系统,可以直接使用brew管理工具进行安装,这种方式比较简单,自动从远程服务器下载最新稳定的版本进行解压、配置环境等。

    # 安装nginx
    ➜  ~ brew install nginx
    

    静静等待~

    安装完成后,我们先来修改下端口号(brew安装包把默认的监听端口号改为了8080,一般在使用解压的方式安装时监听端口都是80)。

    我们需要先找到nginx.conf这个文件的位置:

    ➜  ~ sudo find / -name nginx.conf           
    /usr/local/etc/nginx/nginx.conf
    

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

    server {
            listen       80;
            server_name  localhost;
            #...
    }        
    

    修改后保存退出。

    最后不要忘记重启Nginx服务。

    ➜  ~ brew services restart nginx
    

    解压包方式

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

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

    # 解压nginx
    tar -xvf nginx-1.17.7.tar.gz
    # 进入目录
    cd nginx-1.17.7
    # 配置
    ./configure --prefix=/usr/local/nginx
    # 编译
    sudo make
    # 安装
    sudo make install
    # 进入nginx执行目录
    cd /usr/local/nginx/sbin
    # 启动nginx
    ./nginx
    

    安装完成如果访问 http://127.0.0.1 可以看到Welcome to nginx!字样,说明我们已经安装成功了。

    示例项目

    为了演示更新服务用户无痛感知,我们先来创建一个简单的SpringBoot示例项目,在项目内添加一个测试接口,项目pom.xml依赖如下所示:

    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
    </dependencies>
    

    示例接口

    创建一个名为TestController的测试控制器,如下所示:

    /**
     * 测试控制器
     *
     * @author 恒宇少年
     */
    @RestController
    @RequestMapping(value = "/test")
    public class TestController {
        @Autowired
        private ServerProperties serverProperties;
    
        @GetMapping
        public String hello() {
            return "请求分发到了,端口号:" + serverProperties.getPort() + "的服务,接口访问成功.";
        }
    }
    

    配置转发

    我们测试所需要的请求接口已经准备好了,接下来需要在访问nginx时将请求转发到我们测试的接口,配置转发时需要用到nginx的两个关键字,分别是upstreamlocation

    • upstream:服务器组,配置请求分发到组内多台服务器。
    • location:转发的路径前缀,如:"/user/",当我们访问http://127.0.0.1/user/1时,就会执行该location的转发业务。

    upstream转发流程如下图所示:

    image

    配置UpStream

    nginx.conf文件http内添加转发的服务器组(upstream),如下所示:

    # 负载配置
    upstream test {
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:9090 weight=2;
        server 127.0.0.1:9000 backup;
    }
    

    配置Location

    在上面已经配置好了服务器组,我们需要把名为test的服务器组作为代理的方式配置在location,在locationserver下新增一个location,如下所示:

    # 配置"/lb/"路径的请求全部转发到本地8080端口
    location /lb/ {
        proxy_pass http://test/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_connect_timeout       50;
        proxy_read_timeout          50;
        proxy_send_timeout          50;
    }
    

    重启Nginx

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

    brew services restart nginx
    

    如果你是安装包的方式安装:

    # 进入安装包目录
    cd /usr/local/nginx/sbin
    # 重载
    ./nginx -s reload
    

    权重配置

    nginx中有一个权重的概念,根据权重值的大小来控制请求流量,当权重的配值越大时,流量分发就会越多,我们在test服务器组内配置权重解释:

    • server 127.0.0.1:8080 weight 1; 权重占比为1/3,每3次请求会转发1次到这台服务器上。
    • server 127.0.0.1:9090 weight 2; 权重占比为2/3,每3次请求会转发2次到这台服务器上。

    备用配置

    当我们在upstream内的server尾部添加backup时,表示这台服务器是备用服务器,只有其他服务器都停机时才会启用,我们更新时其实就利用的这一点。

    运行测试

    为了演示方便我们直接将本章测试项目package打包后,通过--server.port来指定运行的端口号来模拟多台服务器的场景。

    # 启动127.0.0.1:8080服务器
    java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=8080
    # 启动127.0.0.1:9090服务器
    java -jar target/use-nginx-loadbalance-upgrade-service-0.0.1-SNAPSHOT.jar --server.port=9090
    # 启动127.0.0.1:9000备用服务器
    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服务器组内的服务器上。

    测试点:权重转发

    curl http://localhost/lb/test
    端口号:8080,接口访问成功.                                                                                                        
    
    curl http://localhost/lb/test
    端口号:9090,接口访问成功.
    
    curl http://localhost/lb/test                                                                                                       
    端口号:9090,接口访问成功.
    
    curl http://localhost/lb/test                                                                                                      
    端口号:8080,接口访问成功. 
    

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

    测试点:备用生效

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

    curl http://localhost/lb/test
    端口号:9000,接口访问成功.
    
    curl http://localhost/lb/test                                                                                                       
    端口号:9000,接口访问成功.      
    
    curl http://localhost/lb/test                                                                                                  
    端口号:9000,接口访问成功.
    

    可以看到我们的备用服务器启用了,已经把全部的请求流量转发到9000这台服务上,测试通过。

    敲黑板,划重点

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

    代码示例

    如果您喜欢本篇文章请为源码仓库点个Star,谢谢!!!
    本篇文章示例源码可以通过以下途径获取,目录为use-nginx-loadbalance-upgrade-service

    作者个人 博客
    使用开源框架 ApiBoot 助你成为Api接口服务架构师

    相关文章

      网友评论

        本文标题:使用nginx的负载均衡机制实现用户无感更新服务

        本文链接:https://www.haomeiwen.com/subject/ycaeactx.html