通信承载:有使用特定TCP/UDP之类的服务器,也有可以让用户自己开发定制的通信模型;还有使用HTTP或者消息队列这一类更加高级的传输协议
方案选型在我们确定了远程调用系统方案几个可行选择后,自然就要明确一下各个方案的优缺点,这样才能选择真正合适需求的设计:
1. 对于远程对象的描述:使用URL是互联网通行的标准,比较方便用户理解,也容易添加日后需要扩展到内容,因为URL本身是一个由多个部分组合的字符串;而名字服务则老式一些,但是依然有他的好处,就是名字服务可以附带负载均衡、容灾扩容、自定义路由等一系列特性,对于需求复杂的定位比较容易实现。
2. 远程调用的接口描述:如果只限制于某个语言、操作系统、平台上,直接利用“隐喻”方式的接口描述,或者以“注解”类型注释手段来标注源代码,实现远程调用接口的定义,是最方便不过的。但是,如果需要兼容编译型语言,如C/C++,就一定要用某种IDL来生成这些编译语言的源代码了。
3.通信承载:给用户自己定制通信模块,能提供最好的适用性,但是也让用户增加了使用的复杂程度。而HTTP/消息队列这种承载方式,在系统的部署、运维、编程上都会比较简单,缺点就是对于性能、传输特性的定制空间就比较小。
分析完核心问题,我们还需要考虑一些适用性场景:
1. 面向对象还是面向过程:如果我们只是考虑做面向过程的远程调用,只需要定位到“函数”即可。而如果是面向对象的,则需要定位到“对象”。由于函数是无状态的,所以其定位过程可以简单到一个名字即可,而对象则需要动态的查找到其ID或句柄。
2.跨语言还是单一语言:单一语言的方案中,头文件或接口定义完全用一种语言处理即可,如果是跨语言的,就少不免要IDL
3. 混合式通信承载还是使用HTTP服务器承载:混合式承载可能可以用到TCP/UDP/共享内存等底层技术,可以提供最优的性能,但是使用起来必然非常麻烦。使用HTTP服务器的话,则非常简单,因为WWW服务的开源软件、库众多,而且客户端使用浏览器或者一些JS页面即可调试,缺点是其性能较低。
假设我们现在要为某种业务逻辑非常多变的领域,如企业业务应用领域,或游戏服务器端领域,去设计一个远程调用系统,我们可能应该如下选择:
1. 使用名字服务定位远程对象:由于企业服务是需要高可用性的,使用名字服务能在查询名字时识别和选择可用性服务对象。J2EE方案中的EJB(企业JavaBean)就是用名字服务的。
2. 使用IDL来生成接口定义:由于企业服务或游戏服务,其开发语言可能不是统一的,又或者需要高性能的编程语言如C/C++,所以只能使用IDL。
3.使用混合式通信承载:虽然企业服务看起来无需在很复杂的网络下运行,但是不同的企业的网络环境又可能是千差万别的,所以要做一个通用的系统,最好还是不怕麻烦提供混合式的通信承载,这样可以在TCP/UDP等各种协议中选择。