本篇的代码使用的前面两篇文章《RabbitMQ与Spring整合之消息生产方》和《RabbitMQ与Spring整合之消息消费方》的代码,这两篇文件里配置文件的名称不正确,不可直接运行。
一 自动确认机制
在服务消费者rabbitmq.xml 做修改:
- <!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象 -->
- <rabbit:listener-container acknowledge="auto"
- connection-factory="connectionFactory">
- <rabbit:listener queues="spring_queue_test_01" ref="consumerService" />
- </rabbit:listener-container>
添加了配置 acknowledge="auto",这里来配置mq的确认机制,auto 自动确认,这也是默认缺省的配置。
特点:消费者挂掉,待ack的消息回归到队列中。消费者抛出异常,消息会不断的被重发,直到处理成功。不会丢失消息,即便服务挂掉,没有处理完成的消息会重回队列,但是异常会让消息不断重试。
ConsumerService.java
- package cn.mn.app;
- import org.springframework.amqp.core.Message;
- import org.springframework.amqp.core.MessageListener;
- public class ConsumerService implements MessageListener{
-
- public void onMessage(Message msg) {
- Object obj= null;
- System.out.println( "msg-------->:"+new String(msg.getBody()));
- try {
- Thread.sleep( 10000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println( "休眠结束,5秒后异常-----------------");
- try {
- Thread.sleep( 5000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(obj.toString());
- }
-
- }
可以看到同一条消息不断在控制台打印出来,不断的抛出空指针。在MQ管理界面上看到消息始终存在。
二 手动确认
-
- <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/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/rabbit
- http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd">
- <!--配置connection-factory,指定连接rabbit server参数 -->
- <rabbit:connection-factory id="connectionFactory"
- host="127.0.0.1" />
-
- <!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->
- <rabbit:admin connection-factory="connectionFactory" />
-
- <!--定义queue,如果mq服务器中没,服务器会自动创建 -->
- <rabbit:queue name="spring_queue_test_01" durable="true"
- auto-delete="false" exclusive="false" />
-
- <!-- 定义direct exchange,绑定,如果服务器中没有会自动创建 -->
- <rabbit:direct-exchange name="spring_exchange_test_01"
- durable="true" auto-delete="false">
- <rabbit:bindings>
- <rabbit:binding queue="spring_queue_test_01" key="spring_queue_test_01_key"></rabbit:binding>
- </rabbit:bindings>
- </rabbit:direct-exchange>
-
- <!-- 消息接收者 -->
- <bean id="consumerService" class="cn.mn.app.ConsumerService"></bean>
- <bean id="cnsumerServiceManu" class="cn.mn.app.ConsumerServiceManu"></bean>
-
-
- <!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象 -->
- <rabbit:listener-container acknowledge="manual"
- connection-factory="connectionFactory">
- <rabbit:listener queues="spring_queue_test_01" ref="cnsumerServiceManu" />
- </rabbit:listener-container>
-
- </beans>
ConsumerServiceManu.java
- package cn.mn.app;
-
- import java.io.IOException;
-
- import org.springframework.amqp.core.Message;
- import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
-
- import com.rabbitmq.client.Channel;
-
- public class ConsumerServiceManu implements ChannelAwareMessageListener {
-
- public void onMessage(Message message, Channel channel) throws IOException {
- System.out.println( "consumer--:" + message.getMessageProperties()
- + ":" + new String(message.getBody()));
- //确认
- channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
- }
- }
三 不适用确认
- <rabbit:listener-container acknowledge="none"
- connection-factory="connectionFactory">
- <rabbit:listener queues="spring_queue_test_01" ref="consumerService" />
- </rabbit:listener-container>
特点:acknowledge="none" 不使用确认机制,只要消息发送完成会立即在队列移除,无论客户端异常还是断开,只要发送完就移除,不会重发。
https://blog.csdn.net/liangwenmail/article/details/80542619