一、创建一个springboot项目
<!--stream 实现mq-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
- 配置yml文件
一般会配置group: logs分组,是为了持久化队列防止消息丢失以及集群重复消费问题;
路由键是为了指定logs-exchange 交换机通过路由键log.# 去绑定队列 logs-exchange.logs
spring:
application:
name: mq
cloud:
stream:
binders: # 在此处配置要绑定的rabbitmq的服务信息;
defaultRabbit: # 表示定义的名称,用于于binding整合 可以随便写什么
type: rabbit # 底层消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
host: 10.10.0.20
port: 5672
username: guest
password: guest
bindings: # 服务的整合处理 消费者配置,在此绑定
# 消息生产者配置(哪个提供者服务需要就配置)
myoutput: # 这个名字是一个通道的名称 在代码中会用到(名字可以随便取 我这个服务是消息生产者,就写的output)
destination: logs-exchange # 表示要使用的Exchange交换机名称定义
content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
binder: defaultRabbit # 设置要绑定的消息服务的具体设置binder
# group: logs #分组只需要在消费者端配置,不需要在生产者配置
# 消息消费者配置(哪个消费者服务需要就配置)
myinput: # 这个名字是一个通道的名称 在代码中会用到(名字可以随便取 我这个服务是消息消费者,就写的input)
destination: logs-exchange # 表示要使用的Exchange交换机名称定义
content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
binder: defaultRabbit # 设置要绑定的消息服务的具体设置binder
group: logs # 指定分组,持久化队列防止消息丢失以及集群重复消费问题
rabbit:
bindings:
myinput: # 这个同上面的消费者通道名称一致 会将对应的交换机和分组确定后的队列 通过路由键绑定
consumer:
# 路由键绑定的自定义规则 (哪个消费者服务需要就配置)
bindingRoutingkey: log.#
二、代码实现
- 模仿Message包提供的Sink、Source类写自定义的信道接口
package com.aliuxy.stream.config;
import org.springframework.cloud.stream.annotation.Input;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.SubscribableChannel;
/**
*@author liuxingying
*@description 自定义输出输入信道 模仿Source Sink类
*@since 2021/8/10
*/
public interface MessageSendChannel {
// 对应配置yml里的myoutput 消息发送方的信道
String MYOUTPUT = "myoutput";
// 对应配置yml里的myinput 消息接受方的信道
String MYINPUT = "myinput";
@Output(MessageSendChannel.MYOUTPUT)
MessageChannel output();
@Input(MessageSendChannel.MYINPUT)
SubscribableChannel input();
}
package com.aliuxy.stream.message;
import com.aliuxy.stream.config.MessageSendChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
/**
*@author liuxingying
*@description 消息发送者
*@since 2021/8/9
*/
@EnableBinding(MessageSendChannel.class)
@Slf4j
public class MessageSender {
// 消息的发送信道 在MessageSendChannel类的@Output("output")注解后会自动注入到spring中
@Autowired
private MessageSendChannel messageSendChannel;
public void publish(Object msg){
// msg可以是对象也可以是字符串,withPayload() api都会转成json
boolean flag = messageSendChannel.output().send(MessageBuilder.withPayload(msg).build());
log.info("消息:{},发送结果:{}",msg,flag);
}
}
package com.aliuxy.stream.service;
import com.aliuxy.stream.message.MessageSender;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*@author liuxingying
*@description 业务处理
*@since 2021/8/9
*/
@Service
@Slf4j
public class MessageService {
@Autowired
private MessageSender messageSender;
public void sendMessage(String msg){
log.info("---------测试开始-----------");
messageSender.publish(msg);
}
}
package com.aliuxy.stream.message;
import com.aliuxy.stream.config.MessageSendChannel;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.messaging.Message;
/**
*@author liuxingying
*@description 消息消费者
*@since 2021/8/9
*/
@EnableBinding(MessageSendChannel.class)
public class MessageConsumer {
@StreamListener(MessageSendChannel.MYINPUT)
public void consumer(Message<?> message){
System.out.println("---消息接收:----"+ message.getPayload());
}
}
三、测试
package com.aliuxy.stream;
import com.aliuxy.stream.message.MessageSender;
import com.aliuxy.stream.service.MessageService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class StreamMqApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(StreamMqApplication.class, args);
MessageService sender = context.getBean(MessageService.class);
sender.sendMessage("测试mq");
}
}