JavaEE:SpringCloud-使用Stream向RabbitMQ发送/接收消息

一、使用Stream向RabbitMQ发送/接收消息:

1.导入stream和rabbitmq依赖包:

<dependencies>
    <!-- 导入Actuator依赖包 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
</dependencies>

2.application.yml中配置stream和rabbitmq:

(1)配置rmq服务器连接信息:

spring:
  application:
    name: stream-service
  rabbitmq: #配置rabbitmq服务器连接信息
    host: 192.168.233.147
    port: 5672
    username: root
    password: root
  ...
server:
  port: 10004
management: #开启actuator-endpoint
  security:
    enabled: false  #关闭security
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: always

(2)配置stream发送/接收普通消息/分组消息/延迟消息:

spring:
  ...
  cloud:
    stream:
      instance-count: 2   #(2)参与消息分区的接收者实例总数为2个(消息分区配置)
      instance-index: 0   #(2)接收者实例初始索引为0(消息分区配置)
      rabbit:  #(3)延迟消息配置(RabbitMQ要安装延迟队列插件)
        bindings:
          delayed-sender:
            producer:
              delayedExchange: true  #开启消息延迟
      bindings:  #将发送者与接收者共同绑定到mall_exchange(exchange名称)
        #############################(1)普通消息配置 start#############################
        receiver:  #消息接收配置,此处名称为Topic.receiver
          destination: topic_exchange   #exchange名称
        sender:  #消息发送配置,此处名称为Topic.sender
          destination: topic_exchange   #exchange名称
        #############################(1)普通消息配置 end#############################
        #############################(2)分组消息配置 start#############################
        group-receiver:  #分区消息接收配置,此处名称为GroupTopic.group-receiver
          destination: group_exchange   #exchange名称
          group: group1   #设置分组名
          consumer:
            partitioned: true  #打开消息分区功能
        group-sender:  #分区消息发送配置,此处名称为GroupTopic.group-sender
          destination: group_exchange   #exchange名称
          producer:
            partitionCount: 2   #2个分区
            partitionKeyExpression: headers['instanceIndex']  #规定指定实例索引的接收者才能收到消息,发送时通过MessageBuilder.setHeader(key名, 索引值)设置接收者索引
        #############################(2)分组消息配置 end#############################
        #############################(3)延迟消息配置 start#############################
        delayed-receiver:  #分区消息接收配置,此处名称为DelayedTopic.delayed-receiver
          destination: delayed_exchange   #exchange名称
        delayed-sender:  #分区消息发送配置,此处名称为DelayedTopic.delayed-sender
          destination: delayed_exchange   #exchange名称
        #############################(3)延迟消息配置 end#############################

3.创建自定义普通/分组/延迟消息Topic:

(1)普通消息Topic:

public interface Topic { //自定义普通消息Topic
    String INPUT = "receiver";  //自定义名
    String OUTPUT = "sender";  //自定义名
    @Input(INPUT)
    SubscribableChannel input();
    @Output(OUTPUT)
    MessageChannel output();
}

(2)分组消息Topic:

public interface GroupTopic { //分组消息Topic
    String INPUT = "group-receiver";  //自定义名
    String OUTPUT = "group-sender";  //自定义名
    @Input(INPUT)
    SubscribableChannel input();
    @Output(OUTPUT)
    MessageChannel output();
}

(3)延迟消息Topic:

public interface DelayedTopic { //延迟消息Topic
    String INPUT = "delayed-receiver";  //自定义名
    String OUTPUT = "delayed-sender";  //自定义名
    @Input(INPUT)
    SubscribableChannel input();
    @Output(OUTPUT)
    MessageChannel output();
}

4.创建消息接收类接收普通/分组/延迟消息:

@EnableBinding(value = {Sink.class, Topic.class, GroupTopic.class, DelayedTopic.class})  //接收rmq消息
public class MsgReceive {
    @StreamListener(Sink.INPUT)   //接收普通消息,Sink.INPUT为系统自带
    public void onMsg0(String msg) {
        //此处接受到普通消息
    }
    @StreamListener(Topic.INPUT)   //接收普通消息,Topic.INPUT为自定义
    public void onMsg(String msg) {
        //此处接受到普通消息
    }
    @StreamListener(GroupTopic.INPUT)   //接收分组消息,GroupTopic.INPUT为自定义
    public void onGroupMsg(String msg) {
//  public void onGroupMsg(String msg, @Header("version") String version) {  //接收带版本号的分组消息,可以根据版本号处理不同的逻辑
        //此处接受到分组消息
    }
    @StreamListener(DelayedTopic.INPUT)   //接收延迟消息,DelayedTopic.INPUT为自定义
    public void onDelayedMsg(String msg) {
        //此处接受到延迟消息
    }
}

5.测试发送消息:

@Controller
public class MsgSendController {
    @Autowired
    private Topic topic; //消息发送
    @Autowired
    private GroupTopic groupTopic; //分组消息发送
    @Autowired
    private DelayedTopic delayedTopic; //延迟消息发送
    @RequestMapping("/sendMsg")
    @ResponseBody
    public String sendMsg(String msg) {
        topic.output().send(MessageBuilder.withPayload(msg).build());  //发送消息到rmq
        return "发送普通消息";
    }
    @RequestMapping("/sendGroupMsg")
    @ResponseBody
    public String sendGroupMsg(String instanceIndex, String msg) {
        groupTopic.output().send(MessageBuilder.withPayload(msg).setHeader("instanceIndex", instanceIndex).build());
        //groupTopic.output().send(MessageBuilder.withPayload(msg).setHeader("version", "1.0.0").build());   //发送带版本号的消息
        return "发送分组消息";
    }
    @RequestMapping("/sendDelayedMsg")
    @ResponseBody
    public String sendDelayedMsg(String msg) {
        delayedTopic.output().send(MessageBuilder.withPayload(msg).setHeader("x-delay", 5000).build()); //通过x-delay头字段控制延迟,此处5毫秒
        return "发送延迟消息";
    }
}

二、其他配置:

1.配置异常重试(application.yml中):

(1)单主机上异常重试:

spring:
  cloud:
    stream:
      bindings:
        receiver:  #receiver为Topic.receiver
          consumer:
            maxAttempts: 3  #单机上异常重试:发生异常时,消息重复发送的最大次数

(2)多主机上异常重试:

spring:
  rabbitmq:
    listener:
      direct:
        default-requeue-rejected: true   #开启多主机上异常重试(方式1):全局异常重试
  cloud:
    stream:
      bindings:
        receiver:  #receiver为Topic.receiver
          consumer:
            maxAttempts: 1  #多主机上异常重试时,强制单机异常重试为1次(也就是不重试)
      rabbit:
        bindings:
          receiver:  #receiver为Topic.receiver
            consumer:
              requeueRejected: true  #开启多主机上异常重试(方式2):仅对receiver异常重试

2.配置死信队列(application.yml中):

spring:
  cloud:
    stream:
      bindings:
        receiver:  #receiver为Topic.receiver
          consumer:
            maxAttempts: 3  #异常重试次数
      rabbit:
        bindings:
          receiver:  #receiver为Topic.receiver
            consumer:
              autoBindDlq: true      #开启死信队列,默认队列名为xxx.dlq

3.异常降级处理:

@EnableBinding(value = {...})
public class MsgReceive {
    ...
    @ServiceActivator(inputChannel = "group_exchange.group1.errors")  //配置异常降级回调方法(异常重试超过最大次数后触发),inputChannel命名规则:destination.group.errors
    public void callback(Message<?> message) { //message为org.springframework.messaging.Message
        //处理异常降级逻辑
    }
}


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值