配置中心意义
集中管理,版本控制,和代码解耦
避免了反复修改编译代码,重启微服务,重新打包。
config
结合euraka
配置实例
配置config server
添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
在启动类添加注解 @EnableConfigServer
@SpringBootApplication
@EnableConfigServer
public class ConfigServerWebApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerWebApplication.class);
}
}
配置文件
spring:
application:
name: config-sever
# 必须配置 ,不然会报错
# If you are using the git profile, you need to set a Git URI in your configuration. If you are using a native profile and have spring.cloud.config.server.bootstrap=true, you need to use a composite configuration.
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:/config/
server:
port: 9080
eureka:
client:
fetch-registry: true
# 注册到Eureka
register-with-eureka: true
serviceUrl:
#Eureka2地址
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}:${spring.cloud.client.hostname}
logging:
level:
root: DEBUG
在resources目录下新建config
目录并添加客户端的配置文件user-dev.yml
management:
endpoints:
web:
exposure:
include: shutdown #开启shutdown端点访问
endpoint:
shutdown:
enabled: true #开始shutdown实现优雅停服,shutdown端点比较特殊,默认开启为false
logging:
level:
root: INFO
my:
arg: 123
请求配置文件http://localhost:9080/user/dev,返回
{"name":"user","profiles":["dev"],"label":null,"version":null,"state":null,"propertySources":[{"name":"classpath:/config/user-dev.yml","source":{"management.endpoints.web.exposure.include":"shutdown,refresh","management.endpoint.shutdown.enabled":true,"logging.level.root":"INFO","my.arg":123456}}]}
配置config客户端
导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!--配置中心客户端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
配置文件 bootstrap.yml
这里必须使用bootstrap.yml
因为spring cloud配置加载顺序: 加载bootstrap.* 配置 --> 连接config-server
,加载远程配置 --> 加载application.* 配置
spring:
application:
name: user
cloud:
config:
profile: dev
discovery:
enabled: true #默认false,设为true表示使用注册中心中的configserver配置,而不是自己配置configserver的uri
service-id: CONFIG-SERVER #指定config server在服务发现中的serviceId,默认为:configserver
server:
port: 8080
eureka:
instance:
# 注册服务时是否使用IP注册,默认false;如果为false,则注册本机的机器名,如果设置了`eureka.instance.hostname`,则注册的是hostname
prefer-ip-address: false
instance-id: ${spring.cloud.client.ip-address}:${server.port}
# 服务续约任务调用间隔时间,默认30秒,client每隔30秒向Eureka server发送心跳
lease-renewal-interval-in-seconds: 30
# 服务时效时间,默认90秒;当Eureka server 90秒内没有收到client的注册信息时,会将该节点标记失效,然后等待定时任务-清除失效服务执行清除。
lease-expiration-duration-in-seconds: 60
client:
fetch-registry: true
register-with-eureka: true
serviceUrl:
# eureka集群,多个英文逗号隔开
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/
手动热刷新
热刷新是什么
不重启前提,刷新应用,spring cloud config
中的热刷新,是不重启spring应用,刷新spring容器。
配置实例
引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
在对应的类上加注解@RefreshScope
加这个的目的是为了在修改配置后不启动客户端
然后在客户端配置文件放开refresh端点
management:
endpoints:
web:
exposure:
include: refresh #开启refresh端点
POST请求 curl -X POST http://localhost:8080/actuator/refresh;注意域名和ip
是客户端的
注意:如果config server
配置的search-locations: classpath:/config/
那么当修改config server
的配置文件时,是修改的classpath
路径下的文件,而不是idea开发工具对应的resources目录,切记!
消息总线BUS实现全局热刷新
两种架构模式,一种是在每个config客户端安装BUS,服务端不安装,然后请求任意一个Config客户端的/bus/refresh;另外一种是除了每个客户端安装BUS,然后在服务端也安装BUS,然后请求服务端的/bus/refresh;
推荐使用第二种:配置刷新工作应有Config server
承担
下面就来配置第二种BUS总线刷新
config server
和config client
导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
当服务/actuator/bus-refresh被调用的时候,自动发消息到RabbitMQ
上的springCloudBus
交换机上,所有客户端自动处理此消息,热刷新应用。使用的是topic交换器exchange,配合#路由键,做的广播消息处理。
每个客户端启动的时候,在MQ
上,创建一个队列,并监听,绑定在同一个交换器上,且路由键是#。
如下图所示,每个客户端(包括服务端)都创建了一个消息队列,队列名格式为springCloudBus.anonymous.随机数
,并都绑定到springCloudBus
交换机上,绑定的Routing key为#
补充
- topic Exchange 主题交换器
工作方式和Direct Exchange 直接交换器类似,也需要通过routing_key来匹配queue,区别是topic Exchange支持模糊匹配,支持通配符*和#,*代表匹配一个任务词组,#代表匹配0个或者多个词组,例如routing_key=user.add
会匹配user.#
,\*.add
等binding_key,当我们发消息给exchange时,会传递一个routing_key用来匹配binding_key,从而决定发送到哪个queue。
config server
配置文件
spring:
application:
name: config-server
# 必须配置 ,不然会报错
# If you are using the git profile, you need to set a Git URI in your configuration. If you are using a native profile and have spring.cloud.config.server.bootstrap=true, you need to use a composite configuration.
profiles:
active: native
cloud:
config:
server:
native:
search-locations: classpath:/config
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
management:
endpoints:
web:
exposure:
include:
- info
- health
- bus-refresh #基于bus提供的全局热刷新,只处理POST请求。刷新spring容器
server:
port: 9080
eureka:
client:
fetch-registry: false
# 注册到Eureka
register-with-eureka: true
serviceUrl:
#Eureka2地址
defaultZone: http://127.0.0.1:7001/eureka/,http://127.0.0.1:7002/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}:${spring.cloud.client.hostname}
logging:
level:
root: info
修改服务端配置,然后执行 curl -X POST http://localhost:9080/actuator/bus-refresh 各个客户端监听到消息会重新拉取config server
配置。