Spring-RabbitMq整合

功能目标

1.Spring整合RabbitMq 实现 helloworld 工作模式
2.实现Work Queue 工作模式
3.实现Publish 工作模式
3.实现Routing 工作模式
4.实现Topic 工作模式
5.实现生产者Confirm & Return 确保消息发送成功
6.实现消费者 ACK,确保消费成功
7.实现延迟消息队列

整合流程

1.打开SpringAMQP 网站,这里有maven 引入,xml基本配置文件;SpringAMQP
2.新建项目引入jar包,复制相关xml配置文件
3.WorkerQueue 整合代码
3.1 生产者

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/rabbit
           https://www.springframework.org/schema/rabbit/spring-rabbit.xsd
           http://www.springframework.org/schema/beans
           https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 定义rabbitmq connectionFactory -->
    <rabbit:connection-factory id="connectionFactory" host=""
                                port="5672" virtual-host="jtfu-firstmq" username="jtfu"
                                password="jtfu123" publisher-returns="true" confirm-type="CORRELATED"/>
    <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>
    <!--定义管理交换机、队列-->
    <rabbit:admin connection-factory="connectionFactory"/>
    <!-- 定义队列-->
    <rabbit:queue id="spring_queue_helloWorld" name="spring_queue_helloWorld"/>

</beans>
public class ProducerApp {
    public static void main(String[] args) throws InterruptedException {
        ApplicationContext context =
                new GenericXmlApplicationContext("classpath:/rabbit-context.xml");
        AmqpTemplate template = context.getBean(AmqpTemplate.class);
        for (int i=0;i<10;i++){
            template.convertAndSend("spring_queue_helloWorld", "helloWorld");
        }
    }
}

3.2 消费者

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/rabbit
           https://www.springframework.org/schema/rabbit/spring-rabbit.xsd
           http://www.springframework.org/schema/beans
           https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 定义rabbitmq connectionFactory -->
    <rabbit:connection-factory id="connectionFactory" host=""
                                port="5672" virtual-host="jtfu-firstmq" username="jtfu"
                                password="jtfu123" publisher-returns="true" confirm-type="CORRELATED"/>
    <!--定义rabbitTemplate对象操作可以在代码中方便发送消息-->
    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>
    <!--定义管理交换机、队列-->
    <rabbit:admin connection-factory="connectionFactory"/>
<!--    Spring声明一个bean-->
    <bean id="workerListener" class="com.jtfu.mq.study.listener.WorkerListener"></bean>
<!--声明一个队列-->
    <rabbit:queue id="spring_queue_helloWorld" name="spring_queue_helloWorld"/>
<!--添加Listener,监听队列消息  acknowledge:手动签收消息,prefetch:每次拉取一条消息 -->
    <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="1">
        <rabbit:listener ref="workerListener" queues="spring_queue_helloWorld"></rabbit:listener>
    </rabbit:listener-container>
</beans>
public class WorkerListener implements ChannelAwareMessageListener {
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        MessageProperties messageProperties = message.getMessageProperties();
        System.out.println(new String(message.getBody()));
        //手动签收消息
        channel.basicAck(messageProperties.getDeliveryTag(),false);
    }

    @Override
    public void onMessage(Message message) {

    }
}

4.实现Publish 工作模式
交换机绑定多个队列,多个队列可以同时监听消息并消费;

生产者

<rabbit:fanout-exchange name="spring_fanout_exchange">
        <rabbit:bindings>
            <rabbit:binding queue="spring_queue_helloWorld"></rabbit:binding>
            <rabbit:binding queue="spring_queue_publish"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:fanout-exchange>

消费者

    <rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="1">
        <rabbit:listener ref="workerListener" queues="spring_queue_helloWorld"></rabbit:listener>
        <rabbit:listener ref="publishListener" queues="spring_queue_publish"></rabbit:listener>
    </rabbit:listener-container>

5.实现Routing 工作模式
交换机绑定多个队列,并指定完整的routing key

生产者

    <rabbit:direct-exchange name="spring-direct_exchange">
        <rabbit:bindings>
            <rabbit:binding queue="spring_queue_direct_kawasaki" key="kawasaki"></rabbit:binding>
            <rabbit:binding queue="spring_queue_direct_honda" key="honda"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>

6.实现Topic 工作模式

<rabbit:topic-exchange name="spring_topic_exchange">
        <rabbit:bindings>
            <rabbit:binding pattern="moto.#" queue="spring_queue_direct_honda"></rabbit:binding>
            <rabbit:binding pattern="moto.*" queue="spring_queue_direct_kawasaki"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:topic-exchange>

7.实现生产者Confirm & Return 确保消息发送成功,实现消费者 ACK,确保消费成功
7.1 生产者确保消息发送成功;首先配置文件中开启发送确认模式 publisher-confirms=“true” publisher-returns="true"

 <rabbit:connection-factory id="connectionFactory" host="8.140.112.183"
                                port="5672" virtual-host="jtfu-firstmq" username="jtfu"
                                password="jtfu123" publisher-confirms="true" publisher-returns="true"/>
blic class ProducerApp {
    public static void main(String[] args) throws InterruptedException {
        ApplicationContext context =
                new GenericXmlApplicationContext("classpath:/rabbit-context.xml");
        RabbitTemplate template = context.getBean(RabbitTemplate.class);
        Map map=new HashMap();
        map.put("moto.kawasaki","Z900");
        map.put("moto.honda.Cbr650","CBR650");
        map.put("moto.honda.Cbr650.ssss","CBR650");
        map.put("honda.Cbr650.ssss","CBR650");
        Set<Map.Entry> set = map.entrySet();
        template.setConfirmCallback(new RabbitTemplate.ConfirmCallback() {
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String s) {
                System.out.println("进入confirm。。。。。");
                if(ack){
                    //消息进入交换机
                    System.out.println("消息进入交换机。。。。");
                }else {
                    System.out.println("消息未找到交换机。。。。");
                }
            }
        });
        //设置交换机处理失败消息的模式   为true的时候,消息达到不了 队列时,会将消息重新返回给生产者
        template.setMandatory(true);
        template.setReturnCallback(new RabbitTemplate.ReturnCallback() {
            @Override
            public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                System.out.println("进入returns。。。未找到相应routing,");
            }
        });
        for (Map.Entry entry : set) {
            template.convertAndSend("spring-direct_exchange","====sss",entry.getValue().toString().getBytes(StandardCharsets.UTF_8));
        }
    }

8.实现延迟消息队列 ,RabbitMq 不支持延迟队列,需要使用TTL 与 死信队列配合达到延迟队列的目的;
8.1 消息在以下情况会进入死信状态
1. 消息到达ttl设置的时间未被消费掉
2. 消息队列达到最大值,新来的消息成为死信
3. 消息发送给消费端后,消费端拒绝签收并丢弃的消息;
在这里插入图片描述

目的:实现10秒钟的延迟队列;
1.创建普通交换机 与 普通队列;
2.创建死信交换机 与 死信队列
3.配置普通队列参数,设置超时时间,死信队列名称,发送给死信队列的routing key

    <rabbit:queue id="orderQueue" name="orderQueue">
        <rabbit:queue-arguments>
<!--            设置队列的过期时间,相关参数可以从rabbitMqServer获取-->
            <entry key="x-message-ttl" value="10000" value-type="java.lang.Integer" ></entry>
<!--            设置队列的最大容量-->
            <entry key="x-max-length" value="10" value-type="java.lang.Integer" ></entry>
<!--            死信队列交换机名-->
            <entry key="x-dead-letter-exchange" value="order_exchange_dead"></entry>
<!--            发送给死信交换机的routing key-->
            <entry key="x-dead-letter-routing-key" value="dlx.order"></entry>
        </rabbit:queue-arguments>
    </rabbit:queue>
    <rabbit:direct-exchange name="order_exchange">
        <rabbit:bindings>
            <rabbit:binding queue="orderQueue" key="order"></rabbit:binding>
        </rabbit:bindings>
    </rabbit:direct-exchange>

消费者监听死信队列,达到延迟的目的

   <rabbit:listener ref="orderDeadListener" queues="orderQueueDead"></rabbit:listener>
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值