Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >你的Redis有类转换异常么

你的Redis有类转换异常么

作者头像
luoxn28
发布于 2019-11-06 06:14:57
发布于 2019-11-06 06:14:57
87102
代码可运行
举报
文章被收录于专栏:TopCoderTopCoder
运行总次数:2
代码可运行

之前同事反馈说线上遇到Redis反序列化异常问题,异常如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
XxxClass1 cannot be cast to XxxClass2

已知信息如下:

•该异常不是必现的,偶尔才会出现;•出现该异常后重启应用或者过一会就好了;•序列化协议使用了hessian。

因为偶尔出现,首先看了报异常那块业务逻辑是不是有问题,看了一遍也发现什么问题。看了下对应日志,发现是在Redis读超时之后才出现的该异常,因此怀疑redis client操作逻辑那块导致的(公司架构组对redis做了一层封装),发现获取/释放redis连接如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {    jedis = jedisPool.getResource();    // jedis业务读写操作} catch (Exception e) {    // 异常处理} finally {    if (jedis != null) {        // 归还给连接池        jedisPool.returnResourceObject(jedis);    }}

初步认定原因为:发生了读写超时的连接,直接归还给连接池,下次使用该连接时读取到了上一次Redis返回的数据。因此本地验证下,示例代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Data@NoArgsConstructor@AllArgsConstructorstatic class Person implements Serializable {    private String name;    private int age;}@Data@NoArgsConstructor@AllArgsConstructorstatic class Dog implements Serializable {    private String name;}
public static void main(String[] args) throws Exception {    JedisPoolConfig config = new JedisPoolConfig();    config.setMaxTotal(1);    JedisPool jedisPool = new JedisPool(config, "192.168.193.133", 6379, 2000, "123456");
    Jedis jedis = jedisPool.getResource();    jedis.set("key1".getBytes(), serialize(new Person("luoxn28", 26)));    jedis.set("key2".getBytes(), serialize(new Dog("tom")));    jedisPool.returnResourceObject(jedis);
    try {        jedis = jedisPool.getResource();        Person person = deserialize(jedis.get("key1".getBytes()), Person.class);        System.out.println(person);    } catch (Exception e) {        // 发生了异常之后,未对该连接做任何处理        System.out.println(e.getMessage());    } finally {        if (jedis != null) {            jedisPool.returnResourceObject(jedis);        }    }
    try {        jedis = jedisPool.getResource();        Dog dog = deserialize(jedis.get("key2".getBytes()), Dog.class);        System.out.println(dog);    } catch (Exception e) {        System.out.println(e.getMessage());    } finally {        if (jedis != null) {            jedisPool.returnResourceObject(jedis);        }    }}

连接超时时间设置2000ms,为了方便测试,可以在redis服务器上使用gdb命令断住redis进程(如果redis部署在Linux系统上的话,还可以使用iptable命令在防火墙禁止某个回包),比如在执行 jedis.get("key1".getBytes() 代码前,对redis进程使用gdb命令断住,那么就会导致读取超时,然后就会触发如下异常:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Person cannot be cast to Dog

既然已经知道了该问题原因并且本地复现了该问题,对应解决方案是,在发生异常时归还给连接池时关闭该连接即可(jedis.close内部已经做了判断),代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
try {    jedis = jedisPool.getResource();    // jedis业务读写操作} catch (Exception e) {    // 异常处理} finally {    if (jedis != null) {        // 归还给连接池        jedis.close();    }}

至此,该问题解决。注意,因为使用了hessian序列化(其包含了类型信息,类似的有Java本身序列化机制),所有会报类转换异常;如果使用了json序列化(其只包含对象属性信息),反序列化时不会报异常,只不过因为不同类的属性不同,会导致反序列化后的对象属性为空或者属性值混乱,使用时会导致问题,并且这种问题因为没有报异常所以更不容易发现。

既然说到了Redis的连接,要知道的是,Redis基于RESP(Redis Serialization Protocol)协议来通信,并且通信方式是停等方式,也就说一次通信独占一个连接直到client读取到返回结果之后才能释放该连接让其他线程使用。小伙伴们可以思考一下,Redis通信能否像dubbo那样使用单连接+序列号(标识单次通信)通信方式呢?理论上是可以的,不过由于RESP协议中并没有一个"序列号"的字段,所以直接靠原生的通信方法来实现是不现实的。不过我们可以通过echo命令传递并返回"序列号"+正常的读写方式来实现,这里要保证二者执行的原子性,可以通过lua脚本或者事务来实现,事务方式如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MULTIECHO "唯一序列号"GET key1EXEC

然后客户端收到的结果是一个 [ "唯一序列号", "value1" ]的列表,你可以根据前一项识别出这是你发送的哪个请求。

为什么Redis通信方式并没有采用类似于dubbo这种通信方式呢,个人认为有以下几点:

•使用停等这种通信方式实现简单,并且协议字段尽可能紧凑;•Redis都是内存操作,处理性能较强,停等协议不会造成客户端等待时间较长;•目前来看,通信方式这块不是Redis使用上的性能瓶颈,这一点很重要。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TopCoder 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
打破次元壁,让游戏角色在指尖跳舞,简易的 AR 教程
作为一个天涯明月刀游戏的端游老玩家,天刀的画质是没的说的。玩天刀的七年,我唯一最大的收获就是拐了女朋友回家。至此,双十一来临之际,我紧急把之前想写的教程赶了出来。为了让单身的少侠可以在现实世界有自己游戏角色的陪伴,不再那么孤单,我可真是操碎了心,半夜把网页赶了出来。其实单身和非单身的双十一区别不是很大,只是吃土的方式不一样罢了。话不多说,我们先来看下效果:
桑榆肖物
2022/11/18
9940
打破次元壁,让游戏角色在指尖跳舞,简易的 AR 教程
内容创造:GANs技术在图像与视频生成中的应用
生成对抗网络(Generative Adversarial Networks,简称GANs)是近年来在机器学习领域引起广泛关注的一种新型算法框架。它通过让两个神经网络——生成器和判别器——相互竞争来生成新的、与真实数据相似的数据样本。GANs在图像与视频生成领域的应用前景广阔,本文将探讨GANs技术的基本原理、在内容创造中的应用案例、面临的挑战以及未来的发展方向。
二一年冬末
2024/05/09
4300
使用Python实现深度学习模型:智能电影制作与剪辑
随着人工智能技术的飞速发展,深度学习在各个领域的应用越来越广泛。在电影制作与剪辑领域,深度学习技术也展现出了巨大的潜力。本文将介绍如何使用Python实现一个简单的深度学习模型,用于智能电影制作与剪辑。我们将使用TensorFlow和Keras库来构建和训练模型,并展示如何应用该模型进行视频剪辑。
Echo_Wish
2024/09/24
2350
使用Python实现深度学习模型:智能电影制作与剪辑
使用Pytorch和OpenCV实现视频人脸替换
“DeepFaceLab”项目已经发布了很长时间了,作为研究的目的,本文将介绍他的原理,并使用Pytorch和OpenCV创建一个简化版本。
deephub
2023/08/30
6670
使用Pytorch和OpenCV实现视频人脸替换
Python实现高级电影特效
前几天写了个实现特效的博客,感觉有点差强人意,只是简简单单的换背景应用场景不是非常多,今天就来实现一个更加复杂的特效“影分身”。下面有请我们本场的主演,坤制作人为我们表演他拿手的鸡你太美。
ZackSock
2020/05/18
1.5K0
Python实现高级电影特效
短视频篇 | Python 带你进行短视频二次创作
无论是抖音还是快手等视频平台,一旦一个视频火了后,很多 UP 主都会争先抢后去模仿拍摄或剪辑,然后上传到平台,最后都能带来不错的流量。
AirPython
2020/03/23
1.7K0
短视频篇 | Python  带你进行短视频二次创作
飞桨PaddleHub带你环游世界,快来试试Python一键视频抠图吧
在视频创作过程中,有时会遇到人像抠图的需求,最一般的做法是使用PR、AE等工具将视频中的每一帧图像手动抠图。这么繁琐的步骤在理工男面前简直是不可存在的,那么有什么简单的方法能快速抠图吗?当然有啦,接下来给大家介绍如何使用PaddleHub一键视频人像抠图。
用户1386409
2020/04/22
1.8K0
5 分钟实现「视频检索」:基于内容理解,无需任何标签
「视频检索」任务就是输入一段文本,检索出最符合文本描述的视频。随着各类视频平台的兴起和火爆,网络上视频的数量呈现井喷式增长,「视频检索」成为人们高效查找视频的一项新需求。
Zilliz RDS
2023/01/10
4.8K0
5 分钟实现「视频检索」:基于内容理解,无需任何标签
tf27: Deep Dream—应用到视频
本文介绍了如何将Deep Dream技术应用于视频上,通过使用TensorFlow和Python实现Deep Dream算法,从而对视频进行逐帧处理,产生具有梦幻效果的视频。同时,也介绍了一些相关的工具和库,如ffmpeg、numpy、scipy、scikit-learn等,这些工具可以帮助我们更好地实现Deep Dream算法。此外,还介绍了一些Deep Dream算法的应用,如图像风格转换、图像修复、图像超分辨率等。最后,也介绍了一些实现Deep Dream算法的技巧和最佳实践,如调整网络结构、选择合适的预训练模型、使用预训练权重等。通过本文的学习,我们可以更好地理解Deep Dream算法,并能够将其应用于实际的视频处理任务中。"
MachineLP
2018/01/09
6750
如何用GPT-4o解读视频
  OpenAI在去年推出的GPT-4V已经支持了多模态识别,但一直仅限于图片输入,不支持视频。相比之下,Google的Gemini早已支持视频识别。最近,我司业务场景中出现了一个需要识别视频的需求,而我们只采购了GPT-4o模型。这就引发了一个问题:如何使用GPT-4o完成对视频的处理?
xindoo
2024/11/18
6230
如何用GPT-4o解读视频
使用Python实现深度学习模型:视频处理与动作识别
视频处理与动作识别是计算机视觉中的重要任务,广泛应用于监控系统、智能家居、体育分析等领域。通过使用Python和深度学习技术,我们可以构建一个简单的动作识别系统。本文将介绍如何使用Python实现视频处理与动作识别,并提供详细的代码示例。
Echo_Wish
2024/07/16
6820
使用Python实现深度学习模型:视频处理与动作识别
多模态AI的未来:从文本到视频的智能融合
随着人工智能技术的迅猛发展,多模态AI正逐渐成为研究和应用的热点。多模态AI通过融合文本、图像、音频和视频等多种数据模态,能够更全面地理解和生成信息,为各行各业带来新的机遇。本文将深入探讨多模态AI的未来发展方向,特别是从文本到视频的智能融合,并通过详细代码实例展示其技术实现。
江南清风起
2025/03/24
2980
多模态RAG应用之实现文本检索视频内容
现如今无论是谷歌百度搜索知识学习,还是淘宝京东购物都离不开文字关键词的搜索。但现在很多平台或者应用有大量的视频,还有某些跟视频打交道的应用比如视频编辑器,视频自动化处理工具等,这些工具如果只有简单的文本搜索就远远不够用了,搜索体验肯定会大打折扣;由此引出我们今天的主题:
郑子铭
2025/01/07
2590
多模态RAG应用之实现文本检索视频内容
百万点赞怎么来?Python批量制作抖音的卡点视频原来这么简单!
玩抖音的朋友都应该知道,最近「卡点视频」简直不要太火。抖音上很多大神也出了剪辑各种卡点视频的教程。
一墨编程学习
2019/07/18
2.8K0
百万点赞怎么来?Python批量制作抖音的卡点视频原来这么简单!
Python实现5毛钱特效
Python牛已经不是一天两天的事了,但是我开始也没想到,Python能这么牛。前段时间接触了一个批量抠图的模型库,而后在一些视频中找到灵感,觉得应该可以通过抠图的方式,给视频换一个不同的场景,于是就有了今天的文章。
ZackSock
2020/04/16
1.1K0
【AI视频】Runway: Gen-2 与 Gen-3 文本生视频详解
Gen-3 是 Runway 在2024年6月18日推出的全新生成视频模型。作为 Gen-2 的继任者,Gen-3 引入了更先进的技术,在效率和图像生成效果上都得到了显著提升。 新推出的功能 相比 Gen-2,Gen-3 主要增强了以下功能:
CSDN-Z
2024/10/17
2.8K0
【AI视频】Runway: Gen-2 与 Gen-3 文本生视频详解
视频数据处理方法!关于开源软件FFmpeg视频抽帧的学习
视频文件是多媒体数据中比较常见的一种,也是入门门槛比较高的一个领域。视频数据相关的领域任务包括视频物体检测、视频物体追踪、视频分类、视频检索和视频摘要抽取等。
Datawhale
2019/10/23
4.1K0
视频数据处理方法!关于开源软件FFmpeg视频抽帧的学习
【AI视频】Runway:Gen-2 图文生视频与运动模式详解
Runway的图加文生成视频模式和运动模式为创作者提供了极大的创作灵活性。通过结合静态图片和文本提示,用户能够快速生成高质量的动态视频。同时,运动模式(Motion)允许根据不同的需求调整视频的动态效果,从轻微的细节移动到剧烈的场景变化都有所覆盖。这种工具不仅简化了复杂视频的制作流程,还大幅提升了创作效率,极大地拓宽了视频内容创作的可能性,为创作者提供了前所未有的便利和创意空间。
CSDN-Z
2024/10/17
9180
【AI视频】Runway:Gen-2 图文生视频与运动模式详解
音视频开发之旅(72)- AI数字人-照片说话之SadTalker
AI数字人目前做的最好的无疑是heygen,但是费用也是很贵,也有一些其他的商业应用,比如:微软小冰、腾讯智影、万兴播爆和硅基智能等。
音视频开发之旅
2024/03/02
7190
python带你剪辑视频
嗯,好久没写文章了。因为最近没有熬夜了,天天背电脑也很辛苦。 工作嘛,手工为主,没有啥技术成长,也没啥好写的。 疫情期间,总听到有人叹气,总听到抖音里面“我太难了”。
赵云龙龙
2020/08/13
3.1K0
推荐阅读
相关推荐
打破次元壁,让游戏角色在指尖跳舞,简易的 AR 教程
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验