1.rpc框架对比
Dubbo | Montan | rpcx | gRPC | Thrift | |
---|---|---|---|---|---|
厂商 | 阿里 开源 | 新浪微博 | Go语言生态圈 | Google开发 | Facebook 开源 |
开发语言 | Java | Java | Go | 跨语言 | 跨语言 |
分布式(服务治理) | √ | √ | √ | × | × |
多序列化框架支持 | √ | √ (当前支持Hessian2、Json,可扩展) | √ | × (只支持protobuf) | × (thrift格式) |
多种注册中心 | √ | √ | √ | × | × |
管理中心 | √ | √ | √ | × | × |
跨编程语言 | × | × (支持php client和C server) | × | √ | √ |
2.序列化协议
protobuf协议
(1)定义
Protobuf 序列化更多地用于跨语言的通信
gRpc只支持protobuf协议,简称pb协议(面试了几次一直没研究,今天补充上)
protocol buffers 由谷歌开源而来,在谷歌内部久经考验。它将数据结构以.proto文件进行描述,通过代码生成工具可以生成对应数据结构的POJO对象和Protobuf相关的方法和属性。
(2)优点
-
序列化后码流小,性能高
-
结构化数据存储格式(XML JSON等)
-
通过标识字段的顺序,可以实现协议的前向兼容
-
结构化的文档更容易管理和维护
(3)缺点
-
需要依赖于工具生成代码
-
支持的语言相对较少,官方只支持Java 、C++ 、Python
(4)适用场景
-
对性能要求高的RPC调用
-
具有良好的跨防火墙的访问属性
-
适合应用层对象的持久化
(5)原理探究
pb协议为什么更快更小
查看下面一个json,protobuffer在处理得时候,对于key得处理不存储具体得key,而是通过编号进行存储,比如name使用1,version使用2,dependencies没有赋值得操作不进行序列化,节省很多空间。
{
"name": "test",
"version": "1.0.0",
"dependencies": {
}
}
总结:
1.对于key得名称使用编号进行替代,一旦确定了顺序不可更改
2.对于value为空得不进行序列化
3.可变长度编码(数据压缩)
可变长度编码,主要缩减整数占用字节实现,例如java中int占用4个字节,但是大多数情况下,我们使用的数字都比较小,使用1个字节就够了,这就是可变长度编码完成的事
如果int是32位,也就是32位数组;如果第一个为1代表数据开始,下一个为0代表数据结束。
4.Tag_Length_Value 简称TLV
Tag表示后面数据的类型
类型 | 释义 | 备注 |
---|---|---|
0 | 可变长度编码 | int32 int64 uint32 uint64 sint32 sint64 bool enum |
1 | 64位长度 | fixed64 sfixed64 double |
2 | value 的长度 | string bytes message packed repeated fiels |
3 | Start Group | 废弃 |
4 | End Group | 废弃 |
5 | 32位长度 | fixed32 sfixed32 float |
length不一定有,依据Tag确定,例如int类型的数据就只有Tag-Value,string类型的数据就必须是Tag-Length-Value。
Value就是数据了
TLV表示数据时,减少分隔符的使用,更加紧凑。结构如下:
thrift
(1)是什么
thrift只支持thrift协议。
使用文本(text)和二进制(binary)传输协议, 为节约带宽,提供传输效率,一般情况下使用二进制类型的传输协议。
(2)优点
-
序列化后的体积小, 速度快
-
支持多种语言和丰富的数据类型
-
对于数据字段的增删具有较强的兼容性
-
支持二进制压缩编码
(3)缺点
-
使用者较少
-
跨防火墙访问时,不安全
-
不具有可读性,调试代码时相对困难
-
不能与其他传输层协议共同使用(例如HTTP)
-
无法支持向持久层直接读写数据,即不适合做数据持久化序列化协议
(4)适用场景
- 分布式系统的RPC解决方案
(5) 原理
json协议
通常我们传输得json格式如下。
"xxx": {
"xxlist": [
"strtest",
2,
"testlark",
"testkeyword"]
}
hession协议
用于将对象序列化为二进制数据的协议
通常用于 Java 应用程序间的通
xml得SOAP协议
这种应该是最熟悉得一种传输方式,占用空间很大。
个人感觉:xml会添加格外得一些信息,但是详细。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="xxx"></import>
<bean>
</bean>
</beans>
JAVA二进制协议
协议对比:
-
XML序列化(Xstream)无论在性能和简洁性上比较差。
-
Thrift与Protobuf相比在时空开销方面都有一定的劣势。
还剩下一部分,改天补充