【Dubbo3高级特性】「性能优化技术」Dubbo3完成扩展使用高效的Kryo和FST序列化开发实战
创始人
2024-04-19 13:56:39

系列文章目录

如果你看到了这里,那么接下来你将会认识Dubbo3的诞生将如何引领微服务领域更进一步,从而迈入云原生的领域,这当然不仅仅是Dubbo3,之前也介绍了Java生态另外一个云原生领域的技术Quarkus等技术,而本文内容侧重点去介绍Dubbo3迈向云原生
的技术分析和探索,如果有不正确的地方,还需要大家多多指正。

在这里插入图片描述


文章目录

  • 系列文章目录
    • 前提介绍
    • 长连接和多路复用
    • Dubbo的序列化
      • 默认的序列化
      • 序列化划分
      • 实战案例:启用Kryo序列化实现
        • 想知道特定但版本可以看一下maven仓库官网地址
          • 在dubbo RPC的XML配置中添加属性
          • 在dubbo RPC的application.yml配置中添加属性
      • 启动FST序列化实现
          • 在dubbo RPC的XML配置中添加属性
          • 在dubbo RPC的application.yml配置中添加属性
      • 进一步提升序列化性能
        • 注册被序列化类
        • 自动注册机制
        • 无参构造函数和Serializable接口


前提介绍

Dubbo-RPC是Dubbo框架体系中最核心的一种高性能、高吞吐量的远程调用方式,称之为多路复用的TCP长连接调用。

长连接和多路复用

  • 长连接:避免了每次调用新建TCP连接,提高了调用的响应速度。
  • 多路复用:单个TCP连接可交替传输多个请求和响应的消息,降低了连接的等待闲置时间,从而减少了同样并发数下的网络连接数,提高了系统吞吐量。

Dubbo的序列化

Dubbo RPC主要用于两个dubbo系统之间作远程调用,特别适合高并发、小数据的互联网场景。而序列化对于远程调用的响应速度、吞吐量、网络带宽消耗等同样也起着至关重要的作用,是我们提升分布式系统性能的最关键因素之一。

Dubbo RPC中,同时支持多种序列化方式,例如:

  • dubbo序列化:阿里尚未开发成熟的高效java序列化实现,阿里不建议在生产环境使用它
  • hessian2序列化:hessian是一种跨语言的高效二进制序列化方式。但这里实际不是原生的hessian2序列化,而是阿里修改过的hessian lite,它是dubbo RPC默认启用的序列化方式
  • json序列化:目前有两种实现,一种是采用的阿里的fastjson库,另一种是采用dubbo中自己实现的简单json库,但其实现都不是特别成熟,而json这种文本序列化性能一般不如上面两种二进制序列化。
  • java序列化:主要是采用JDK自带的Java序列化实现,性能很不理想。

默认的序列化

在通常情况下,这四种主要序列化方式的性能从上到下依次递减,对于dubbo RPC这种追求高性能的远程调用方式来说,实际上只有1、2两种高效序列化方式比较般配,而第1个dubbo序列化由于还不成熟,所以实际只剩下2可用,所以dubbo RPC默认采用hessian2序列化。

但hessian是一个比较老的序列化实现了,而且它是跨语言的,所以不是单独针对java进行优化的。而dubbo RPC实际上完全是一种Java to Java的远程调用,其实没有必要采用跨语言的序列化方式(当然肯定也不排斥跨语言的序列化)。

序列化划分

最近几年,各种新的高效序列化方式层出不穷,不断刷新序列化性能的上限,最典型的包括:

  • 专门针对Java语言的:Kryo,FST等等
  • 跨语言的:Protostuff,ProtoBuf,Thrift,Avro,MsgPack等等

以上这些序列化方式的性能多数都显著优于hessian2(甚至包括尚未成熟的dubbo序列化),有鉴于此,我们为dubbo引入Kryo和FST这两种高效Java序列化实现,来逐步取代hessian2。

  • Kryo是一种非常成熟的序列化实现,已经在Twitter、Groupon、Yahoo以及多个著名开源项目(如Hive、Storm)中广泛的使用。
  • FST是一种较新的序列化实现,目前还缺乏足够多的成熟使用案例,但我认为它还是非常有前途的。

在面向生产环境的应用中,我建议目前更优先选择Kryo

实战案例:启用Kryo序列化实现

使用Kryo和FST非常简单,只需要先增加对应的依赖

想知道特定但版本可以看一下maven仓库官网地址

https://mvnrepository.com/search?q=dubbo-serialization-kryo
在这里插入图片描述再次我们选择最新的版本1.0.1版本的kryo


org.apache.dubbo.extensionsdubbo-serialization-kryo1.0.1

在dubbo RPC的XML配置中添加属性

如果计划采用Java默认的序列化方式,则可以直接使用serialization=“java”。

在dubbo RPC的application.yml配置中添加属性
dubbo:protocol: serialization: kryo

启动FST序列化实现

在dubbo RPC的XML配置中添加属性

在dubbo RPC的application.yml配置中添加属性
dubbo:protocol: serialization: fst

进一步提升序列化性能

注册被序列化类

要让Kryo和FST完全发挥出高性能,最好将那些需要被序列化的类注册到dubbo系统中,例如,我们可以实现如下回调接口:

public class SerializationOptimizerImpl implements SerializationOptimizer {public Collection getSerializableClasses() {List classes = new LinkedList();classes.add(RpcRequest.class);classes.add(RpcResponse.class);classes.add(SyvhecObject.class);classes.add(XXXService.class);classes.add(Impression.class);return classes;}
}

然后在XML配置中添加:


在注册这些类后,序列化的性能可能被大大提升,特别针对小数量的嵌套对象的时候。

当然,在对一个类做序列化的时候,可能还级联引用到很多类,比如Java集合类。针对这种情况,我们已经自动将JDK中的常用类进行了注册,所以你不需要重复注册它们(当然你重复注册了也没有任何影响),包括:

GregorianCalendar
InvocationHandler
BigDecimal
BigInteger
Pattern
BitSet
URI
UUID
HashMap
ArrayList
LinkedList
HashSet
TreeSet
Hashtable
Date
Calendar
ConcurrentHashMap
SimpleDateFormat
Vector
BitSet
StringBuffer
StringBuilder
Object
Object[]
String[]
byte[]
char[]
int[]
float[]
double[]

由于注册被序列化的类仅仅是出于性能优化的目的,所以即使你忘记注册某些类也没有关系。事实上,即使不注册任何类,Kryo和FST的性能依然普遍优于hessian和dubbo序列化。

自动注册机制

自动注册机制中,特别需要考虑如何保证服务提供端和消费端都以同样的顺序(或者ID)来注册类,避免错位,毕竟两端可被发现然后注册的类的数量可能都是不一样的。

无参构造函数和Serializable接口

如果被序列化的类中不包含无参的构造函数,则在Kryo的序列化中,性能将会大打折扣,因为此时我们在底层将用Java的序列化来透明的取代Kryo序列化。所以,尽可能为每一个被序列化的类添加无参构造函数是一种最佳实践(当然一个java类如果不自定义构造函数,默认就有无参构造函数)。

另外,Kryo和FST本来都不需要被序列化的类实现Serializable接口,但我们还是建议每个被序列化类都去实现它,因为这样可以保持和Java序列化以及dubbo序列化的兼容性,另外也使我们未来采用上述某些自动注册机制带来可能。

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...