spring cloud之消息驱动stream
为什么要引入stream?
MQ主要有activeMQ,rabbitMQ,RocketMQ,kafka,而stream让我们不在关注MQ的细节,只要一种适配绑定的方式就可以进行通信
使用
新建模块(消息生产者)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
配置文件
server:
port: 8801
spring:
application:
name: cloud-stream-rabbitmq-provider8801
cloud:
stream:
binders: #在此处配置要绑定mq的服务信息
defaultRabbit: #表示定义的名称,用于binders的整合
type: rabbit
environment: #设置mq相关的环境配置
spring:
rabbitmq:
host: 139.9.206.233
port: 5672
username: guest
password: guest
bindings: #服务的整合处理
output: #这个名字是一个通道的名字
destination: studyExchange #表示使用的exchange定义
content-type: application/json #设置消息类型,本次为json,文本则设为“text/plain”
binder: defaultRabbit #设置要绑定消息服务的具体设置
eureka:
instance:
lease-renewal-interval-in-seconds: 2 #设置心跳时间的间隔(默认30秒)
lease-expiration-duration-in-seconds: 5 #如果现在超过了5秒的时间间隔(默认90秒)
instance-id: send-8801.com #在信息列表显示的主机名称
prefer-ip-address: true #访问的路径变成IP地址
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
代码
controller代码
@RestController
public class SendMessageController {
@Resource
private ImessageProvider imessageProvider;
@GetMapping("/sendMessage")
private String sendMessage(){
return imessageProvider.send();
}
}
service层
public interface ImessageProvider {
public String send();
}
impl实现层
@EnableBinding(Source.class) //定义消息的推送管理
@Slf4j
public class ImessageProviderImpl implements ImessageProvider {
@Resource
private MessageChannel output;
@Override
public String send() {
String serial = UUID.randomUUID().toString();
output.send(MessageBuilder.withPayload(serial).build());
log.info("********************serial:"+serial);
return null;
}
}
创建模块(消费者1)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
配置文件
server:
port: 8802
spring:
application:
name: cloud-stream-rabbitmq-consumer8802
cloud:
stream:
binders: #在此处配置要绑定mq的服务信息
defaultRabbit: #表示定义的名称,用于binders的整合
type: rabbit
environment: #设置mq相关的环境配置
spring:
rabbitmq:
host: 139.9.206.233
port: 5672
username: guest
password: guest
bindings: #服务的整合处理
input: #这个名字是一个通道的名字
destination: studyExchange #表示使用的exchange定义
content-type: application/json #设置消息类型,本次为json,文本则设为“text/plain”
binder: defaultRabbit #设置要绑定消息服务的具体设置
eureka:
instance:
lease-renewal-interval-in-seconds: 2 #设置心跳时间的间隔(默认30秒)
lease-expiration-duration-in-seconds: 5 #如果现在超过了5秒的时间间隔(默认90秒)
instance-id: send-8802.com #在信息列表显示的主机名称
prefer-ip-address: true #访问的路径变成IP地址
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
业务代码@Component
@EnableBinding(Sink.class)
public class ReceveMessageLinstenController {
@Value("${server.port}")
private String serverPort;
@StreamListener(Sink.INPUT)
public void input(Message<String> message){
System.out.println("===消费者1号接收的消息是:"+message.getPayload()+"\t"+"serverPort:"+serverPort);
}
创建另一端口号的消费者2模块
测试
生产者发送消息
消费者1和消费者2都进行了消费
此处明显进行了重复消费
解决:在配置文件中给消费者分组即添加group: atguiguA
如何进行持久化
当消费者端宕机了,生产者端在不停的发送消息,这是消费者端重启之后造成消息丢失
解决,加group: atguiguA
}