# cubelink **Repository Path**: jfire/cubelink ## Basic Information - **Project Name**: cubelink - **Description**: 以Dubbo2.0和JSF为功能蓝图的SOA框架。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2017-08-23 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # cubelink概要设计 --- [TOC] ## 1. 撰写记录 |更新时间|内容|作者| |---|---|---| |2017-08-23 08:39:31|撰写参数回调章节内容|林斌| |2017-08-22 21:26:52|增加了异步响应和异步回调章节|林斌| |2017-08-22 14:36:36|确定文档结构和大致框架|林斌| ## 2. 设计目标 1. 设计一个具备治理,监控,服务发现能力的RPC框架 2. 框架支持同步、异步调用;支持回调 ## 3. 架构设计 ### 3.1 注册、发现 大体上来说是依靠注册中心实现注册和发现机制。架构如下 ![mark](http://olcswa2uq.bkt.clouddn.com/mk/20170823/104704586.png) 链接均采用长连接方式。注册中心会监控服务端的健康状态。并且在发生变化时,实时推送实例状态到客户端。 ### 3.2 客户端架构 客户端的主要架构如下 ![mark](http://olcswa2uq.bkt.clouddn.com/mk/20170823/104716684.png) TCP的双工特点使得实际上客户端的消息写出和消息收取可以并行。但是由于大多数RPC调用是同步的,因为需要一个同步/异步转换层在中间,满足接口调用的特性。 ### 3.3 服务端架构 服务端主要架构如下 ![mark](http://olcswa2uq.bkt.clouddn.com/mk/20170823/104724436.png) ## 4. 技术要点 ### 4.1 服务端注册服务方式 从服务端的实现角度来说, ### 4.1 接口定位 服务端可以在一个监听端口上暴露多个接口服务。那么调用的时候首先需要明确的就是调用的哪一个接口。 ### 4.2 方法定位 客户端使用接口调用,如何在服务端这一侧定位对应的调用方法。为了节省传输数据,客户端和服务端可以通过一种方式约定每一个方法的数字序号。这样只需要传递数字序号即可定位调用的方法。 排序方式的方式为方法的字符串签名进行字母自然排序。序号从0开始递增。 ### 4.3 多线程共享TCP通道 多个线程如果需要共享TCP通道,那么就需要通过请求序号的方式来区别不同的线程收到的响应。具体做法如下 1. 客户端发出请求的报文中携带一个客户端全局唯一的序号。 2. 服务端处理完业务请求后将响应和序号一起发回 3. 客户端依靠响应中的序号将响应给予对应的等待线程(如果有的话)。 ### 4.4 异步响应 底层的传输层框架本身就是支持异步的客户端。因此异步响应的支持本身实际上只需要在底层客户端的基础之上,引入一个异步响应的future实现类即可。 异步响应本身不需要修改API,可以只是在客户端配置该方法为异步响应。此时通过上下文之类的方式获得一个响应的future。调用方式类似 ```java // 此调用会立即返回null fooService.findFoo(fooId); // 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future。 Future fooFuture = RpcContext.getContext().getFuture(); ``` ### 4.4 参数回调 参数回调的效果是让客户端传递了一个调用行为到服务端。而这个调用行为的效果是发生在客户端本地的,所使用到的资源也在客户端本地。比较容易实现而且也实践较多的做法是定义一个只有一个方法且该方法没有返回值的接口。 接着的问题就是如何传递这个接口的实现。上面说到这个回调行为是发生在客户端本地的,因此传递一个接口的对象实现到服务端是没有意义的。因此只需要传递一个代表这个回调接口的标识过去即可。