您的位置:首页 > 理论基础 > 计算机网络

大型分布式网站架构设计与实践 第一章《面向服务的体系架构(SOA)》1.1基于TCP协议的RPC

2015-11-23 23:06 1276 查看
1.1基于TCP协议的RPC

1.1.1RPC名词理解

RPC的全称是Remote Process Call,即远程过程调用,它应用广泛,实现方式也很多,拥有RMI,WebService等诸多成熟的方案,在业界得到了广泛的应用。单台服务器的处理能力受硬件成本的限制,不可能无限制的提升,RPC将原来的本地调用转变为调用远端的服务器上的方法,给系统的处理能力和吞吐量带来了近乎无限制的提升,这是系统发展到一定阶段必然性的改革,也是实现分布式计算的基础。

如图1-2所示,RPC的实现包括客户端和服务端,即服务的调用方和服务的提供方,服务调用方发送RPC请求到服务提供方,服务提供方根据服务调用方提供的参数执行请求方法,将执行结果返回给调用方,一次RPC调用完成。关于调用方发起请求及服务提供方执行完请求的方法后返回结果的过程,和所涉及的调用参数及响应结果的序列号和反序列化操作,下节将详细介绍。

随着业务的发展,服务调用者的规模发展到一定的阶段,对服务提供方的压力也日益增加,因此,服务需要扩容,而随着服务提供者的增加和业务的发展,不同的服务之间还需要进行分组,以隔离不同的业务,避免相互影响,在这种情况下,服务的路由和负载均衡则成为必须要考虑的问题。如图1-3所示。

服务消费者通过获取服务提供者的分组信息和地址信息进行路由,如果一个服务提供者为一个集群而非单台机器,则需要根据负载均衡的策略,选择其中的一台调用,有关服务的路由和负载均衡,后续章节会详细介绍,此处不再赘述。

1.1.2对象的序列化

无论是何种数据类型的数据,最终都需要转换成二进制流在网络上进行传输,那么在面向对象程序设计中,如何将一个定义好的对象传输到远端呢?数据的发送方需要将对象转换成二进制流,才能在网络上进行传输,而数据的接收方需要把二进制流再恢复为对象。

将对象转换为二进制流的过程,叫做对象的序列化。
将二进制流恢复为对象的过程,叫做对象的反序列化。

对象的序列化和反序列化有多种成熟的解决方案,较为常用的有Google的Protocal Buffers、java 本身内置的序列化方式、Hessian,以及后面要介绍的JSON 和XML等,它们各有各的使用场景和优\缺点。图1-4所展示的是使用各种序列化方案将一个对象序列化为一个网络可传输的字节数组,然后再反序列化为一个对象的时间的性能对比。

Google 的 Protocol Buffers 真正开源的时间并不长,但是其性能优异,在短时间内引起了广泛的关注,其优势是性能十分优异,支持跨平台,但使用其编程代码侵入性较强,需要编写proto文件,无法直接使用java等面向对象编程语言的对象,相对于 Protocol Buffers,Hessian 的效率稍低,但是其对各种编程语言有着良好的支持,且性能稳定,比java本身内置的序列化方式效率要高很多,java内置的序列化方式不需要引入第三方包,使用简单,在对效率要求不是很敏感的场景下,也未尝不是一个好的选择,而后面章节要介绍的
JSON 和 XML 格式,在互联网领域,尤其是现在流行的移动互联网领域,得益于其跨平台的特性,得到了极为广泛的应用。

本节重点介绍 java 内置的序列化方式和基于 java 的 Hessian 序列化方式,并用代码演示具体实施方法。

以下是 java 内置的序列化方式和实现反序列化的关键代码:

//定义一个字节数组输出流

ByteArrayOutputStream os = new ByteArrayOutputStream();

//对象输出流

ObjectOutputStream out = new ObjectOutputStream(os);

//将对象写入字节数组输出,进行序列化

out.writeObject(zhansan);

byte[] zhanByte = os.toByteArray();

//定义一个字节数组输入流

ByteArrayInputStream is = new ByteArrayInputStream();

//执行反序列化,从流中读取对象

ObjectInputStream in = new ObjectInputStream(is);

Person person = (Person)in.readObject();

通过 java.io 包下的 ObjectOutputStream 的 writeObject 方法,将 Person 类的实例 zhansan 序列化为字节数组,然后通过 ObjectInputStream 的 readObject 方法将字节数组反序列化为 Person 对象。

使用 Hessian 进行序列化,需要引入其提供的二方包 hessian-4.0.7.jar ,针对基于 java 的 Hessian 序列化和反序列化的实现,关键代码如下:

//定义一个字节数组输出流

ByteArrayOutputStream os = new ByteArrayOutputStream();

// Hessian 序列化输出

HessianOutput ho = new HessianOutput(os);

ho.writeObject(zhansan);

byte[] zhansanByte = os.toByteArray();

//定义一个字节数组输入流

ByteArrayInputStream is = new ByteArrayInputStream();

// Hessian 反序列化读取对象

HessianIput hi = new HessianInput(is);

Person person = (Person)hi.readObject();

通过 com.aucho.hessian.io 包下的 HessianOutput 的 writeObject 方法将 Person 的实例 zhansan 序列化为字节数组,然后再通过 HessianInput 的 readObject 方法将字节数组进行反序列化还原为对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: