概念

从上一节 [2:SpringCloud Config配置中心] 中可以看到当配置中心服务中的配置变更后,如果不重启各个客户端服务,客户端服务无法获取到变更后的配置内容。
为了解决这一问题,SpringCloud提供了一个消息总线(SpringCloud Bus),它本质上是一个消息系统,目前有rabbitmq和kafka两种实现。
在这里插入图片描述

原理

在这里插入图片描述

  • 1,当配置变更后,我们调用刷新接口:默认为 http://ip:port/actuator/bus-refresh ,图中的bus/refresh是D版以前的接口,我们现在是基于G版的代码,默认已经变成了/actuator/bus-refresh
    注:这里的 ip:port 可以是任意一个接入到了消息总线bus的服务,由于一般其它业务服务都是通过gateway来调用的,并不对外暴露 ip:port,而配置中心configServer是需要对外暴露ip的,所以一般会在注册中心configServer上调用刷新接口
  • 2,注册中心configServer接收到刷新命令后,会把刷新消息广播到SpringCloud Bus消息总线
  • 3,其它各个服务会接受到SpringCloud Bus消息总线广播的刷新消息,
  • 4,各个服务重新从注册中心configServer上面拉取变更后的配置

springCloud Config配置中心

先创建并启动一个接入SpringCloud Bus消息总线的配置中心服务:
1,创建一个maven项目scd-config-server-bus
项目名称可以按需自定义
2,引入pom依赖

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-parent -->
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-parent</artifactId>
		<version>Greenwich.RELEASE</version>
	</parent>
	
	<groupId>com.scd</groupId>
	<artifactId>scd-config-server-bus</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
	<name>scd-config-server-bus</name>
	<url>http://maven.apache.org</url>
	
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-config-server</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-bus-amqp</artifactId>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	
</project>
  • 引入消息总线spring-cloud-starter-bus-amqp,消息总线有rabbitm和kafka两种实现,如果用kafka的话,引入spring-cloud-starter-bus-kafka即可。我们用rabbitmq作为示例

3,启动类上加@EnableConfigServer注解

@SpringBootApplication
@EnableConfigServer
public class Application {

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

}

4,加上application.yml配置

spring:
  application:
    name: scd-config-server-bus
  profiles:
    active:
    - native #使用本地配置
  cloud:
    config:
      server:
        bootstrap: true
        native:
          search-locations:
          - classpath:config-repo/ # 搜索src/main/resource 下的config-repo文件夹下的文件
# git配置
#        git:
#          uri: https://gitee.com/ifrozen/spring-cloud-demo
#          search-paths:
#          - config-repo
#          username: username
#          password: password
  #-------------------------------------------------------------------------
  rabbitmq:
    host: 192.168.14.231
    port: 5672
    username: i5x
    password: i5xrabbitmq
    virtual-host: i5x
#-------------------------------------------------------------------------
management:
#  actuator的端口可以单独定义,如果不定义的话,默认为${server.port}
#  server:
#    port: 31000
  endpoints:
    web:
      exposure: 
        include: "*" #默认只暴露了/actuator/info和/actuator/health,没有暴露/actuator/bus-refresh,这里把所有endpoints都暴露了
      cors:
        allowed-origins: "*"
        allowed-methods: "*"
#---------------------------------------------------------------------    
server:
  port: 50010
#---------------------------------------------------------------------
eureka:
  instance:
    prefer-ip-address: true
    status-page-url-path: /actuator/info
    health-check-url-path: /actuator/health
    hostname: localhost
  client:
    register-with-eureka: true #把本服务也注册到注册中心,从注册中心的服务列表中可以看到本服务
    fetch-registry: true #从注册中心拉取服务列表
    service-url:
      defaultZone: http://localhost:50000/eureka/
  • spring.rabbitmq.xxx为rabbitmq的连接配置,消息总线需要使用rabbitmq来通信
  • management.endpoints.web.exposure.include: “*”,表示把所有endpoints端点都暴露出去,默认只暴露了/actuator/info和/actuator/health,没有暴露/actuator/bus-refresh
  • management.endpoints.web.exposure.cors为跨域设置

5,创建配置仓库
在上面一步中设置了spring.cloud.config.server.native.search-locations为classpath:config-repo/ ,即仓库位置为src/main/resource 下的config-repo文件夹
在这里插入图片描述
我们创建scd-biz-smile-dev.yml,scd-biz-smile-test.yml,scd-biz-smile-prod.yml三个配置文件,分别代表调试,测试和正式环境的配置文件。
里面只有一个属性smile,值分别为dev,test,prod。例scd-biz-smile-dev.yml

smile: dev

完整示例代码可以参照:https://gitee.com/ifrozen/spring-cloud-demo/tree/master/demo-3

6,启动配置中心服务
启动配置中心服务,访问 http://localhost:50000/ 可以看到配置中心服务的启动状况

springCloud Config客户端

创建并启动一个接入消息总线SpringCloud Bus的客户端服务:
1,创建一个maven项目scd-biz-smile-bus
项目名称可以按需自定义
2,引入pom依赖

<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-parent -->
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-parent</artifactId>
		<version>Greenwich.RELEASE</version>
	</parent>
	
	<groupId>com.scd</groupId>
	<artifactId>scd-biz-smile-bus</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	
	<name>scd-biz-smile-bus</name>
	<url>http://maven.apache.org</url>
	
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>
	
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>
				spring-cloud-starter-netflix-hystrix
			</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-config</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-bus-amqp</artifactId>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
	
</project>
  • 引入消息总线spring-cloud-starter-bus-amqp,消息总线有rabbitm和kafka两种实现,如果用kafka的话,引入spring-cloud-starter-bus-kafka即可。我们用rabbitmq作为示例

3,启动类,普通的SpringCloudApplication启动类即可

@SpringCloudApplication
public class Application {

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

}

创建一个普通controller类读取配置文件中的smile属性,一定要加上@RefreshScope注解,否则不会被bus刷新

@RefreshScope
@RestController
public class SmileController {

	@Value("${smile}")
	private String smile;
	
	@GetMapping("/config")
	public String config() {
		return smile;
	}
	
}

消息总线会刷新两种类中的配置属性

  • @RefreshScope注解修饰的类
  • @ConfigurationProperties注解定义的类:例spring.rabbitmq的定义类RabbitProperties
@ConfigurationProperties(prefix = "spring.rabbitmq")
public class RabbitProperties {

	/**
	 * RabbitMQ host.
	 */
	private String host = "localhost";

	/**
	 * RabbitMQ port.
	 */
	private int port = 5672;

	/**
	 * Login user to authenticate to the broker.
	 */
	private String username = "guest";

	/**
	 * Login to authenticate against the broker.
	 */
	private String password = "guest";
	.......
	.......
}

4,yml配置文件
由于从配置中心拉取配置仓库要先于其它功能的启动,其它功能才能读取到配置。
所以配置文件需要增加一个bootstrap.yml,spring启动的时候,会先读取bootstrap.yml的配置来启动,然后再读取application.yml的配置来启动。
使用配置中心后,客户端服务的eureka配置和config配置必须写到bootstrap.yml里面去,其它配置可以写到application.yml里面去。

bootstrap.yml

spring:
  cloud:
    config:
      discovery:
        enabled: true
        service-id: scd-config-server-bus
      label: config-repo
      name: scd-biz-smile
      profile: dev
#---------------------------------------------------------------------
eureka:
  instance:
    prefer-ip-address: true
    status-page-url-path: /actuator/info
    health-check-url-path: /actuator/health
    hostname: localhost
  client:
    register-with-eureka: true #把本服务也注册到注册中心,从注册中心的服务列表中可以看到本服务
    fetch-registry: true #从注册中心拉取服务列表
    service-url:
      defaultZone: http://localhost:50000/eureka/
  • spring.cloud.config.discovery.enabled用来开启配置中心
  • spring.cloud.config.discovery.service-id指定配置中心服务
  • spring.cloud.config.label对应配置仓库的目录,本例中为 config-repo
  • spring.cloud.config.name对应配置文件名称最后一个 - 符号前面的名称,本例中为 scd-biz-smile
  • spring.cloud.config.profile对应配置文件名称最后一个 - 符号后面的名称,本例中为 dev

application.yml

spring:
  application:
    name: scd-biz-smile-bus
  #-------------------------------------------------------------------------
  rabbitmq:
    host: 192.168.14.231
    port: 5672
    username: i5x
    password: i5xrabbitmq
    virtual-host: i5x
#---------------------------------------------------------------------    
server:
  port: 50020
  servlet:
    context-path: /smile
#---------------------------------------------------------------------
  • server.servlet.context-path为项目名
  • spring.rabbitmq.xxx为rabbitmq的连接配置,消息总线需要使用rabbitmq来通信

完整示例代码可以参照:https://gitee.com/ifrozen/spring-cloud-demo/tree/master/demo-3

启动服务后,可以现在 http://localhost:50000/ 查看服务启动情况:
在这里插入图片描述

访问 http://localhost:50020/smile/config rest接口:
在这里插入图片描述

springCloud bus刷新配置

1,修改配置仓库的scd-biz-smile-dev.yml文件,把smile值改为dev-update:

smile: dev-update

2,然后不重启scd-biz-smile服务,直接访问 http://localhost:50020/smile/config rest接口,发现返回的还是变更前的dev

3,利用postman或者curl工具,发送post http://localhost:50010/actuator/bus-refresh ,这里的localhost:50010为注册中心服务scd-config-server-bus的ip和port,只有其暴露了/actuator/bus-refresh端点
在这里插入图片描述
可以查看scd-biz-smile-bus服务的log
在这里插入图片描述
4,再次访问 http://localhost:50020/smile/config rest接口:
在这里插入图片描述
可见已经取到了最新的配置值

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐