前言
所谓的序列化解决方案,就是对象和二进制互相转换的解决方案。
为什么要采用二进制呢?这里有几个点要理解清楚。
1.应用程序里的数据是对象 2.网络传输的过程中一直是二进制 不管有没有进行对象和二进制互相转换,最终网络传输的都是二进制数据。 3.那为什么还要说进行对象和二进制的转换? 其实,这里的本质不在于转换,而在于双方的通信协议(也就是数据报文格式),必须采用二进制的数据报文协议才能够最大限度的减少数据报文的大小。所以,总结如下,序列化解决方案,就是采用二进制通信协议(数据报文格式)。
不同序列化解决方案对比
json和google区别?
有 Protocol buffer 这种轻便的序列化反序列化工具,Json 为什么还会大量使用?
当然json的格式清晰,但是数据量显然大于protocol buffer绝大多数情况下,JSON不是瓶颈,不需要替换或者优化。
中小公司切忌照抄Google的方案。
protobuf在文本为主的传输上并不会有很大的空间效率优化,带来的确是debug效率的下降。
跨语言的序列化方案
事实上的跨语言序列化方案只有三个: protobuf, thrift, json。json体积太大,并且缺少类型信息,实际上只用在RESTful接口上,并没有看到RPC框架会默认选json做序列化的。 国内一些大公司的使用情况:
protobuf ,腾迅,百度等
thrift,小米,美团等
hessian, 阿里用的是自己维护的版本,有js/cpp的实现,因为阿里主用java,更多是历史原因。
参考
序列化里的类型信息
序列化就是把对象转换为二进制数据,反序列化就把二进制数据转换为对象。
各种序列化库层出不穷,其中有一个重要的区别:类型信息存放在哪?
可以分为三种:
1、不保存类型信息典型的是各种json序列化库,优点是灵活,缺点是使用的双方都要知道类型是什么。当然有一些json库会提供一些扩展,偷偷把类型信息插入到json里。
2、类型信息保存到序列化结果里
比如java自带的序列化,hessian等。缺点是类型信息冗余。比如RPC里每一个request都要带上类型。因此有一种常见的RPC优化手段就是两端协商之后,后续的请求不需要再带上类型信息。
3、在生成代码里带上类型信息
通常是在IDL文件里写好package和类名,生成的代码直接就有了类型信息。比如protobuf, thrift。缺点是需要生成代码,双方都要知道IDL文件。
类型信息看起来是一个小事,但在安全上却会出大问题,后面会讨论。
参考
hessian
是什么
Binary RPC数据的解决方案。作用
1.转换数据类型 对象——二进制 2.RPC通信 也算是一个通信框架,和netty是一样的。 只不过,通信这一块,肯定没有netty做得好,只是说可以用它来通信而已。最大的优点
跨语言设计目标
- Introduction This document describes the portions of the Hessian 2.0 protocol concerning web services. The document is intended to be read by implementors of Hessian 2.0. Hessian 2.0 supports two types of network communication: remote procedure call (RPC) and message-based. These may also be viewed as synchronous and asynchronous communication.
RPC communication is based on "methods" invoked on a server. The method being invoked is specified in a Hessian 2.0 "call". Arguments to these methods are passed in the call and are serialized using the Hessian 2.0 serialization protocol. If the method was successfully invoked, the return value of the method is also serialized using Hessian 2.0 and sent to the client. If the method was not successfully invoked, a "fault" is returned to the client. RPC communication can use any underlying network protocol for transport such as HTTP or TCP.
Message-based communication is asynchronous and does not necessarily involve the use of methods, clients, or servers. Messages may or may not receive a response message. Messages simply contain other Hessian 2.0 objects. These may be simple types, aggregates like a list or map, or an "envelope". Envelopes may have headers that specify routing or other special processing information. They may also contain encrypted, signed, and/or compressed data. Thus using messages with envelopes can be useful in cases where end-to-end security is necessary. Message-based communication can also use any underlying network protocol such as HTTP or TCP and may be especially appropriate in queued message systems.
- Design Goals Unlike older binary protocols, Hessian is both self-describing, compact, and portable across languages. The wire protocol for web services should be invisible to application writers, it should not require external schema or IDL.
The Hessian protocol has the following design goals:
It must not require external IDL or schema definitions, i.e. the protocol should be invisible to application code. It must be language-independent. It must be simple so it can be effectively tested and implemented. It must be as fast as possible. It must be as compact as possible. It must support Unicode strings. It must support 8-bit binary data (i.e. without encoding or using attachments.) It must support encryption, compression, signature, and transaction context envelopes.
demo
通信方面
基于http协议。Hessian是比较常用的binary-rpc,性能较高,适合互联网应用,主要使用在普通的webservice 方法调用,交互数据较小的场景中。hessian的数据交互基于http协议,通常hessian的server端设计需要使用到web server容器(比如servlet等)。你可以将任何Java类暴露给HessianServlet,并发布成hessian服务;那么hessian client将可以通过类似调用servlet一样,获得远程方法的输出结果。
转换数据格式方面
基于java 序列化 API。dubbo使用hessian作为通信协议
参考
//官网//很好的入门文章
Dubbo-序列化解决方案
序列化在dubbo中所处的位置?
1.发送端 对象——二进制 2.接受端 二进制——对象序列化就是数据类型转换,把对象数据转换为二进制数据。
为什么要转换为二进制类型的数据?因为传输效率高。
剩下来的问题,就是哪一种解决方案,转换二进制是最快的?
1.google 开源软件 2.dubbo采用的hession 3.其他4.事实上,java本身也有官方jdk 序列化
只不过,有两个缺点,1.效率不高2.只支持javanetty通信框架在dubbo中所处的位置?
通信框架是在tcp/ip通信协议这一层。 是数据的流通。让数据流通起来。让数据可以在两个进程之间通过socket通信数据。hessian在dubbo里所处的位置?
首先,dubbo有两个方面值得重视 1.通信协议 2.转换数据格式通信协议,有几种方案
1.dubbo自定义协议 2.hessian自定义协议 //前面也多次讲到,hessian也是一个通信解决方案,和netty这个通信框架一样转换数据格式
通信协议是通信协议,通信协议只是定义了数据报文的格式而已。 在通信之前,还需要把对象转换为二进制数据,这个时候就需要转换对象为二进制数据的技术解决方案——hessian是其中的一种解决方案,也是dubbo通信协议默认的解决方案。除了hessian,google的protobuf也是解决同样问题的一种解决方案。就像google rpc默认用的是google 二进制序列化。dubbo默认是hessian二进制序列化。
dubbo-dubbo通信协议和hessian通信协议的区别?
最大的区别是应用场景的区别
1.dubbo 小数据 2.hessian 大数据为什么?一个小数据,一个大数据?
1.数据量 一个是基于tcp rpc API调用,适用于小数据量。一个是基于http,相当于是web服务器(内嵌jetty)。适用于页面请求这样比较大的数据,等等。
2.单一长连接?多连接 短连接?
一个是单一长连接,就是一个消费者只有一个连接,避免生产者承受太多连接(消耗资源),毕竟生产者机器数量比较少,消费者机器数量比较多。一个是多连接,既然是web服务器(jetty)嘛,就是每个请求都创建一个连接,http协议适合大数据,最小的数据请求就是一个页面,还有其他多媒体数据那就更大。
3.异步非阻塞?同步阻塞?
一个是基于netty java nio,异步非阻塞。一个是基于hessian http服务器(jetty),同步阻塞。
具体数量数据
参考官方文档解释说明
常见问题 1、为什么要消费者比提供者个数多? 因 dubbo 协议采用单一长连接,假设网络为千兆网卡 [3],根据测试经验数据每条连接最多只能压满 7MByte(不同的环境可能不一样,供参考),理论上 1 个服务提供者需要 20 个服务消费者才能压满网卡。解释:
-
7M字节,消费者和生产者的一个tcp连接,最多7M字节的数据。
-
千兆网卡(1000bit/10=100M,也就是说,实际只有100M字节)
100M/7M=约等于20 //意思就是,单个生产者的网卡,可以承担20个消费者的连接
下面的数据,计算方法类同!
2、为什么不能传大包?
因 dubbo 协议采用单一长连接,如果每次请求的数据包大小为 500KByte,假设网络为千兆网卡 [3:1],每条连接最大 7MByte(不同的环境可能不一样,供参考),单个服务提供者的 TPS(每秒处理事务数)最大为:128MByte / 500KByte = 262。单个消费者调用单个服务提供者的 TPS(每秒处理事务数)最大为:7MByte / 500KByte = 14。如果能接受,可以考虑使用,否则网络将成为瓶颈。3、为什么采用异步单一长连接?
因为服务的现状大都是服务提供者少,通常只有几台机器,而服务的消费者多,可能整个网站都在访问该服务,比如 Morgan 的提供者只有 6 台提供者,却有上百台消费者,每天有 1.5 亿次调用,如果采用常规的 hessian 服务,服务提供者很容易就被压跨,通过单一连接,保证单一消费者不会压死提供者,长连接,减少连接握手验证等,并使用异步 IO,复用线程池,防止 C10K 问题。参考
dubbo-通信协议
其实没啥。它就是基于: dubbo自定义通信协议——netty自定义通信协议——tcp协议。
也就是说,自己弄了一套协议(就是数据报文的格式)。
其他的也没啥不一样。