RPC远程调用的序列化框架

news/2024/9/22 17:40:04/

序列化框架对比:

在这里插入图片描述

一、Java Serialiazer

字段serialVersionUID的作用是为了在序列化时保持版本的兼容性,即版本升级时反序列化仍保持对象的唯一性。

//序列化
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutoutStream out = new ObjectOutputStream(bout);
out.writeObject(obj);
byte[] bytes = bout.toByteArray();//反序列化
ObjectInputStream bin = new ObjectInputStream(new ByteArrayInputStream(bytes));
bin.readObject();

二、Hessian

底层基于list和HashMap实现
其在序列化的类有父类的时候,如果有字段相同,父类的值会覆盖子类的值,因此使用时一定要注意子类和父类不能有同名字段

Hessian的实现有v1和v2两个版本,并不兼容。推荐使用Hessian2相关的类

//序列化
ByteArrayOutputStream os = new ByteArrayOutputStream();
Hessian2Output out = new Hessian2Output(os);
out.startMessage();
TestUser user = new TestUser();
out.writeObject(user);
out.completeMessage()
out.flush();
byte[] bytes = os.toByteArray();
out.close();
os.close();//反序列化
ByteArrayInputStream ins = new ByteArrayInputStream(bytes);
Hessian2Input input = new Hessian2Input(ins);
input.startMessage();
TestUser newUser = (TestUser)input.readObject();
input.completeMessage();
input.close();
ins.close();

三、MsgPack

需要在序列化的类上加@Message注解
为了保证序列化向后兼容,新增加的属性需要加在类的最后面,且要加@Optional注解

MsgPack提供了动态类型的功能,通过接口Value来实现动态类型
首先将数组序列化为Value类型的对象,然后用converter转化为本身的类型

//TestUser.java
@Message
public class TestUser{private String name;private String mobile;//...
}TestUser user = new TestUser();
MessagePack messagePack = new MessagePack();//序列化
byte[] bs = messagePack.write(user);//反序列化
user = messagePack.read(bs,TestUser.class);

四、Kryo

Kryo kryo = new Kryo();//序列化
ByteArrayOutputStream os = new ByteArrayOutputStream();
Output output = new Output(os);
TestUser user = new TestUser();
kryo.writeObject(output,user);
output.close();
byte[] bytes = os.toByteArray();//反序列化
Input input = new Input(new ByteArrayInputStream(bytes));
TestUser newUser = kryo.readObject(input,TestUser.class);
input.close();

五、Thrift

需要先定义IDL,再使用Thrift

//定义IDL
//TestUser.thrift
namespace java.me.rowkey.pje.datatrans.rpc.thriftstruct TestUser{1: required string name2: required string mobile
}thrift --gen java TestUser.trhrift

使用生成的TestUser类做序列化和反序列化

TestUser user = new TestUser();//由Thrift代码生成引擎生成//序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
user.write(new TBinaryProtocol(new TIOStreamTransport(bos)));
byte[] result = bos.toByteArray();
bos.close();//反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(result);
TestUser user = new TestUser();
user.read(new TBinaryProtocol(new TIOStreamTransport(bis)));
bis.close();

由于Thrift序列化时,丢弃了部分信息,故使用ID+Type来做标识
因此对新增的字段属性采用ID递增的方式标识并以Optional修饰来添加,这样才能做到向后兼容

六、Protobuf

Google开源的序列化框架

首先需要编写.proto文件,并使用Protobuf代码生成引擎生成Java代码

//TestUser.proto
syntax = "proto3";
option java_package = "me.rowkey.pje.datatras.rpc.proto";
option java_outer_classname = "TestUserProto";
message TestUser{string name = 1;string mobile = 2;
}protoc --java_out = ./TestUser.proto

即生成TestUserProto.java,使用此类即可完成序列化和反序列化

//序列化
TestUserProto.TestUser testUser = TestUserProto.TestUser.newBuilder().setMobile("xxx").setName("xxx").build();
byte[] bytes = testUser.toByteArray();//反序列化
testUser = TestUserProto.TestUser.parseFrom(bytes);

使用提示:

面对RPC框架,选择的时候需要一下方面进行选择

  • 是否允许代码侵入,即需要依赖响应的代码生成器生成代码,入Thrift
  • 是否需要长连接获取高性能,如果性能需求高,则选择基于TCP的Thrift/Dubbo
  • 是否需要跨网段、跨防火墙,需要基于HTTP协议的Hessian和Thrift的HTTP Transport

http://www.ppmy.cn/news/1528933.html

相关文章

SpinalHDL之结构(三)

本文作为SpinalHDL学习笔记第六十三篇,介绍SpinalHDL的函数(Function)。 目录: 1.简介(Introduction) 2.RGA到灰度(RGB to grey) 3.Valid和Ready负载总线(Valid Ready Payload bus) ⼀、简介(Introduction) ⽤Scala函数产⽣硬件的⽅式与VHDL/Verilog…

计算机人工智能前沿进展-大语言模型方向-2024-09-21

计算机人工智能前沿进展-大语言模型方向-2024-09-21 1. AIvril: AI-Driven RTL Generation With Verification In-The-Loop Authors: Mubashir ul Islam, Humza Sami, Pierre-Emmanuel Gaillardon, and Valerio Tenace AIVRIL: 人工智能驱动的RTL生成与验证内循环 摘要 本…

响应式CSS 媒体查询——WEB开发系列39

CSS媒体查询(Media Queries)是响应式设计中的核心技术之一,帮助我们在不同设备上展示不同的样式。通过媒体查询,开发者可以检测用户设备的特性,如屏幕宽度、高度、分辨率、方向等,针对性地调整网页布局。 一…

Go语言的垃圾回收(GC)机制的迭代和优化历史

Go语言的垃圾回收(GC)机制自Go语言发布以来经历了多次重要的迭代和优化,以提高性能和减少程序运行时的停顿时间。 以下是一些关键的版本和相应的GC优化: Go版本GC耗时情况主要改进点Go 1.0-1.4可能达到几百毫秒至秒级使用简单的标…

第一章 HTTP

目录 一、HTTP简介 1.1. 概述 1.2. HTTP与TCP的区别 二、HTTP迭代版本 三、HTTP请求头 四、HTTP响应 五、请求头中的请求方式 一、HTTP简介 1.1. 概述 超文本传输协议(Hypertext Transfer Protocol,HTTP),用于在客户端和服…

ERP进销存管理系统的业务全流程 Axure高保真原型源文件分享

这是一套ERP进销存管理系统的业务全流程Axure高保真原型设计文档。 原型预览地址:https://ppndif.axshare.com 产品意义: 提高工作效率: 电子记账替代手工记账,减少工作负担和人为错误。 实时查看库存情况,减少盘点时…

从现象级到“无人问津”,“高格调”的知乎为啥失宠了?

撰文|ANGELICA 编辑|ANGELICA 审核|烨 Lydia 声明|图片来源网络。日晞研究所原创文章,如需转载请留言申请开白。 看到这个页面布局,你以为是小红书吗? 不,这是现在版本的知乎首页…

调整pycharm中的字体大小

1.找到设置 2.打开setting ,按照图示操作即可