非spring 工程使用 spring cloud config配置中心
最近在学习使用spring cloud ,自己动手搭建了spring cloud
eureka服务器作为服务的注册和发现中心,然后搭建了spring cloud config server端和client
端,并使用rabbit mq 作为消息总线,来实现Git仓库中的内容修改触发应用程序的属性更新.可参考
http://blog.didispace.com/springcloud7/ 这里.现在来说说我们的应用场景,由于之前的项目都不是与spring cloud 相关的项目,如果也想使用这样的配置该如何做呢?
跟大多数同学一样,我的第一个想法就是定时任务.在我们的工程里,写一个定时任务,定时去调用config server 的接口,获取数据,并保存成文件
这自然也是一个解决的办法,但是有一个问题,如果我们有多台服务器的情况下,定时来取,对config server 端来说 ,也会造成很大的压力.
那么有没有更好的解决方法呢?先看一下这个!
如上图所示,其中包含了Git仓库、Config Server、以及微服务“Service A”的三个实例,这三个实例中都引入了Spring Cloud Bus,所以他们都连接到了RabbitMQ的消息总线上。
当我们将系统启动起来之后,“Service A”的三个实例会请求Config Server以获取配置信息,Config Server根据应用配置的规则从Git仓库中获取配置信息并返回。
当我们在更改了git 仓库中的配置文件信息时,我们只需要调用/bus/refresh (post 方式),就能够完成所有实例的配置文件刷新.这是如何实现的呢?
注意看,Config Server、及三个service A 的实例都引入了Spring Cloud Bus ,所以他们都连接到了RabbitMQ的消息总线上。
所以大胆的猜想在Config Server服务启动的时候,创建了一个topic,其他的 service 都订阅了这个topic ,然后在我们调用bus/refresh 时,所有订阅这个topic的service 都会重新去config server上读取配置文件.
我们去rabbitmq 服务器上验证一下.
名字看起来好像有点关联.
这个就是我们启动的服务.再看一个图.
没错了 ,就是它.
下面的问题就很简单了,只要我们订阅这个topic ,以后调用bus/refresh时,我们去config server 上取一下对应的配置文件,这样不就ok了,哈哈哈.
贴上我的代码.
import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;
//连接rabbit mq 并订阅 springCloudBus topic
public class MQUtil {
private static final String EXCHANGE_NAME = "springCloudBus";
public static void consumer() throws Exception {
// 创建连接和频道
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setUsername("test");
factory.setPassword("test");
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
// 声明转发器
channel.exchangeDeclare(EXCHANGE_NAME, "topic", true);
// 随机生成一个队列
String queueName = channel.queueDeclare().getQueue();
// 接收所有与springCloudBus相关的消息
channel.queueBind(queueName, EXCHANGE_NAME, "#");
QueueingConsumer consumer = new QueueingConsumer(channel);
channel.basicConsume(queueName, true, consumer);
while (true) {
QueueingConsumer.Delivery delivery = consumer.nextDelivery();
String message = new String(delivery.getBody());
String routingKey = delivery.getEnvelope().getRoutingKey();
JSONObject json = JSONObject.parseObject(message);
// 类型
String type = json.getString("type");
// 收到服务端的刷新文件标志
if ("RefreshRemoteApplicationEvent".equals(type)) {
System.out.println("收到刷新的标识了");
}
}
}
public static void main(String[] args) throws Exception {
consumer();
}
}
搞定.具体的处理方法我就不写了.O(∩_∩)O哈哈~.