分布式配置中心 Spring cloud config

spring cloud config 是用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端和客户端,其中服务端被称为分布式配置中心,它是一个独立的微服务应用,用来链接仓库,并为客户端提供配置信息。

快速入门

搭建配置中心

  1. 创建工程,导入相关依赖
1
2
3
4
5
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>

  1. 在主程序类中开启sprong cloud config的服务端功能
1
2
3
4
5
6
7
8
@SpringBootApplication
@EnableConfigServer
public class ConfigServerApplication {

public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class, args);
}
}
  1. 添加配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
application:
name: config-service
cloud:
config:
server:
git:
uri: https://github.com/zofun/spring-cloud-config.git # 仓库的位置
username:
password:
search-paths: test/config-repo
server:
port: 8090

  1. 上传配置文件到GitHub仓库的test/config-repo目录下
  2. 通过url范围获取配置文件/{application}-{profile}.yml

搭建spring cooud config客户端

  1. 创建spring boot应用并添加相关依赖
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
  1. 创建配置文件
1
2
3
4
5
6
7
8
9
10
11
spring:
application:
name: didispace
cloud:
config:
profile: dev
label: master
uri: http://localhost:8090/
server:
port: 7002

  1. 写一个用来测试的RESTful接口
1
2
3
4
5
6
7
8
9
10
11
12
13
@RefreshScope
@RestController
public class TestController {

@Value("${from}")
private String from;

@RequestMapping("/from")
public String from(){
return from;

}
}

服务化配置中心

服务端配置

  1. 在config-server中添加eureka相关的依赖
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  1. 配置相关参数
1
2
3
4
eureka:
client:
serviceUrl:
defaultZone: http://peer1:8083/eureka/
  1. 编辑主类
    添加@EnableDiscoveryClient注解
1
2
3
4
5
6
7
8
9
10
11

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerApplication {

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

}

客户端配置

  1. 添加相关的依赖
1
2
3
4
5
6
7
8
<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-eureka</artifactId>
</dependency>
  1. 添加相关的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
application:
name: didispace
cloud:
config:
discovery:
enabled: true
service-id: config-service
profile: dev
server:
port: 7002

eureka:
client:
serviceUrl:
defaultZone: http://peer1:8083/eureka/
  1. 修改主类,添加@EnableDiscoveryClient注解
1
2
3
4
5
6
7
8
9
@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClientApplication {

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

}

动态刷新配置

改造config-client。

  1. 在pom中增加spring-boot-starter-actuator监控模块,利用其中的/refresh端点实现来实现配置信息的重新获取与刷新
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

注意:springboot2.0之后默认是不开启/refresh端点的,需要手动开启

1
2
3
4
5
management:
endpoints:
web:
exposure:
include: "*"

测试:

  1. 访问http://localhost:7002/from查看配置信息
  2. 更新仓库中的配置文件
  3. 访问http://localhost:7002/from查看配置信息,没有改变
  4. 请求http://localhost:7002//actuator/refresh
  5. 再次访问http://localhost:7002/from配置信息已经被改变了

我们可以利用/refresh和github的webhooks来实现自动更新
KFII6x.png

消息总线 spring cloud bus

在微服务架构中,我们使用轻量级的消息代理来构建一个共用的消息主题让系统所有微服务都连接上来,由于该主题中产生的消息会被所有实例监听和消费,所以我们称他为消息总线。

消息代理

消息代理是一种消息验证、传输、路由的架构模式。他在应用程序之间起到通信调度并最小化应用之间的依赖的作用,使得应用程序之间能够高效的解耦通信过程。
使用消息代理的场景:

  1. 将消息路由到一个或多个目的地。
  2. 将消息转化为其它的表现形式
  3. 执行消息的聚集、消息的分解。并将结果发送到它们的目的地。
  4. 调用web服务来检索数据。
  5. 响应事件或错误。
  6. 使用发布-订阅模式来提供内容或基于主题的消息路由。

RabbitMq实现消息总线

基本概念

  1. Broker:消息队列服务器实体,负责接收消息生成者的消息,然后将消息发送至消息接收者或者其它的Broker
  2. Exchange:消息交换机,是消息到达的第一个地方,消息通过它指定的路由规则分发到不同的消息队列中去。
  3. Queue:消息队列。进入消息队列中消息进入逻辑上的等待消费的状态。
  4. Binding:绑定:它的作用就是将Exchange和queue按照一定的路由规则绑定起来。也就是Exchange和Queue之间的虚拟连接。
  5. Rounting Key:路由关键字,Exchange根据这个关键字进行消息投递
  6. Virtual host: 虚拟主机。他是对Broker的虚拟划分。
  7. Connection:连接,代表生成者、消费者、Broker之间进行通信的物理网络
  8. Channel:消息通道,用于连接生成者和消费者的逻辑结构。
  9. Producer:消息生产者,制造消息并发送消息的程序。
  10. Consumer:消息消费者,接收消息并处理消息的地方

简单使用

  1. 添加相关依赖
1
2
3
4
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  1. 编写相关的配置
1
2
3
4
5
6
7
8
spring:
application:
name: rabbitmq-hello
rabbitmq:
host: localhost
port: 5672
username: springcloud
password: 123456
  1. 编辑消息生产者类
1
2
3
4
5
6
7
8
9
10
11
@Component
public class Sender {
@Autowired
private AmqpTemplate amqpTemplate;

public void send(){
String context="hello"+new Date();
System.out.println("sender:"+context);
this.amqpTemplate.convertAndSend("hello",context);
}
}
  1. 编辑消息消费类
    实现对hello队列的消费
1
2
3
4
5
6
7
8
9
@Component
@RabbitListener(queues = "hello")
public class Receiver {

@RabbitHandler
public void process(String hello){
System.out.println("Receiver:"+hello);
}
}
  1. 创建配置类文件
1
2
3
4
5
6
7
8
9
@Configuration
public class rabbitConfig {

@Bean
public Queue helloQueue(){
return new Queue("hello");
}
}

KmRpvR.png

整合spring cloud bus

以之前的config-clent-eureka拓展

  1. 添加spring-cloud-starter-bus-amqp依赖
1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
  1. 在配置文件中添加RabbitMQ相关的配置信息
1
2
3
4
5
rabbitmq:
host: localhost
port: 5672
username: springcloud
password: 123456

测试:
首先访问两个config-client-eureka的/from请求,会返回当前仓库中的配置文件的信息,,接着修改配置文件,访问其中一个项目的/bus/refresh,所有的项目的属性都会被刷新
Km2z8J.png