远程方法调用的实现方案研究

2016-02-06 05:44赖歆
电脑与电信 2016年11期
关键词:序列化网络通信调用

赖歆

(福富软件,福建 福州 350003)

远程方法调用的实现方案研究

赖歆

(福富软件,福建 福州 350003)

针对分布式系统需要通过网络来表达调用的语义和传达调用的数据而会遇到的问题,本文对此问题展开探讨,首先对跨机间的远程调用进行分析,其次从通讯、编码解码进行研究,最后了提出具体的解决方案。

远程方法;通讯;序列化

1 引言

分布式系统并不像单机系统可以直接通过本地调用,其基本上由大大小小的服务组成,并且各种服务通常会被部署在不同的机器上。由于各种服务不在同一个内存空间,因此不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。这时就会遇到两个问题:

(1)要搭建一个新服务,需要依赖远程的服务,如何才能调用远程服务?

(2)远程访问如何才能满足高效的性能要求?下文我们将对这两个问题展开探讨。

2 实现远程服务调用

由于各服务部署在不同机器,服务消费方调用一个服务就要编写一堆网络通信相关的代码,不仅复杂而且极易出错。

我们需要一种能像调用本地服务一样调用远程服务的方式,让网络通信中的细节对调用者透明,这样将大大简化工作,提高编码效率,这种方式就是RPC(Remote Procedure Call Protocol)。RPC调用的流程如图1所示:

图1 RPC调用流程图

RPC的目标是将这些步骤都封装起来,让整体的过程细节对使用者变得透明。

2.1 实现透明化远程服务调用

通过JAVA的动态代理技术封装通信细节,让用户以类似本地调用的方式调用远程服务。代理类通过调用被代理类的相关方法,提供预处理、过滤、事后处理等服务,可以使用JDK中的java.lang.reflect.Proxy类来实现动态代理。

下面简单介绍用动态代理进行封装的示例。调用者先从RPCProxyClient获得服务提供方的接口,当执行helloServ. hello()方法时会调用Invoke方法,在代理类的Invoke方法中封装与远端服务通信的细节。

/**定义接口并实现方法,它存在于远端*/

public interface IHello{

void hello();

}

public class Hello implements IHello{

@Override

public String hello(){

System.out.println("Hello.");

return"Hello.";

}

}

/**通过动态代理封装屏蔽通信细节*/

public class RPCProxyClient implements java.lang.reflect. InvocationHandler{

private Object obj;

public RPCProxyClient(Object obj){

this.obj=obj;

}

public static Object getProxy(Object obj){

return java.lang.reflect.Proxy.newProxyInstance(obj. getClass().getClassLoader(),

obj.getClass().getInterfaces(),new RPCProxy-Client(obj));

}

public Object invoke(Object proxy,Method method, Object[]args)

throws Throwable{

//结果参数;

Object result=new Object();

//...实现远程间通信的相关逻辑

//...

return result;

}

}

/**调用示例*/

public class Test{

public static void main(String[]args){

IHello helloServ=(hello)RPCProxyClient.getProxy (IHello.class);

helloServ.hello();

}

}

2.2 实现消息的编码解码

在Invoke对通信细节进行封装,第一步要确定客户端和服务端相互通信的消息结构。一般需要包括几个主要的信息:

(1)接口名称:用于服务端确定调用哪个接口,如上面例子里接口名是“IHello”。

(2)方法名:用于服务端确定调用哪个方法(一个接口内可以有多个方法),上面例子里是“hello”。

(3)参数类型&参数值。

(4)唯一请求标识:远程调用可能是同步的,也可能是异步的,当设计工作在异步方式时,需要唯一请求标识来明确具体的事务。

(5)返回值。

确定了消息的数据结构后,下一步要考虑序列化与反序列化,以便于将数据结构或对象转换为二进制串后进行网络传输,以及从网络接收后将二进制转换回对象进行后续业务逻辑处理。

序列化/反序列化的方案很多,每种序列化方案都有优点和缺点,从远程调用的角度上看,主要看三点:(1)通用性,比如是否能支持Map等复杂的数据结构;(2)性能,包括时间复杂度和空间复杂度;(3)可扩展性,如果序列化协议具有良好的可扩展性,支持自动增加新的业务字段,删除老的字段,而不影响老的服务,这将大大提供系统的健壮性。

可以根据需要选择互联网广泛使用的hessian、protobuf、avro等成熟的序列化解决方案来搭建。

2.3 实现网络通信

消息数据结构被序列化为二进制串后,接下来要实现网络通信。网络通信的实现主要有以下几种:

(1)同步阻塞(即早期的IO操作):在此种方式下,用户进程在发起一个IO操作以后,必须等待IO操作的完成,只有当真正完成了IO操作以后,用户进程才能运行。JAVA传统的IO模型属于此种方式,适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中。

(2)同步非阻塞(NIO):在此种方式下,用户进程发起一个IO操作以后边可返回做其它事情,但是用户进程需要定时去询问IO操作是否就绪,从而引入不必要的CPU资源浪费。在JDK 1.4开始支持此种方式,适用于连接数目多且连接比较短(轻操作)的架构,并发局限于应用中。

(3)异步(AIO):此种方式是指应用发起一个IO操作以后,不等待内核IO操作的完成,等内核完成IO操作以后会通知应用程序。在JDK1.7开支持该方式,适用于连接数目多且连接比较长(重操作)的架构,充分调用OS参与并发操作。

3 性能验证

接下来对几种通信框架gRPC、Java RMI、Netty进行性能验证,验证环境的主要配置参数见表1:

表1 验证环境的主要配置参数

验证过程:

(1)编写验证程序在2台主机间调用,1次调用算为1次事务。

(2)逐步加大线程数测试多线程并发的性能增长曲线,测试单线程处理多通道的性能增长能力,测试不同长度数据下的性能数据变化规律,统计发送时间和对应返回接收时间的时间差作为延迟时间。

(3)观察运行稳定后,收集不同场景下的性能数据。

表2 几种通信架构的性能验证

Netty集群极限性能较高,扩展能力较好,资源利用率较高,适用于异步处理大量通道并发的业务场景;gRPC在ProtoBuf序列化协议使用上受到一定的限制,采用http2的网络利用率较低;RMI的扩展能力较差,通道复用能力较差,且跨语言调用能力较弱。

4 结束语

本文对远程调用场景进行分析,通过实现调用透明化、编码解码、网络通信形成远程方法调用的方案,描述方案适用的场景。通过方案原型的测试验证,更深入地说明方案的特点,实际使用中可根据不同的场景需要,分别采用不同的方案。

[1]周筱瑜,雷晓俊,陈芳.分布式系统中的通信方式:R PC与R M I [J].电脑与电信,2 0 12(3):3 6-3 9.

[2]刘绪崇,张悦,钟情花.分布式多用户远程控制与密取系统设计与实现[J].警察技术,2 0 15(6):3 6-3 9.

The Realization of Remote Method Invocation

Lai Xin
(FFCS,Fuzhou 350003,Fujian)

In view of the problem that the distributed system needs to express the semantics of the invocation and communicate the data of the invocation through the network,this paper firstly analyzes the remote invocation across machines;and then researches on the communication,encoding and decoding;and finally puts forward the specific solutions.

remote method;communications;serialize

TP311.52

A

1008-6609(2016)11-0068-03

赖歆(19 79-),男,福建人,系统架构工程师,研究方向为电信信息化。

猜你喜欢
序列化网络通信调用
基于FlatBuffers的机车通信数据序列化方法应用研究
如何建构序列化阅读教学
核电项目物项调用管理的应用研究
基于网络通信的智能照明系统设计
网络通信中信息隐藏技术的应用
基于网络通信的校园智能音箱设计
谈计算机网络通信常见问题及技术发展
基于系统调用的恶意软件检测技术研究
Java 反序列化漏洞研究
作文训练微格化、序列化初探