当前位置: 首页 > news >正文

fastjson序列化MessageExt对象问题(1.2.78之前版本)

前言

  无论是kafka,还是RocketMq,消费者方法参数中的MessageExt对象不能被 fastjson默认的方式序列化。

一、查看代码

@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,ConsumeConcurrentlyContext context) {try {GiftSendMessage message = JSON.parseObject(msgs.get(0).getBody(),GiftSendMessage.class);UserInfo userInfo = new UserInfo();userInfo.setMemberId(String.valueOf(message.getFromId()));userInfo.setScId(message.getScId());userInfo.setAnchorScid(message.getAnchorScid());userInfo.setAnchorId(message.getAnchorId());userInfo.setGiftSendToId(message.getToId());DrawByGiftSendConfig draw =filter.getGiftIdBySend().get(String.valueOf(message.getGiftId()));GiftSendRequest request = new GiftSendRequest();request.setActivityId(draw.getActivityId());request.setBoxType(draw.getBoxType());request.setGiftOrderId(message.getGiftOrderId());request.setBatch(message.getAmount());request.setSendTime(message.getSendTime());request.setUserInfo(userInfo);request.setPaymentVersion(PAYMENT_VERSION);this.userDrawService.giftSend(request);LOG.info("DRAW BY GIFT SEND WITH SANTA CHECKOUT, MQ-MESSAGE={}, REQUEST={}",JSON.toJSONString(message),JSON.toJSONString(request));} catch (Exception e) {LOG.error("GIFT-SEND-QUEUE CONSUME FATAL ERROR ON PARSING, DROPPED, MSG={},EXCEPTION={}, EXCEPTION-MESSAGE={}",JSON.toJSONString(msgs), e.getClass().getSimpleName(),e.getMessage(), e);} return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}

二、问题代码

在这里插入图片描述

三、原因分析

  上图中红色方框当中,用的序列化方式为 fastjson,此行代码会抛出异常,导致消费失败,进入重试队列,且没有任何业务日志输出。MQ源码如下:
在这里插入图片描述
如果异常,返回 ConsumeConcurrentlyStatus.RECONSUME_LATER;

结论:无论是kafka,还是RocketMq,消费者方法参数中的MessageExt对象不能被 fastjson默认的方式序列化。

环境:项目采用1.2.31 (最新版本1.2.78)
接下来,我们分析下fastjson序列化的完整过程:
fastjson反序列化的方式默认为采用 get方法、is方法作为序列化属性 字段的,序列化流程如下:
在这里插入图片描述
其中:在获取对象序列化的时候,MessageExt中有返回 ByteBuffer的get方法,代码如下:

public ByteBuffer getStoreHostBytes() {return socketAddress2ByteBuffer(this.storeHost);
} 
//socketAddress2ByteBuffer
public static ByteBuffer socketAddress2ByteBuffer(SocketAddress socketAddress) {ByteBuffer byteBuffer = ByteBuffer.allocate(8);return socketAddress2ByteBuffer(socketAddress, byteBuffer);
}
//socketAddress2ByteBuffer
public static ByteBuffer socketAddress2ByteBuffer(SocketAddress socketAddress, ByteBuffer
byteBuffer) {InetSocketAddress inetSocketAddress = (InetSocketAddress)socketAddress;byteBuffer.put(inetSocketAddress.getAddress().getAddress(), 0, 4);byteBuffer.putInt(inetSocketAddress.getPort());byteBuffer.flip();return byteBuffer;
}

Mq消息在接收到消息时,构造了返回了ByteBuffer对象的方法,该方法是nio中设计用于保存数据到缓冲区的目的。

3.1 ByteBuffer主要的属性,与fastjson的get方法反序列化方式

  • position: 其实是指从buffer读取或写入buffer的下一个元素位置。比如,已经写入buffer 3个元素那那么position就是指向第4个位置,即position设置为3(数组从0开始计);
  • limit:还有多少数据需要从buffer中取出,或还有多少空间可以放入;postition总是<=limit;
  • capacity: 表示buffer本身底层数组的容量。limit绝不能>capacity;

数据结构如下:
在这里插入图片描述

  • get()方法,一字节一字节读;
  • getChar()、getShort()、getInt()、getFloat()、getLong()、getDouble()读取相应字节数的数据;

3.2 最终原因分析得到

  至此:问题显而易见,fastjson在1.2.31及之前,没有提供ByteBuffer 序列化器,所以用了默认的javabean序列化器,而默认的javabean序列化器,又通过get方法反序列化,当遇见ByteBuffer时,ByteBuffer中会先遇到如下方法,getLong():

public long getLong() {return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
} //nextGetIndex
final int nextGetIndex(int nb) { // package-privateif (limit - position < nb)throw new BufferUnderflowException();int p = position;position += nb;return p;
}

每次读取position偏移8个字节,而MessageExt中,构建的ByteBuffer存储的时4个字节,所以会报错,完整的堆栈如下:
在这里插入图片描述

四、总结

  1. fastjson 序列化需注意问题,不能序列化RocketMq工具类中MessageExt对象,会报错;
  2. 原因:MessageExt包含ByteBuffer类型的nio包对象,而低版本fastjson没有该类型序列化器(JavaBeanSerializer),使用默认的序列化器;
  3. ByteBuffer中getLong方法,getLong方法的position偏移8个字节,而MessageExt中,构建的ByteBuffer存储的时4个字节,所以会BufferUnderflowException异常。
  4. BufferUnderflowException异常:表示在读取缓冲区时发生了下溢(underflow)的情况。下溢是指尝试从缓冲区中读取比可用数据量更多的数据;
  5. 无论是kafka,还是RocketMq,消费者方法参数中的MessageExt对象不能被 fastjson默
    认的方式序列化;

相关文章:

fastjson序列化MessageExt对象问题(1.2.78之前版本)

前言 无论是kafka&#xff0c;还是RocketMq&#xff0c;消费者方法参数中的MessageExt对象不能被 fastjson默认的方式序列化。 一、查看代码 Override public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,ConsumeConcurrentlyContext context) {t…...

osi模型,tcp/ip模型(名字由来+各层介绍+中间设备介绍)

目录 网络协议如何分层 引入 osi模型 tcp/ip模型 引入 命名由来 介绍 物理层 数据链路层 网络层 传输层 应用层 中间设备 网络协议如何分层 引入 我们已经知道了网络协议是层状结构,接下来就来了解了解下网络协议如何分层 常见的网络协议分层模型是OSI模型 和 …...

ElasticSearch之找到乔丹的空中大灌篮电影

写在前面 本文看一个搜索的实际例子&#xff0c;找到篮球之神乔丹的电影Space Jam&#xff0c;即空中大灌篮。 正式开始之前先来看下要查询的目标文档&#xff0c;以及查询的text&#xff1a; 要查询的目标文档 {..."title": "Space Jam",..."ove…...

CSS @符规则(@font-face、@keyframes、@media、@scope等)

随着前端开发的不断发展&#xff0c;CSS 的功能日益强大&#xff0c;其中 规则扮演着举足轻重的角色。它们不仅扩展了 CSS 的功能边界&#xff0c;还为开发者提供了更加灵活和高效的样式定义方式&#xff0c;让我们来一同探索这些强大而实用的 规则吧&#xff01; font-face …...

uniapp微信小程序解决上方刘海屏遮挡

问题 在有刘海屏的手机上&#xff0c;我们的文字和按钮等可能会被遮挡 应该避免这种情况 解决 const SYSTEM_INFO uni.getSystemInfoSync();export const getStatusBarHeight ()> SYSTEM_INFO.statusBarHeight || 15;export const getTitleBarHeight ()>{if(uni.get…...

项目:shell实现多级菜单脚本编写

目录 1. 提示 2. 演示效果 2.1. 一级菜单 2.2. 二级菜单 2.3. 执行操作 3. 参考代码 1. 提示 本脚本主要实现多级菜单效果&#xff0c;并没有安装LAMP、LNMP环境&#xff0c;如果要用在实际生成环境中部署LNMP、LAMP环境&#xff0c;只需要简单修改一下就可以了。 2. 演…...

Collections常用方法(Java)

Collections常用方法 使用 sort(List<T> list) 对 List 进行排序&#xff1a; List<Integer> numbers new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6)); Collections.sort(numbers); System.out.println("排序后的列表&#xff1a;" …...

Mysql整理-概述

Mysql概述 MySQL是一种流行的开源关系数据库管理系统(RDBMS),它使用结构化查询语言(SQL)来访问、管理和处理数据。它是基于客户端-服务器模型的数据库,意味着数据存储在服务器上,而用户可以通过客户端软件从不同的位置访问这些数据。 MySQL的主要特点包括: 开源软件:M…...

ubuntu+QT+ OpenGL环境搭建和绘图

一&#xff0c;安装OpenGL库 安装OpenGL依赖项&#xff1a;运行sudo apt install libgl1-mesa-glx命令安装OpenGL所需的一些依赖项。 安装OpenGL头文件&#xff1a;运行sudo apt install libgl1-mesa-dev命令来安装OpenGL的头文件。 安装GLUT库&#xff1a;GLUT&#xff08;Ope…...

Vue实现打印功能(vue-print-nb)

1、安装依赖 npm install vue-print-nb --save2、在main.js中引入 import Print from vue-print-nb Vue.use(Print)3、在组件的打印区域标签上加 id“printArea” <div id"printArea"> 打印区域 </div>4、在组件的打印按钮标签上使用指令 v-print“pr…...

【JSON2WEB】06 JSON2WEB前端框架搭建

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 前端技术路线太多了&#xff0c;知识点更多&…...

【蓝桥杯单片机入门记录】动态数码管

目录 一、数码管动态显示概述 二、动态数码管原理图 &#xff08;1&#xff09;原理图 &#xff08;2&#xff09;动态数码管如何与芯片相连 &#xff08;3&#xff09;“此器件” ——>锁存器74HC573 三、动态数码管显示例程 &#xff08;1&#xff09;例程1&#xf…...

12 Redis之Lua脚本

11. Lua脚本 Lua 是一个由标准 C 语言开发的、开源的、可扩展的、轻量级的、弱类型的、解释型脚本语言 常用于Nginx/分布式锁/ 先下载并安装Lua...

网络安全之内容安全

内容安全 攻击可能只是一个点&#xff0c;防御需要全方面进行 IAE引擎 DFI和DPI技术--- 深度检测技术 DPI --- 深度包检测技术--- 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对 数据包的内容进行识别。&#xff08;应用…...

在CentOS上使用Docker搭建Halo博客并实现远程访问的详细指南

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、数据结构 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. Docker部署Halo1.1 检查Docker版本1.2 在Docker中部署Halo 二. Linux安装Cpol…...

数据结构day5

link_stack.c #include "link_stack.h" //申请栈顶指针 top_p create_top() {top_p top (top_p)malloc(sizeof(top_t));if(topNULL){printf("空间申请失败\n");return NULL;}top->len 0;top->ptop NULL; //刚申请栈指针时没有指向元素return to…...

基础!!!吴恩达deeplearning.ai:神经网络中使用softmax

以下内容有任何不理解可以翻看我之前的博客哦&#xff1a;吴恩达deeplearning.ai 文章目录 softmax作为输出层的神经网络Tensorflow的实现softmax的改进实现数值舍入误差(Numerical Roundoff Errors)sigmoid修改修改softmax 在上一篇博客中我们了解了有关softmax的原理相关内容…...

mapbox高德地图与相机

mapbox高德地图与相机 本案例使用Mapbox GL JavaScript库创建高德地图。 演示效果引入 CDN 链接地图显示 创建地图实例定义地图数据源配置地图图层 设置地图样式实现代码 1. 演示效果 2. 引入 CDN 链接 <script src"https://api.mapbox.com/mapbox-gl-js/v2.12.0/mapb…...

Eslint在Vscode中使用技巧的相关技巧

ps :该文章会详细结论构建一个脚手架遇到的问题&#xff0c;会持续更新&#xff0c;请定时查看 Eslint相关​ 在vscode中使用eslint插件 在vscode中用户配置没有开启eslint.enable 在vscode中工作区配置开启eslint.enable settings.json中没有做eslint相关配置 在编写的vue…...

045-WEB攻防-PHP应用SQL二次注入堆叠执行DNS带外功能点黑白盒条件

045-WEB攻防-PHP应用&SQL二次注入&堆叠执行&DNS带外&功能点&黑白盒条件 #知识点&#xff1a; 1、PHP-MYSQL-SQL注入-二次注入&利用条件 2、PHP-MYSQL-SQL注入-堆叠注入&利用条件 3、PHP-MYSQL-SQL注入-带外注入&利用条件 演示案例&#xff1a…...

实战:用WRF-Chem V3.9.1.1模拟一次华北雾霾过程(附完整namelist配置与排放数据处理心得)

实战&#xff1a;用WRF-Chem V3.9.1.1模拟华北雾霾的完整技术指南 华北地区秋冬季雾霾问题一直是环境科学研究的重点。本文将基于WRF-Chem V3.9.1.1版本&#xff0c;详细介绍如何从零搭建一个针对华北雾霾事件的数值模拟系统。不同于基础教程&#xff0c;我们聚焦于实际科研项目…...

终极Windows系统优化指南:使用RyTuneX实现性能提升300%的完整方案

终极Windows系统优化指南&#xff1a;使用RyTuneX实现性能提升300%的完整方案 【免费下载链接】RyTuneX RyTuneX is a cutting-edge optimizer built with the WinUI 3 framework, designed to amplify the performance of Windows devices. Crafted for both Windows 10 and 1…...

告别米家,用ESP32和Home Assistant打造你的专属HomeKit门窗传感器(附完整YAML配置)

用ESP32和Home Assistant打造高自由度HomeKit门窗传感器 去年装修新房时&#xff0c;我买了十几个米家门窗传感器&#xff0c;用着用着就发现不少痛点&#xff1a;磁铁体积太大影响美观、电池续航不稳定、无法自定义触发逻辑。直到偶然在创客社区发现ESP32Home Assistant的解决…...

【卷卷观察】一边是44%新歌是AI唱的,一边是广告男主脖子扭到后背:AI内容失控的AB面

两条新闻&#xff0c;放在一起读&#xff0c;越读越有意思。欧洲那边&#xff1a;流媒体平台Deezer上周公布了一组数据&#xff0c;平台每日新增音乐里&#xff0c;44%是AI生成的。每天75000首AI歌曲入库。调查发现&#xff0c;97%的用户根本分辨不出哪首是AI唱的、哪首是真人在…...

从‘围成面积’到图像处理:用C++实现连通域分析与面积计算(信息学奥赛题拓展)

从网格到像素&#xff1a;C连通域分析在图像处理中的实战演进 第一次接触连通域问题时&#xff0c;我盯着那个10x10的网格看了整整半小时——那些简单的0和1背后隐藏着怎样的数学之美&#xff1f;后来才发现&#xff0c;这不仅是信息学奥赛的一道题目&#xff0c;更是计算机视觉…...

C# 14原生AOT打包Dify客户端,从218MB到12MB,微软官方未公开的6步精简法,仅限首批内测开发者掌握

第一章&#xff1a;C# 14 原生 AOT 部署 Dify 客户端 2026 最新趋势C# 14 引入的原生 AOT&#xff08;Ahead-of-Time&#xff09;编译能力已深度集成至 .NET SDK 9.0&#xff0c;并成为构建高性能、零依赖 AI 客户端的事实标准。Dify 作为开源 LLM 应用编排平台&#xff0c;其官…...

Zotero-GPT插件5大秘籍:用AI思维重塑文献管理新范式

Zotero-GPT插件5大秘籍&#xff1a;用AI思维重塑文献管理新范式 【免费下载链接】zotero-gpt GPT Meet Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-gpt 你是否曾为堆积如山的文献感到焦虑&#xff1f;每天面对数十篇待读论文&#xff0c;摘要浏览就要…...

告别虚拟机!用Termux在安卓手机上跑Ubuntu的保姆级教程(含自动登录配置)

告别虚拟机&#xff01;用Termux在安卓手机上跑Ubuntu的保姆级教程&#xff08;含自动登录配置&#xff09; 每次出差都要背着沉重的笔记本&#xff0c;或是临时需要调试代码却发现手边没有电脑&#xff1f;现在&#xff0c;你的安卓手机就能变身便携Linux工作站。想象一下&…...

深入理解Hash冲突:两个不相等的对象能否拥有相同的HashCode?

深入理解Hash冲突&#xff1a;两个不相等的对象能否拥有相同的HashCode&#xff1f; 在Java、Python等编程语言中&#xff0c;哈希表&#xff08;HashMap、HashSet等&#xff09;是极为常用的数据结构。而哈希码&#xff08;hashCode&#xff09;作为哈希表的核心概念&#xff…...

智能游戏伴侣BetterGI:让原神体验全面升级的终极解决方案

智能游戏伴侣BetterGI&#xff1a;让原神体验全面升级的终极解决方案 【免费下载链接】better-genshin-impact &#x1f4e6;BetterGI 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动刷本 | 自动采集/挖矿/锄地 | 一条龙 | 全连音游 …...