为什么我不推荐你使用RabbitMQ的消息转换功能

开发 前端
发送消息与订阅消息取消使用amqp提供的消息序列化与反序列化功能,使用String类型,发送消息时手动转化为json字符串再发送,消费消息时手动json反序列化。

[[409095]]

改版:

发送消息与订阅消息取消使用amqp提供的消息序列化与反序列化功能,使用String类型,发送消息时手动转化为json字符串再发送,消费消息时手动json反序列化。

背景:

如果使用自动序列化与反序列化功能,即给Rabbitmq配置Jackson2JsonMessageConverter消息转化器,当我们修改消息Body的java类型名称或者包名时,消费历史消息就会抛出ClassNotFoundException异常。

1、不做兼容上线,但需要:

  • 确保不会有新的消息进入队列;
  • 确保队列中的消息已经消费完。

2、粗暴方式,直接清空队列,丢弃历史消息;

3、做兼容,给旧消息创建一个类名匹配的消息Body类型,添加一个@RabbitHandler方法处理旧消息。

这是因为Rabbitmq为了实现一个队列支持多个方法消费(即@RabbitHandler注解的方法),每个方法消费不同Java类型的消息Body,在消费到消息时,就需要先反序列化出消息Body,才能根据消息Body的类型去匹配一个消费方法消费消息,如DelegatingInvocableHandler#invoke方法源码所示。

  1. // org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler#invoke 
  2. public InvocationResult invoke(Message<?> message, Object... providedArgs) throws Exception {  
  3.    // 获取消息body类型 
  4.    Class<? extends Object> payloadClass = message.getPayload().getClass(); 
  5.    // 匹配的方法 
  6.    InvocableHandlerMethod handler = getHandlerForPayload(payloadClass); 
  7.    // 调用方法消费 
  8.    Object result = handler.invoke(message, providedArgs); 
  9.    //.... 

由于需要在匹配消息消费方法之前就需要解析出消息Body,也就是要先知道消息Body的Java类型才能实现json反序列化,这就要求消息生产者在发送消息时不得不在消息头添加一个参数表示消息Body的Java类型,如下图所示。

在消息消费阶段,Jackson2JsonMessageConverter也需要先根据消息头的TypeId获取JavaType,再执行反序列化操作,当类名修改时,或者生产者和消费者各自定义的类名不同,都将会导致反序列化失败。

除非确保消息Body的类名不会变,且生产者与消费者定义的完整类名相同,否则不建议使用自动序列化与反序列化功能。

本文转载自微信公众号「Java艺术」,作者wujiuye 。转载本文请联系Java艺术公众号。  

 

责任编辑:武晓燕 来源: Java艺术
相关推荐

2015-07-03 09:37:21

程序员外包公司

2021-06-25 11:19:04

LinuxWindows操作系统

2022-05-17 14:28:42

编程语言Julia代码

2020-04-01 17:50:02

Python编程语言

2020-12-24 18:46:11

Java序列化编程语言

2024-06-04 00:10:00

开发拷贝

2024-11-12 10:30:54

Docker部署数据库

2022-12-28 11:44:19

用户画像互联网用户信息

2023-11-01 11:34:40

用户画像企业

2021-06-09 11:28:04

用户画像标签

2024-09-12 08:32:42

2021-08-23 13:02:50

MySQLJOIN数据库

2023-11-06 13:04:59

Python日志库

2020-05-25 10:05:26

Python 开发程序员

2016-10-11 16:31:56

微信服务器消息

2022-01-11 10:29:32

Docker文件挂载

2023-01-24 16:13:22

编程语言JavaIT

2022-09-07 11:38:04

async代码前端

2018-11-29 14:30:42

数据库外键约束应用程序

2021-01-13 09:55:29

try-catch-fJava代码
点赞
收藏

51CTO技术栈公众号