使用rabbitMQ后总结

本文详细介绍了RabbitMQ中如何实现队列和消息的持久化,确保即使服务器宕机,消息也不会丢失。同时,讲解了消费者设置,包括启用Qos和ack机制,确保消息正确处理并避免重复消费。此外,还展示了手动ack的重要性,以防止未完成处理的消息阻塞后续消费。

一.数据持久化

1.队列持久化

//队列申明,durable:true队列持久化
channel.queueDeclare(Constant.QUEUE_NAME, true, false, false, null);

2.消息持久化


/**
                 * exchange:名称
                 *
                 * routingKey:路由键,#匹配0个或多个单词,*匹配一个单词,在topic exchange做消息转发用
                 *
                 * mandatory:为true时如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返还给生产者。
                 *            (默认为false)false时出现上述情形broker会直接将消息扔掉
                 *
                 * immediate:为true时如果exchange在将消息route到queue(s)时发现对应的queue上没有消费者,那么这条消息不会放入队列中。
                 *            当与消息routeKey关联的所有queue(一个或多个)都没有消费者时,该消息会通过basic.return方法返还给生产者。
                 *            <P>MessageProperties.PERSISTENT_TEXT_PLAIN</>
                 *
                 * props:需要注意的是BasicProperties.deliveryMode,1:不持久化 2:持久化 这里指的是消息的持久化,
                 *        配合channel(durable=true),queue(durable)可以实现,即使服务器宕机,消息仍然保留
                 *        BasicProperties:
                 *         private String contentType;  // content-type属性用于描述消息体的数据格式 如 JSON = application/json
                 *         private String contentEncoding;
                 *         private Map<String, Object> headers;
                 *         private Integer deliveryMode; // 表示在将消息投递给任何消费者之前,是否希望先将它持久化到磁盘上,1表示非持久化消息,2表示持久化消息。
                 *         private Integer priority; // 用于指定队列中消息的优先级
                 *         private String correlationId;
                 *         private String replyTo;
                 *         private String expiration; // 设置消息的有效期,超过10秒没有被消费者接收后会被自动删除
                 *         private String messageId;
                 *         private Date timestamp;
                 *         private String type;
                 *         private String userId; // 携带一些信息以便消费者应用程序在处理消息之前进行验证
                 *         private String appId; // 携带一些信息以便消费者应用程序在处理消息之前进行验证
                 *         private String clusterId;
                 *
                 * body:要发送的信息
                 */
channel.basicPublish("", Constant.QUEUE_NAME, MessageProperties.PERSISTENT_TEXT_PLAIN, eCriminal.getZfbaCode().getBytes());

二.消费者设置

1.启用Qos和ack机制

//同一时刻服务器只发送1条消息给消费者(能者多劳,消费消息快的,会消费更多的消息)
//当RabbitMQ的队列达到1条Unacked消息时,不会再推送消息给Consumer
//保证在接收端一个消息没有处理完时不会接收另一个消息,即消费者端发送了ack后才会接收下一个消息。
//在这种情况下生产者端会尝试把消息发送给下一个空闲的消费者。
channel.basicQos(1);
//声明队列的消费者O
        Consumer consumer1 = new DefaultConsumer(channel){
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                String message = new String(body, "UTF-8");
                System.out.println("customerA 消费消息:"+message);
                try {
                    dataHandle.consumerDataHandle(message);
                }catch (Exception e){
                    //  业务处理的异常应该捕获 另外保存
                    log.error("customerA 消费消息异常:{}",message);
                }
                //手动返回结果: 一定要放在最后 通过该方法后 就算手动ack 该消息被消费成功;在这之前的异常,都会把当前消费数据返回队列
                // channel.basicQos(1);==> 如果不处理数据 业务异常 数据 会阻塞继续消费
                channel.basicAck(envelope.getDeliveryTag(), false);
            }
        };
//定义的消费者监听队列 autoAck:true自动返回结果,false手动返回
        channel.basicConsume(Constant.QUEUE_NAME, false,consumer1);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值