Spring Cloud系列之配置中心Config

Spring Cloud系列之Eureka
Spring Cloud系列之配置中心Config
Spring Cloud系列之gateway
Spring Cloud系列之Feign
Spring Cloud系列之Hystrix
Spring Cloud系列之链路追踪

配置中心可以简单的理解为一个服务模块,开发人员或运维人员可以通过界面对配种中心进行配置,下面相关的微服务连接到配置中心上面就可以实时连接获取到配置中心上面修改的参数。更新的方式一般有两种

  • pull模式,服务定时去拉取配置中心的数据

  • push模式,服务一直连接到配置中心上,一旦配置有变成,配种中心将把变更的参数推送到对应的微服务上

这两种做法其实各有利弊

  • pull可以保证一定可以拉取得到数据,pull一般采用定时拉取的方式,即使某一次出现网络没有拉取得到数据,那在下一次定时器也将可以拉取得到数据,最终保证能更新得到配置

  • push也有好处,避免pull定时器获取存在时延,基本可以做到准实时的更新,但push也存在问题,如果有网络抖动,某一次push没有推送成功,将丢失这次配置的更新

目前比较流行的配种中心开源组件有Spring Cloud Config,百度的disconf,阿里的Nacos,还有携程的apollo。

实现原理大同小异

配置中心.png

实践

config server搭建
  • 引入依赖


    
        dy-springcloud
        com.dy
        0.0.1-SNAPSHOT
    
    4.0.0

    com.dy
    config-server

    

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

        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-client
        

    


  • 配置文件
#eureka 参数配置
eureka:
  # 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
  instance:
    #  与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
    hostname: localhost
    # 获取实例的ip地址
    prefer-ip-address: true
    #  eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒
    lease-renewal-interval-in-seconds: 10
    #  Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
    lease-expiration-duration-in-seconds: 30
  client:
    # 注册自己
    register-with-eureka: true
    # 是否拉取服务
    fetch-registry: true
    # 配置注册中心服务地址
    service-url:
      # eureka 服务地址
      defaultZone: http://172.16.10.16:10001/eureka
server:
  port: 10002
spring:
  application:
    name: config-server
  cloud:
    # cloud配置中心相关配置
    config:
      server:
        # git相关配置
        git:
          # git 地址
          uri: https://gitee.com/dai-yong-1/config-server-dy.git
          # git用户名
          username: xxxx
          # git密码
          password: xxxxx
          # 配置文件所在文件夹
          search-paths: config-yml

配置中心git仓库如下:

配置中心git仓库.png
  • 启动类
/**
 * @Description:
 * @author: dy
 */
@EnableConfigServer  //声明当前应用是config server服务
@EnableDiscoveryClient //开启Eureka客户端发现功能
@SpringBootApplication
public class ConfigServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigServerApplication.class, args);
    }

}
config client 搭建
  • 引入依赖


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

    
    
        org.springframework.cloud
        spring-cloud-starter-netflix-eureka-client
    


  • 配置类
server:
  port: 11001
spring:
  application:
    name: user-service
  cloud:
    config:
      enabled: true
      # 与远程仓库中的配置文件的application保持一致
      name: user-service
      # 远程仓库中的配置文件的profile保持一致
      profile: dev
      # 远程仓库中的 分支 版本保持一致
      label: master
      # config server地址
      uri: http://localhost:10002/
      # 配置的用户名密码
      username: root
      password: root

在git仓库里面我们新建了一个配置文件user-service-dev.yml,配置内容如下:

dy:
  config:
    app-id: 110
    app-name: 'user-service-name'

使用的时候在config client端我们新建一个配置文件:

package com.dy.user.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

/**
 * @Description:
 * @author: dy
 */
@Data
@Component
@Configuration
@ConfigurationProperties(prefix = "dy.config")
public class AppInfo {

    private String appId;

    private String appName;

}

测试类如下:

package com.dy.user.resource;

import com.dy.user.client.UserClient;
import com.dy.user.config.AppInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description:
 * @author: dy
 */
@Slf4j
@RestController
@RequestMapping(UserClient.MAPPING)
public class UserResource implements UserClient {

    @Autowired
    private AppInfo appinfo;

    @Override
    public String getUserId() {
        return "======111111222>>"+appinfo.getAppId();
    }
}

运行结果如下:

配置中心运行结果.png

如此我们就大致实现了配置中心的基础功能

config刷新功能

但是如果我们线上实时修改了git仓库里面的配置文件内容,那我们的客户端怎么及时读取git仓库里面实时的文件内容呢?

spring cloud config给我们提供了两种方式:

  • config配置手动刷新

  • 自动刷新

config配置手动刷新
  • 引入依赖


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

  • 添加配置
management:
  #启用监控 默认打开health和info,* 表示开放所有端口
  endpoints:
    web:
      exposure:
        include: *
  #打印健康信息详情
  endpoint:
    health:
      show-details: always
  • 引用类里面添加注解@RefreshScope

    该注解处代理的bean会在调用/refresh接口时被清空

@Slf4j
@RestController
@RequestMapping(UserClient.MAPPING)
@RefreshScope
public class UserResource implements UserClient {

    @Autowired
    private AppInfo appinfo;

    @Override
    public String getUserId() {
        log.info("==============请求来了===============");
        return "======111111222>>"+appinfo.getAppId();
    }
}
  • 先修改git仓库配置文件内容

  • 再调用http://localhost:11001/actuator/refresh 进行手动刷新,注意是:post方式访问

  • 请求接口我们可以发现内容改变了

虽然手动刷新可以避免我们重启服务,但是每次去刷脚本跑接口刷新每个服务感觉十分不便,那有什么更好的方式呢?

config自动刷新

在微服务架构体系中,我们可以接口消息总线bus实现配置的自动更新,也就是Spring Cloud Config+Spring Cloud Bus

Spring Cloud Bus是基于MQ的,支持Rabbitmq/Kafka,是Spring Cloud的消息总线方案。

具体实现流程如下:

配置中心自动刷新流程.png

具体实现如下(mq我们使用的是Rabbitmq):

config server端

  • 引入依赖


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

  • 添加配置
server:
  port: 10002
spring:
  application:
    name: config-server
  # 这里我们用的rabbitmq
  rabbitmq:
    addresses: amqp://192.168.2.56:5672
    username: sxw_demo
    password: sxw_demo
  cloud:
    # cloud配置中心相关配置
    config:
      server:
        # git相关配置
        git:
          # git 地址
          uri: https://gitee.com/dai-yong-1/config-server-dy.git
          # git用户名
          username: 15828101225
          # git密码
          password: hd961740841
          # 配置文件所在文件夹
          search-paths: config-yml
          
#eureka 参数配置  
eureka:
  # 此实例注册到eureka服务端的唯一的实例ID,其组成为${spring.application.name}:${spring.application.instance_id:${random.value}}
  instance:
    #  与此实例相关联的主机名,是其他实例可以用来进行请求的准确名称
    hostname: localhost
    # 获取实例的ip地址
    prefer-ip-address: true
    #  eureka客户需要多长时间发送心跳给eureka服务器,表明它仍然活着,默认为30 秒
    lease-renewal-interval-in-seconds: 10
    #  Eureka服务器在接收到实例的最后一次发出的心跳后,需要等待多久才可以将此实例删除,默认为90秒
    lease-expiration-duration-in-seconds: 30
  client:
    # 注册自己
    register-with-eureka: true
    # 不拉取服务
    fetch-registry: true
    # 配置服务地址
    service-url:
      # eureka 服务地址,如果是集群的话;需要指定其它集群eureka地址  ,如果是多台eureka server 地址以逗号隔开
      defaultZone: http://172.16.10.16:10001/eureka

management:
  #启用监控 默认打开health和info,* 表示开放所有端口
  endpoints:
    web:
      exposure:
        include: "*"
  #打印健康信息详情,
  endpoint:
    health:
      show-details: always

config client端

  • 引入依赖


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

  • 添加配置
server:
  port: 11001
spring:
  application:
    name: user-service
  rabbitmq:
    addresses: amqp://192.168.2.56:5672
    username: sxw_demo
    password: sxw_demo
  zipkin:
    # zipkin server的请求地址
    base-url: http://localhost:10005/
    sender:
      #web 客户端将踪迹日志数据通过网络请求http的方式发送到服务端
      #rabbit 客户端将踪迹日志数据通过mp  rabbit的方式发送到服务端
      #kafka 客户端将踪迹日志数据通过mp  kafka的方式发送到服务端
      type: web
  sleuth:
    sampler:
      probability: 1 # 采样率
  cloud:
    config:
      enabled: true
      # 与远程仓库中的配置文件的application保持一致
      name: user-service
      # 远程仓库中的配置文件的profile保持一致
      profile: dev
      # 远程仓库中的 分支 版本保持一致
      label: master
      # config server地址
      uri: http://localhost:10002/
      # 配置的用户名密码
      username: root
      password: root

运行项目操作步骤如下:

  • 修改git仓库配置文件内容

  • 向config server发起post请求http://localhost:10002/actuator/bus-refresh

  • 调用接口就可以发现拉取到了最新文件内容信息

如果要实现修改完远程git文件自动刷新配置的话,可以在git上面添加一个WebHooks, URL需要把本地的 http://localhost:10002/actuator/bus-refresh映射成公网IP.可以使用第三方内网穿透实现.具体如下:

配置中心wehooks配置.png

你可能感兴趣的:(Spring Cloud系列之配置中心Config)