在进行微服务开发时,我们使用Spring Cloud的消息总线组件来使用消息通讯是非常方便的。
消息服务根据消息的消费模式不同,可以分为点对点和广播型(发布/订阅)消息两种模式,开发时可以根据业务需求选择不同的模式使用。
点对点模式适用于消息生产者和消费者一一对应的方式,通讯方式如下图所示:
即由消息生产者发出的消息只能由一个消息消费者消费。
广播型消息可以由多个消息消费者同时消费,这是一种一对多的关系,通讯方式如下图所示:
上面两种消息模式的消息队列,都可以配置成持久化的消息队列,并且消息被消费时具有自动确认的功能,当一个队列被同一服务的多个实例所监听时,消息队列中的消息,将被多个实例进行均分(或争抢)消费,但不存在重复消费。
在使用Spring Cloud的开发环境中,需要使用消息总线时,引入下面依赖引用:
<!--消息总线-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
然后在应用的配置文件application.yml中使用如下配置连接RabbitMQ服务器(这里假设RabbitMQ安装在本地上):
spring:
rabbitmq:
addresses: amqp://localhost:5672
username: guest
password: guest
对于点对点的消息,开发是很简单的。
首先,创建一个消息队列,即使用配置方式在程序启动时初始化一个消息队列:
@Configuration
public class RabbitConfig {
@Bean
public Queue initQueue(){
return new Queue(“queusname”);
}
}
点对点消息发送:
@Service
public class PtoPSender {
@Autowired
private AmqpTemplate amqpTemplate;
public void send(Map<String, Object> msg){
amqpTemplate.convertAndSend(“queusname”, msg);
}
}
点对点消息接收:
@Component
public class Testreceiver {
@RabbitListener(queues = "queusname")
public synchronized void process(Map<String, Object> msg){
System.out.println("接收到的消息:"+msg.toString());
//消息处理
}
}
其中,“queusname”为消息队列名称。在实际应用中,可以将消息队列名称放在配置文件中进行设置。
对于广播型的消息模式,会稍微复杂一点。但是如果我们使用Spring Cloud组件中定制的通道来设计,也会简单一些。
对于消息发布,即使用Source设置的通道:
@Service
@EnableBinding(Source.class)
public class PushSend {
@Autowired
@Output(Source.OUTPUT)
private MessageChannel channel;
public void send(Map<String, Object> msg){
channel.send(MessageBuilder.withPayload(msg).build());
}
}
同时在配置文件中配置发布通道:
# 广播型消息发布通道配置
spring:
cloud:
stream:
bindings:
output:
destination: CommonMessages
content-type: application/json
注意:上面配置的通道为“output”。
对于订阅消息,可以使用Sink定制的通道来接收:
@EnableBinding(Sink.class)
public class TestSubscribe {
@StreamListener(Sink.INPUT)
public synchronized void listener(String msg) {
Map<String, Object> receiver = new Gson().fromJson(msg, new TypeToken<Map<String,Object>>(){}.getType());
System.out.println("recerver:"+receiver.toString());
//消息处理
}
}
同时在配置文件中配置接收消息的订阅通道及队列:
# 广播型消息订阅队列配置
spring:
cloud:
stream:
bindings:
input:
destination: CommonMessages
content-type: application/json
group: Group1
consumer:
durableSubscription: true
注意:上面配置的通道为“input”。
这样就相当于配置了一个持久化队列:”CommonMessages.Group1”。对于不同的订阅者,只要按照上面配置更改group的配置即可,例如:“Group2”。这样就实现了一条消息能够被多个订阅者消费的功能。