Java 性能调优实战
刘超
前金山软件技术经理
59174 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
开篇词 (1讲)
模块一 · 概述 (2讲)
结束语 (1讲)
Java 性能调优实战
15
15
1.0x
00:00/00:00
登录|注册

09 | 网络通信优化之序列化:避免使用Java序列化

JSON序列化、Protocol Buffers
控制反序列化对象
使用其他序列化协议
需要序列化与反序列化
解决方法
只能对实现了Serializable接口的类的对象进行反序列化和序列化
Dubbo默认使用Hessian序列化
SpringCloud使用Json序列化
不同业务之间通信需要通过接口实现调用
比较Java序列化和NIO中的ByteBuffer编码的大小和性能
Apache Commons Collections漏洞
writeReplace()和readResolve()
writeObject和readObject
用于验证序列化对象是否加载了反序列化的类
不序列化静态变量
仅对非transient的实例变量进行序列化
ObjectInputStream和ObjectOutputStream
主流微服务框架避免使用Java序列化
服务解耦带来的问题
选择适合的序列化框架优化系统性能
避免使用Java序列化
Protocol Buffers存储格式和实现原理
性能优秀
多语言支持
影响网络通信效率和系统响应时间
影响存储空间和网络带宽
反序列化存在安全漏洞
Java序列化只适用于基于Java语言实现的框架
其他重写方法
实现序列化的方法
生成serialVersionUID版本号
默认序列化方式
JDK提供的序列化机制
优秀的序列化框架可以提高系统整体性能
大部分后端服务基于微服务架构
实现了Java的Serializable接口的单例
总结
Protobuf的优势
序列化性能太差
序列化后的流太大
易被攻击
无法跨语言
Java序列化的实现原理
为什么要避免使用Java序列化
思考题
使用Protobuf序列化替换Java序列化
Java序列化的缺陷
Java序列化
为什么要避免使用Java序列化
网络通信中,为什么要避免使用Java序列化

该思维导图由 AI 生成,仅供参考

你好,我是刘超。
当前大部分后端服务都是基于微服务架构实现的。服务按照业务划分被拆分,实现了服务的解耦,但同时也带来了新的问题,不同业务之间通信需要通过接口实现调用。两个服务之间要共享一个数据对象,就需要从对象转换成二进制流,通过网络传输,传送到对方服务,再转换回对象,供服务方法调用。这个编码和解码过程我们称之为序列化与反序列化。
在大量并发请求的情况下,如果序列化的速度慢,会导致请求响应时间增加;而序列化后的传输数据体积大,会导致网络吞吐量下降。所以一个优秀的序列化框架可以提高系统的整体性能。
我们知道,Java 提供了 RMI 框架可以实现服务与服务之间的接口暴露和调用,RMI 中对数据对象的序列化采用的是 Java 序列化。而目前主流的微服务框架却几乎没有用到 Java 序列化,SpringCloud 用的是 Json 序列化,Dubbo 虽然兼容了 Java 序列化,但默认使用的是 Hessian 序列化。这是为什么呢?
今天我们就来深入了解下 Java 序列化,再对比近两年比较火的 Protobuf 序列化,看看 Protobuf 是如何实现最优序列化的。

Java 序列化

在说缺陷之前,你先得知道什么是 Java 序列化以及它的实现原理。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Java序列化存在诸多缺陷,包括跨语言通信问题、安全漏洞、性能低下等。因此,建议避免使用Java序列化,而选择替代方案如Json序列化、Hessian序列化或Protobuf序列化。本文详细介绍了Protobuf序列化的优势,以及通过反序列化对象白名单来控制反序列化对象的方法。同时,对比了Java序列化和NIO中的ByteBuffer编码的性能,清晰地展示了Java序列化的缺陷。文章还提到了Protocol Buffers存储格式及其实现原理,以及Protobuf的高效编码和解码过程。最后,文章强调了选择适合的序列化框架来优化系统的序列化性能,推荐了FastJson、Protobuf和Kryo等主流序列化框架。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Java 性能调优实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(36)

  • 最新
  • 精选
  • 陆离
    序列化会通过反射调用无参构造器返回一个新对象,破坏单例模式。 解决方法是添加readResolve()方法,自定义返回对象策略。

    作者回复: 回答正确

    2019-06-08
    7
    102
  • 密码123456
    看到提问,才发现这竟然不是单例。回想内容是因为。可以把类路径上几乎所有实现了 Serializable 接口的对象都实例化。还真不知道怎么写?内部私有类实现,这种可以吗?

    作者回复: 线上代码发生错位了,已修正。 导致这个问题的原因是序列化中的readObject会通过反射,调用没有参数的构造方法创建一个新的对象。 所以我们可以在被序列化类中重写readResolve方法。 private Object readResolve(){ return singleInstance; }

    2019-06-08
    7
    24
  • 尔冬橙
    它会在反序列化过程中来验证序列化对象是否加载了反序列化的类,如果是具有相同类名的不同版本号的类,在反序列化中是无法获取对象的。老师,这句话能举个例子么,没太明白

    作者回复: 在Class类文件中默认会有一个serialNo作为序列化对象的版本号,无论在序列化方还是在反序列化方的class类文件中都存在一个默认序列号,在序列化时,会将该版本号加载进去,在反序列化时,会校验该版本号。

    2019-09-14
    9
  • kevin
    老师请教下,为什么spring cloud不使用protobuf, thrift等性能更高、支持跨平台的序列化工具,而且使用json?

    作者回复: springcloud是spring生态中的一部分,就目前spring生态很少引入非生态框架。但是我们可以自己实现springcloud兼容protobuf序列化。

    2019-06-09
    7
  • -W.LI-
    文中说Java序列化,不会序列化静态变量,这个单例的静态变量会被怎么处理啊?

    作者回复: 是的,Java序列化会调用构造函数,构造出一个新对象

    2019-06-08
    2
    7
  • waniz
    老师您好,Java序列化将数据转化为二进制字节流,json序列化将数据转化为json字符串。但是在物理层数据都是以电信号或模拟信号传输。那么从应用层到物理层数据的编码状态究竟是怎么变化的?出发点不同,最后都是二进制传输…忘解惑

    作者回复: Java序列化是将Java对象转化为二进制流,而Json序列化是将Json字符串转为二进制的过程,只是包装的数据格式不一样。

    2019-07-05
    2
    6
  • 天天向上
    想知道为什么用非Java的序列化方式的也需要实现Serializable接口?

    作者回复: 这是Java说明需要序列化的一种标识

    2019-12-28
    4
  • 课后思考及问题 1:老师能深入细致的讲讲JAVA怎么实现序列化的嘛?比如:一个对象怎么一步步神奇的变成一个字节数组的?对象中的属性、属性值、方法、以及此对象的信息怎么变成一个字节数组的? 2:我们知道对象是通过在 ObjectInputStream 上调用 readObject() 方法进行反序列化的,这个方法其实是一个神奇的构造器,它可以将类路径上几乎所有实现了 Serializable 接口的对象都实例化。 这个神奇的构造器的实现原理是啥?一个字节数组他怎么将其转换为一个对象的?很好奇,他知道字节数组多少位表示啥意思?然后一段一段的取,一段的翻译嘛?老师给讲讲呗? 老师深入讲一下原理实现细节,API式的讲解不过瘾,和老师要深入理解的风格也不符呀😄

    作者回复: 序列化是将一个对象通过某种数据结构包装好对象中的具体属性和值,转换为二进制进行网络传输的一个过程。例如一个int类型的属性,数组是1000,转换为二进制则是4个字节的byte数组了。 后面我会使用一个具体的例子来优化讲解这一讲。

    2019-09-07
    3
  • 晓杰
    不是单例,因为在反序列化的时候,会调用ObjectInputStream的readObject方法,该方法可以对实现序列化接口的类进行实例化,所以会破坏单例模式。 可以通过重写readResolve,返回单例对象的方式来避免这个问题

    作者回复: 正确

    2019-06-08
    2
    1
  • 尔冬橙
    序列化对象中加载反序列化的类怎么理解?

    作者回复: 我也没有看懂这句话,请问在哪里看到的?

    2020-02-15
收起评论
显示
设置
留言
36
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部