【专栏】RPC系列(理论)-协议与序列化

学长来引流啦,刚毕业一年,在魔都某大厂,大家可以关注公众号【离心计划】,我会出一些高质量的实战教程,让大家对于技术有更多的了解

目录

【专栏】RPC系列(理论)-夜的第一章_scwMason的博客-CSDN博客

正文

今天我们接着上一篇文章【专栏】RPC系列(理论)-夜的第一章,进一步讲解RPC中协议和序列化的作用。

RPC的最终目标是调用远程服务并拿到返回,涉及到通信必定会涉及到“网络编程”领域,其实网络的目的也很简单,就是实现两个进程的通信,相信你八股文也背过进程间通信的方式,socket的方式那便可以理解成网络了。

无论是七层网络还是四层网络,落到物理网卡的传输的都是二进制数据流,而对于我们的应用程序,我们只认识”对象“。什么意思呢,对java而言你只能从User实例中调用getName方法拿到名字,而无法直接从01010101中拿到名字,所以这里是第一个网络问题:序列化。

| 序列化

序列化指数据从存储状态到传输状态的转化,对应反序列化就是传输状态到存储状态的转化,说人话从网络的角度,便是对象与二进制之间的互相转换。业界有许许多多的序列化方式,常见的如Json、XML这种可读性较好的文本序列化方式,还有Hession、Kyro、Protobuf这种效率较高的二进制序列化方式,有这么多形形色色的方式是因为序列化方式永远在效率和可读性之间做拉扯,正是因为没有一种兼得的方式才诞生了这么多产物。

Json的好处在于可读性强

{
   "name":"sugela",
   "age":"23"
}

缺点在于你看表示两个信息名字和年龄,居然需要这么多字符,还有什么空格引号在里面。而二进制序列化方式就显得更加 紧凑 ,相同空间可以存放更多信息。所以他们的使用场景也是不同,json一般在C端应用中,需要对传输数据直接展示,比如后端传输商品信息给前端,就需要可读性较好的表现形式。而微服务之间的数据传输,更多偏向于效率,牺牲可读性无所谓,应用可以快速响应就行。

这样,我们可以通过各种序列化方式在对象和二进制之间转换,数据经过网络只要经过反序列化就可以变成我们想要的结构化对象

| 协议

协议我们上一篇文章也提及过,目的是为了让收发数据两端能够按照统一的格式去传输,虽然说在序列化小结中我们说了把对象转换成二进制,比如有(纯属乱打)

1001100011111100011010101000

对应User:

public class User implements Serializable {
    String name;
    Integer age;
    Byte gender;
}

我们总得知道哪几位表示name,哪几位表示age吧。另外除了这些数据信息,我们还需要一个”协议头“来表示协议的一些基本约定吧,比如协议版本,发送端升级了协议用1.1版本,接收端还是用1.0那肯定有问题。所以我们总结来说,协议分为两步:语义设计和分割设计

语义设计就是基于结构化的数据,我们如何表示一条消息,目标是通用、兼容。通常我们将协议分为协议头和协议体,协议头存放版本、消息类型等信息,协议体主要存放真实数据

这是一个协议的大概语义,看起来很简单,其实应用层协议的设计大致便是这样,http也是分为请求行、请求头和请求主题三部分。ok,现在还有一个问题,便是我们如何区分协议头和协议体的起始位置?这就需要分割设计

分割设计可以理解为”断句“,这里有一个小笑话:

新闻:佟大为妻子产下一女
评论:这个佟大是谁?真了不起,太厉害了!!

很简单,断句就是将信息分割,让人知道怎么去理解,分割设计则是为了让应用知道如何区分。通常我们在协议设计中会使用”长度“来实现分割,也就是在协议头之前加上一个协议头的长度

这样我们在协议两个部分的时候,就知道一段二进制流从头开始到哪结束是协议头,就区分开了协议头和协议体。

| 小结

协议规定了数据的传输格式,序列化实现了二进制与实例之间的转化,这样一来我们就可以通过网络编程方式进行数据传输了,这也是RPC的基本网络通信能力,后面我们会动手实现自定义协议与各种序列化方式,纸上得来终觉浅。

【RPC系列合集】

【专栏】RPC系列(理论)-夜的第一章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值