文档章节

RSF 分布式服务框架设计

哈库纳
 哈库纳
发布于 2014/09/21 14:26
字数 2286
阅读 16566
收藏 139

    是时候设计一个分布式服务框架了。我先将它定名为 Hasor-RSF,“RSF”为 Remote Service Framework 的缩写。

    RSF的目的是为了提供一种高效的远程服务访问方式,例如“A机器访问在B机器上的一个服务”。当然首先它是运行在Java上的,但是我并不希望 Java 成为 RSF的唯一平台。

    它应该是分布式的,就是说服务 A 可能会分布在若干台机器内。 当我的应用打算调用这个服务时我应该可以在这若干服务提供的机器上随机调用。这样做的好处是有助于高并发、高访问、高可用。


    RSF 的本质其实就是 RPC 那么我们可以先对比一下 RPC 里都有什么可以被我们拿来选用。下面列出来的只是其中一些我相信聪明的朋友们会列举出更多的解决方案,我也敢保证你们知道的比我还多。

  1. Java原生的 RMI。
  2. Hessian
  3. WebServices
  4. Restful
  5. HTTP Request
  6. RTMP/AMF
  7. 淘宝的 HSF、Dubbo

    RMI,这个 Java 原生的东东似乎从一开始就没有被人们所看好,究其原因是速度太慢。但是它的好处是Java原生,使用 RMI 不需要引入其它任何第三方软件包。不过挑剔的同学们似乎不太看好这个优点。

    Hessian,原则上说Hessian我并不认为它是一个远程服务框架范畴的东西。我更觉得 Hessian 是一种数据交互格式。就像是 JSON,XML-RPC,AMF,Kryo 一类的东西。Hessian 的优点是大量的兼容平台例如:“IOS、Java、.net、C++、Python、Flash、Ruby、PHP”,其次它的第二个有点是二进制格式。在大对象序列化上会占有很大的优势。

    WebServices,一个老牌技术解决方案。在我印象中 WebServices 是跟随着 SOA 这个东西一起出名的,他有一个最大的好处是防火墙穿透。毕竟人家是靠 80 端口吃饭的,牛叉的很。不过话说回来WebServices的最大要害就是,Xml传输格式。把一个对象序列化成为一个Xml数据是一件很容易的事,但是反序列化成本似乎是很高。再加上 SOAP 协议本身是建立在 XML 形式上,这就使得 Web Service 奇慢无比了。当然因素还有很多我就不多说了。

    Restful,其实 restful 我更觉得它是一种 API 表述规范。但在社区论坛中讨论看来,restful 的应用似乎也延伸到远程服务的领域。所以有必要说明一下。restful 最初是出现在 web 上,究其本质是还是 HTTP。例如对于:“http://xxxxx/xxxx”这个资源的访问可以利用 HTTP 的“GET、PUT、DELETE”等方法对资源操作加以描述说明。我个人觉得这东西用在 RPC 上并不合适。

    HTTP,这是我用过最多的一种远程交互方式。远离很见dna,服务发布者将服务发布成为一个http资源。调用者请求这个http资源。数据传输格式完全程序双方自行协商。这种方法简单除暴行之有效。不过缺点是我们要自己补充通信协议,例如请求参数和响应数据格式。常规的交互格式有 JSON、XML。

    RTMP/AMF,这个组合的确是一套很完善的远程调用解决方案。RTMP协议中专门为 Invoke 开辟了一条通道,在配合 AMF 格式极大的方便了 Flash 下远程服务访问。不过这些都是 Flash下的东西,即使是拥有 Red5 这样的神器让我们在 java 下可以使用 rtmp 但是究其目的还是为了和 flash 通信。一般 flash 调用业务系统的方式还都停留在 http 请求或者通过 red5 服务器代为转发。

    HSF,这个东西是淘宝内部用的很广泛的远程服务框架。它是使用NIO、Mina 并且工作在长连接模式下。话说这个东西的确是个好东西,淘宝也将其开源了!只可惜,开源了 hsf 但是相关配套依赖没有开源。在加上 hsf 依赖繁杂。这个东西也就只能让局外人膜拜一下,在淘系之外的同学们是无福享受了。

    Dubbo,也是淘系的另外一个服务框架,它比较 HSF 来说要轻巧很多。依赖会少一些,这个东东目前也是开源状态。由于我对 dubbo 一点都不了解,在这里保持沉默不做评价。

    最后补充一下,真正原生就支持分布式服务调用的也就只有“HSF、Dubbo”至于京东内部是否有更好的解决方案我并不知道。哦还有一点,如果您想脱离 Spring 的话 HSF、Dubbo 会让你失望的。这就是说您的技术构架如果是非 Spring 阵营的会比较悲催。

    so,上面提到了很多可用的技术方案,想必最后符合要求也就只有其中 HSF 和 Dubbo 了。为什么其它的方案都不入选呢?原因就是它们虽然可以完成 RPC 但是并不支持分布式。当然您可以通过架设集群来提高它们的可靠性,这些都是您需要额外付出的。

------------------------------

    下面这个是 RSF 的架构图,包括服务生产着和消费者在内 RSF 被分为 6 层(网络层、协议层、请求响应层、调度层、接口层、消费者生产)。

关键5层:

    Netty,其中位于最下层的网通信部分 RSF 采用 Netty 实现。Netty 是一款非常优秀的网络通信框架,使用 Netty 可以帮助 RSF 减少大量底层网络上的代码开发。这也就意味着 RSF 将采用 Selector 方式实现异步IO。

    Protocol,协议层。该层主要的目的是负责解释翻译 RSF 数据包,并将 RSF 数据包转意成为 Request 和 Response 对象。协议层可以是一个协议栈,这就意味您可以通过 RTMP 、或者其它自定义网络协议传输 RSF 数据包。

    Request/Response层,请求响应层。这个在这个层中,RSF 脱离了底层网络方面的特性将每次调用请求对象化为一个 Request 对象,并且将调用结果封装成为一个 Response 对象。这种编程模式和 Web 很像。

    调度层,这一层最为复杂。它负责管理本地 RSF 服务的注册,远程传输对象序列化方式的管理,并且还要负责实现其它更加复杂的功能。

    接口层,这一层是最终 RSF 暴露给业务系统的接口,将会由两个类提供。一个代表服务生产着,另一个是服务消费者。

序列化格式:

    RSF 规定在网络中传输的数据格式可以是任意的。这就意味着您可以使用 AMF 作为 RSF 数据传输格式发布(同时如果协议层支持 RTMP 那您可以在 Flash 中无需通过 red5 这样的中间代理直接访问 RSF 服务)。同样的,如果您使用 Hessian 作为数据传输格式,在其它平台。例如 .net、php。也会很方便的调用 RSF 服务(需要解析 RSF 数据包)。如果协议采用 HTTP,RSF序列化格式采用 JSON ,那么运行在浏览器中的 javascript 也可以绕过 web 服务器,直接访问 RSF 服务。

服务配置Config:

    说是服务配置,其实就是路由的功能。先假设我们有4台服务器,其中有两台是位于北京机房,另外两台分别位于青岛和内蒙古。这四台机器上都运行着 RSF,跑着相同的业务系统,这种架构通常前端会有一个 CDN 之类的东西负责让用户就近访问网站。

    如果没有服务路由的情况下,用户A在北京即使访问了最近的北京服务器,但是由于调用的 RDS 服务是青岛的,那么也会降低访问速度。因此服务配置所负责的 路由特性可以很方便的高速服务调用程序,优先选用北京机房的 RSF 服务。只有当北京机房的服务撑不住的情况下才会动用其它地域的 RSF 服务。

    流量管控高级一点的特性是可以通过服务路由来控制服务流量。假如目前要做一个全国范围的活动,我们充分的为每个地方准备了若干机器。但是在活动现场很可能某一个地区的服务使用量达到了临界点,服务路由应该可以通过配置的方式让附近地区的机器提供一定的流量来减缓这个地区的访问压力。


© 著作权归作者所有

哈库纳

哈库纳

粉丝 960
博文 84
码字总数 151810
作品 4
杭州
后端工程师
私信 提问
加载中

评论(25)

笨笨的阿星
大神 厉害啊 虽然不懂什么意思 但看到大家的评论还是很厉害的样子
dhmj2ee
dhmj2ee
还有一种,LinkedIn公司开源的Norbert,采用Netty+Protobuf+Zookeeper
金贞花
金贞花

引用来自“Grrrr”的评论

感觉和楼主走了同样的道路。

我曾尝试用Restful搭建集群服务,开始会很爽,基于http status code,再加上http本身无状态,非常容易扩展。后来发现性能还是不行,毕竟是http。

然后我又用Zero Ice搭建集群,这玩意就是搭建电信级集群服务的。开始又是很爽,但是发现一旦出了问题,或者需要一些额外的功能,简直就是登天啊,2000+页的文档直接看死。。。

最终我又回到了最初的起点:Netty + Protocol Buffer

我想建议楼主的是:关于调度层,水太深了,可以被设计的无限复杂,我现在已经放弃了这一层的设计,用一些成熟的产品来替代,比如Zookeeper, HAproxy

把你的经验发个博文好吗
金贞花
金贞花

引用来自“哈库纳”的评论

引用来自“hya1985”的评论

其实dubbo基本很成熟了,调度层,服务治理,基本主流的都用Zookeeper了,毕竟自己控制,肯定有许多需要完善的地方,好友JD貌似是基于dubbo的二次开发
dubbo 是个明星。 如果要稳定优先肯定是首选。 自己写一个一方面可以摸一摸这里面到底有多深,另一方面也锻炼一下。

9494
i
i仅此而已
持续关注楼主的作品哈!!!
哈库纳
哈库纳

引用来自“hya1985”的评论

其实dubbo基本很成熟了,调度层,服务治理,基本主流的都用Zookeeper了,毕竟自己控制,肯定有许多需要完善的地方,好友JD貌似是基于dubbo的二次开发

分享一个刚得到的消息,据说在阿里 dubbo 目前已经死掉了,阿里全线在推广使用 hsf。
哈库纳
哈库纳

引用来自“hya1985”的评论

其实dubbo基本很成熟了,调度层,服务治理,基本主流的都用Zookeeper了,毕竟自己控制,肯定有许多需要完善的地方,好友JD貌似是基于dubbo的二次开发
dubbo 是个明星。 如果要稳定优先肯定是首选。 自己写一个一方面可以摸一摸这里面到底有多深,另一方面也锻炼一下。
hya1985
hya1985
其实dubbo基本很成熟了,调度层,服务治理,基本主流的都用Zookeeper了,毕竟自己控制,肯定有许多需要完善的地方,好友JD貌似是基于dubbo的二次开发
哈库纳
哈库纳

引用来自“july”的评论

79
静待后续佳作 113
肯定会有的,不过要先把手头的活干完才能接着写 blog。
哈库纳
哈库纳

引用来自“12叔”的评论

到底要用啥
还没最终决定 Hessian、Netty 这两个目前是必选的了。
RSF 分布式 RPC 服务框架的分层设计

RSF 是个什么东西? 一个高可用、高性能、轻量级的分布式服务框架。支持容灾、负载均衡、集群。一个典型的应用场景是,将同一个服务部署在多个Server上提供 request、response 消息通知。使用...

哈库纳
2016/10/28
2.5K
4
RSF-Center,集群模式下-协调数据结构

RSF是一个轻量化的分布式服务框架。支持点对点调用,也支持分布式调用。典型的应用场景是,将同一个服务部署在多个Server上提供 request、response 消息通知。它的设计思想是:通过Netty实现...

哈库纳
2016/02/05
431
2
分布式服务框架 RSF 1.1.0 ,新增网关和 Bug 修复

分布式服务框架 RSF 1.1.0 发布了。 更新日志 一个高可用、高性能、轻量级的分布式服务框架。支持容灾、负载均衡、集群。一个典型的应用场景是,将同一个服务部署在多个Server上提供 reques...

哈库纳
2016/12/01
2K
11
RSF 1.0.1 分布式服务框架,新增 Spring/JFinal 支持

RSF 1.0.1 分布式服务框架,新增 Spring/JFinal 支持。 Hasor-RSF是一个高可用、高性能、轻量级的分布式服务框架。支持容灾、负载均衡、集群。一个典型的应用场景是,将同一个服务部署在多个...

哈库纳
2016/11/08
2.2K
8
服务框架 RSF 1.2.0 发布,新增多协议&跨语言支持

服务框架 RSF 1.2.0 发布,本地发布最大亮点在于新增了:多协议、跨语言的特性。语言方面大约涵盖了大约 25种语言。 在原有 RSF RPC 协议下,通过与 Hprose 进行合作新增了 Hprose HTTP协议 ...

哈库纳
2017/02/03
823
4

没有更多内容

加载失败,请刷新页面

加载更多

面试爱奇艺,竟然挂在第5轮……

今天给大家分享我曾经在爱奇艺的面试,过程还是比较有意思的,可以给大家一些参考 <br> 聊骚阶段 嗲妹妹:你好,我是爱奇艺的HR,我们正在招聘运维开发岗位,请问您最近有在看工作机会吗? ...

上海小胖
今天
5
0
Jenkins系列_插件安装及报错处理

进入Jenkins之后我们可以进行插件的安装,插件管理位于以下模块: 发现上面报了一堆错误,是因为插件的依赖没有安装好,那么这一节,就先把这些错误解决掉吧。解决完成后,也就基本会使用插件...

shzwork
今天
2
0
mysql mysql的所有查询语句和聚合函数(整理一下,忘记了可以随时看看)

查询所有字段 select * from 表名; 查询自定字段 select 字段名 from 表名; 查询指定数据 select * from 表名 where 条件; 带关键字IN的查询 select * from 表名 where 条件 [not] in(元素...

edison_kwok
昨天
9
0
解决多线程并行加载缓存问题(利用guava实现)

依赖 com.google.guava:guava:20.0 import com.google.common.cache.Cache;import com.google.common.cache.CacheBuilder;import java.util.concurrent.ExecutionException;import j......

暗中观察
昨天
4
0
利用VisualVM 内存查看

准备工作,建几个测试类。等下就是要查看这几个类里面的属性 package visualvm;public class MultiObject { private String str; private int i; MultiObject(String str...

冷基
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部