SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务)
作者:mmseoamin日期:2024-01-22

文章目录

    • 前言
    • 1.痛点
    • 2.解决方案
    • 3.具体实现
      • 3.1搭建热配置服务
      • 3.2编写配置文件
      • 3.3搭建版本控制仓库
      • 3.4Eureka-Client引入以下依赖
      • 3.5Eureka-Client微服务编写以下配置bootstrap.yml提前加载
      • 3.6分别编写测试Controller
      • 3.7测试效果
      • 3.8下线场景压测
      • 4.SpringCloudBus优化

        前言

        在上文讲到,在发布服务的场景下通过MQ利用“下线”这一事件驱动去更新Ribbon缓存,搭配上更改Eureka的两个配置信息成功实现了Eureka服务下线无感知。当时就说这个过程中存在一个非常鸡肋的地方,就是在通知前要去更改Eureka的配置参数。本文将通过配置热更新搭配SpringCloudBus消息总线的方式来将其解决。

        1.痛点

        发布服务场景特殊,如果关闭Eureka-Server三级缓存、对Eureka-Client的参数进行修改势必会对高可用性产生影响。如果可以在这个过程中进行配置热更新,在下线旧服务发布新服务这一特定情况下对Eureka配置进行更改做到既支持服务的无感知下线,又不影响非此场景下Eureka的性能就好了。

        2.解决方案

        使用SpringCloudConfig+Actuator+Git来实现配置热更新,服务发布的场景下热更新配置,人为保证Eureka数据强一致用来实现服务下线无感知。服务发布完恢复Eureka原生配置保证高可用。总结来看就是在对服务数据一致性有要求的情况下,去做到一致性;没有此要求的情况下去还原高可用

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第1张

        3.具体实现

        3.1搭建热配置服务

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第2张

        引入依赖:

        
            
                org.springframework.cloud
                spring-cloud-config-server
                2.2.3.RELEASE
            
        
        

        3.2编写配置文件

        #服务端口
        server:
          port: 8086
          #指定应用名称
        spring:
          application:
            name: config-center
          cloud:
            config:
              label: master #配置git仓库分支
              server:
                git:
                  uri: https://gitee.com/lazy-sheep-java/cloud-config.git #配置git仓库地址
                  search-paths: cloud-config/application.yml #配置仓库路径
                  #username:  git_username #访问git仓库的用户名,公开仓库不配置用户名
                  #password: git_password #访问git仓库的用户密码,公开仓库不配置密码
        

        3.3搭建版本控制仓库

        创建一个yml配置文件

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第3张

        application-dev.yml文件内容

        声明:该文件内容是和项目中的参数一致的,没有作出更改

        eureka:
            client:
              registry-fetch-interval-seconds: 3
              #每次获取全量注册信息
              disable-delta: true
              #服务消费者从注册中心拉取服务列表
              fetch-registry: true
            server:
              #三级缓存开关
              useReadOnlyResponseCache: false
        

        3.4Eureka-Client引入以下依赖

        
        
            org.springframework.cloud
            spring-cloud-starter-config
        
        
            org.springframework.boot
            spring-boot-starter-actuator
        
        

        3.5Eureka-Client微服务编写以下配置bootstrap.yml提前加载

        spring:
          application:
            name: payment-service
          cloud:
            config:
              uri: http://localhost:8086    #config服务端的地址
              label: master
              profile: dev              #开发环境
        

        并在application.yml中配置actuator支持

        #Actuator
        management:
          endpoint:
            shutdown:
              enabled: false
          endpoints:
            web:
              exposure:
                include: "*"
        

        3.6分别编写测试Controller

        @RestController
        @RefreshScope
        public class TryConfigController {
            @Value("${eureka.client.registry-fetch-interval-seconds}")
            private String seconds;
            @GetMapping("info")
            public String info(){
                return seconds;
            }
        }
        @RestController
        @RefreshScope
        public class TryController {
            @Value("${eureka.server.useReadOnlyResponseCache}")
            private String flag;
            @GetMapping("info")
            public String info(){
                return flag;
            }
        }
        

        3.7测试效果

        到此时Eureka-Client端application.yml中的核心配置参数eureka.client.registry-fetch-interval-seconds的值为10秒,并且Eureka-server端三级缓存为开启状态

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第4张

        我们启动所有微服务,访问测试Controller的接口,观察该属性的值:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第5张SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第6张

        可以看到为10S,与此同时观察控制台日志输出情况,Eureka-Client拉取Eureka-Server端的服务列表时间间隔:SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第7张

        可见此时Eureka配置参数还与该模块下的application.yml保持一致!

        在不全程不重启微服务的前提下,当我们向存在git仓库中的application-dev.yml文件进行更改(关闭了三级缓存,将Eureka-Client从Eureka-server拉取服务列表的时间变为2S),并且push上去。

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第8张

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第9张

        此时分别调用Actuator提供的动态刷新接口去刷新对应微服务的热配置http://localhost:8088/actuator/refresh,http://localhost:10086/actuator/refresh,刷新成功并返回了如下结果:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第10张

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第11张

        此时调用测试接口,测试Eureka配置属性变化:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第12张

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第13张

        这说明不重启情况下完成了配置热更新,为了进一步观察效果,直接去日志中查看:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第14张

        这说明热更新成功实现!

        3.8下线场景压测

        基于此,去做Eureka服务下线感知情况的压测,调用下线接口后立即压测,观察下线服务是否被负载均衡到:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第15张

        立即使用Jmeter压测,可以看到异常情况是没有的:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第16张

        观察控制台,下线服务实例是否被负载均衡到?

        8083

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第17张

        8081

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第18张

        8084

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第19张

        可见完全没问题,这时就可以kill掉下线的服务实例,去发布新服务了,当新服务发布完毕又去push配置来热更新还原原生配置保证Eureka高可用:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第20张

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第21张

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第22张

        4.SpringCloudBus优化

        Spring-Cloud-Bus:广播配置文件的更改或服务的监控管理,用于实现微服务的监控和相互通信,配合SpringCloudConfig使用,实现配置的动态刷新。当一个服务刷新数据时,将信息放入消息总线中,其他监听该消息总线的服务就能得到通知并更新自身的配置

        整个流程下来相信大家可以深刻体会到,每次Git中的配置文件发生更改,我都要去基于属性变更的微服务去调用http://localhost:对应端口/actuator/refresh发送POST请求,如果服务集群部署数量较少那运维工作量还不算大,但反之就有点折磨运维老哥了。

        基于此,可以使用SpringCloudBus的广播模式将配置文件更新的动作广播出去,让受其管理的微服务、集群都去刷新配置

        具体实现如下:

        1.在目标微服务中配置好mq(如文章上面所示),并引入Spring-Cloud-Bus的依赖

        
           org.springframework.cloud
           spring-cloud-starter-bus-amqp
        
        

        2.当Git中的配置文件更新,直接调用接口:http://localhost:任选一个服务列表中的端口/actuator/bus-refresh POST

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第23张

        即完成受Spring-Cloud-Bus管控的所有微服务的配置热更新:

        SpringCloudConfig+SpringCloudBus+Actuator+Git实现Eureka关键配置属性热更新(全程不重启服务),在这里插入图片描述,第24张

        出现Keys refreshed[…]说明更新配置广播完毕,所有的目标微服务的配置都完成了热更新!一次调用更新所有,大大简化了操作