RabbitMq消费信息,对数据处理和编码设置

本文介绍了RabbitMQ的消息消费,包括普通消费和手动确认消费两种方式。普通消费中,消费者只需实现MessageListener接口的onMessage方法。而在手动确认消费模式下,消费者可自定义异常处理,如消息重入队列或持久化,通过实现ChannelAwareMessageListener的onMessage方法来实现。

RabbitMq消费信息,对数据处理和编码设置

将消息放到MQ的队列,必然要对消息进行处理,不然使用MQ就显得没有什么意义了。

普通消费

单纯的消费消息只需写一个实现类实现MessageListeneronMessage方法即可,如

public class RabbitmqService implements MessageListener {

    private Logger logger = LoggerFactory.getLogger(RabbitmqService.class);
    
    @Autowired
    private UserService userService;

    @Autowired
    private MsgInfoService msgInfoService;

    public void onMessage(Message message) {
      
        try {
        	//将放入队列的消息已UTF-8的格式转为JSON字符串(前提是放入队列是也是JSON字符串,中文存在乱码)
            String  msg  = new String(message.getBody(),"utf-8");
            logger.info("消息:{}",JSON.toJSONString(msg));
            //将JSON字符串转换为自己想要处理的对象
            User user= JSON.parseObject(msg, User .class);
            //处理逻辑
            User userDto = userService.save(user);
            logger.info("调用结果返回:{}",JSON.toJSONString(userDto ));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

手动确认消费

手动确认即在消息消费出现异常是可选择自己的处理方式,入消息重入队列,消息的持久化等。手动确认 消息只需实现ChannelAwareMessageListeneronMessage方法

public class AckConsumer implements ChannelAwareMessageListener {
    private Logger logger = LoggerFactory.getLogger(AckConsumer.class);
    @Autowired
    private UserService userService;

    @Autowired
    private MsgInfoService msgInfoService;

    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        logger.info("接受到消息:{}",message);
        channel.basicQos(1);//每次处理一条消息
        String state = null;
        try{
            String  msg = new String(message.getBody(),"utf-8");
            logger.info("处理的数据:{}",JSON.toJSONString(msg));
            User user= JSON.parseObject(msg, User.class);
            User userDto = userService.save(user);
            String returnCode = userDto .getReturnCode();
            logger.info("调用结果返回:{}",JSON.toJSONString(userDto ));
            if(returnCode.equals("1000")){
                state = "10A";
                //第一个参数Delivery Tag 用来标识信道中投递的消息,RabbitMQ 推送消息给 Consumer 时,
                // 会附带一个 Delivery Tag,以便 Consumer可以在消息确认时告诉 RabbitMQ 到底是哪条消息被确认了.
                //第二个参数 multiple 取值为 false 时,表示通知 RabbitMQ 当前消息被确认;
                // 如果为 true,则额外将比第一个参数指定的 delivery tag 小的消息一并确认。
                channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);//确认消息已消费
            }else{
                state = "10I";
                //第一个参数,消息的标识
                //第二个参数是否批量处理消息,true:将一次性拒绝所有小于deliveryTag的消息。
                //第三个参数,消息是否重入队列,false将消息存队列删除。true:会重复消费该消息直到消息被确认消费
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);//拒绝消费消息
            }
        }catch (Exception e){
            state = "10I";
            e.printStackTrace();
            channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
        }finally {
            //消息持久化
            msgInfoService.saveMsg(message, state);
        }
    }
}
### RabbitMQ Socket 的数据传输效率对比分析 #### 1. 基础概念与适用场景 RabbitMQ 是一种基于 AMQP 协议的消息中间件,主要用于异步任务处理、事件驱动架构系统间的数据同步[^1]。其核心功能在于提供可靠的队列管理消息分发能力。相比之下,Socket 是一种底层网络通信接口,允许开发者直接控制 TCP/UDP 连接的建立数据传输。 在实际应用中,如果需要简单的点对点实时通信,Socket 可能更高效;但如果涉及复杂的消息路由、持久化存储或负载均衡,则 RabbitMQ 更加合适。 --- #### 2. 数据传输效率的影响因素 ##### (a) 消息开销 RabbitMQ 在消息传递过程中引入了一些额外的元数据(如头部信息、确认机制等),这增加了每条消息的整体大小。而 Socket 则几乎没有这种开销,因为它只负责原始字节流的传输[^3]。 ##### (b) 确认机制 为了保证消息的可靠性,RabbitMQ 提供了多种确认机制(如生产者确认消费者确认)。这些机制虽然提高了系统的稳定性,但也可能导致延迟增加[^2]。相反,Socket 不具备内置的确认机制,因此速度更快,但在某些情况下可能会丢失数据。 ##### (c) 并发处理能力 RabbitMQ 支持多线程并发处理,在合理配置下能够显著提升吞吐量。例如,推荐的最佳实践是设置三到五个生产者线程两倍于生产者的消费者线程数以优化性能。然而,由于 RabbitMQ 需要维护内部状态(如队列索引日志文件),它的扩展性可能受到硬件资源的限制。 另一方面,Socket 的并发性能取决于操作系统对套接字的支持程度以及应用程序的设计方式。现代框架(如 Netty 或 gRPC)可以在单机上轻松管理数千甚至百万级连接。 ##### (d) 流控与背压 当消息发送速率远高于消费速率时,RabbitMQ 会启动流量控制机制以防止内存耗尽。尽管这一特性有助于保护系统免受过载影响,但它同样会造成性能下降[^4]。而在 Socket 层面,开发者需自行实现类似的背压策略,否则容易因缓冲区溢出而导致崩溃。 --- #### 3. 实际测试结果 以下是两种技术在不同条件下的表现概览: | 特性 | RabbitMQ | Socket | |---------------------|-----------------------------------------|-----------------------------------------| | **延时** | 较高(约几毫秒至几十毫秒) | 极低(微秒级别) | | **吞吐量** | 中等到较高 | 高 | | **可靠性** | 非常高 | 依赖具体实现 | | **易用性** | 易于集成分布式环境 | 要求更多手动编码 | | **开发成本** | 较高 | 较低 | 需要注意的是,上述结论并非绝对固定——特定业务需求会对最终效果产生重要影响。 --- #### 4. 使用建议 - 如果项目强调高性能且容忍一定程度不可靠性(比如游戏中的玩家位置更新),应优先选用 Socket。 - 对于那些追求稳定性灵活性的应用场合(诸如订单管理系统或支付平台),则更适合采用 RabbitMQ 来简化开发流程并增强容错能力。 ```python import pika connection = pika.BlockingConnection(pika.ConnectionParameters('localhost')) channel = connection.channel() channel.queue_declare(queue='hello') channel.basic_publish(exchange='', routing_key='hello', body='Hello World!') print(" [x] Sent 'Hello World!'") connection.close() # 上述代码展示了如何利用 Python 向 RabbitMQ 发送一条简单消息 [^1]. ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值