为什么80%的码农都做不了架构师?>>>   

RSF 的线程模型

使用了 RSF 框架之后系统一共会产生至少 7 条线程,有些功能的线程可能会产生多个。我们先来鸟瞰一下所有的线程和它们的大致功能。

初一看,还真是挺复杂的,这么多线程,这么多功能。根据重要程度大致可以分为这么两类。

主要线程:监听线程、定时器线程、网络IO线程、RPC调用线程
    次要线程:地址本备份线程、Telnet线程、Hasor事件异步处理线程

其中主要线程中可以进一步在分为核心线程和重要线程。它们是:

核心线程:监听线程、网络IO线程、RPC调用线程。
    重要线程:定时器线程。

核心线程

现在我们就从最最重要的核心线程说起,然后在谈一谈同样重要的定时器线程。先看一张图直观的感受一下 RSF 的线程模型。

网络部分(RSF-Nio):

在 RSF 中 监听线程 的作用就是接受 远程计算机的连接请求,并负责创建 Socket 通信通道。因为 RSF 采用了长链接双向通信的工作模式。因此一般两台计算机在顺利链接上之后短时间内不会关闭彼此的链接。因此一般情况下 1 条线程足以应付。

其次就是 RSF 的 网络IO线程 这个线程的主要目的是负责处理网络 IO 的读写操作。可以说 网络IO线程 处理了所有 RSF 网络相关数据的传输操作。

监听线程 和 IO 线程是由 Netty 的“io.netty.channel.nio.NioEventLoopGroup”类提供支持。下面是 RSF 中框架启动的代码节选,图中红框部分就是 监听线程和网络IO线程的使用。 它和一般情况下 Netty 启动 TCP 监听的方式是一样的。这段代码位于“net.hasor.rsf.rpc.net.RsfNetManager”类的“start”方法中。有兴趣的同学可以去看一看 RSF 的网络启动过程。

Server 在启动之后开始源源不断的从网络上异步的接受 RSF request 请求。然后再把接收到的网络数据经过协议层转换为 RsfRequest 对象,然后在丢入RPC队列。最后交给 RPC 调用线程去处理。

“net.hasor.rsf.rpc.net.RpcCodec”类就是负责接收 RSF 网络数据然后通过“net.hasor.rsf.rpc.net.ReceivedListener”接口送到队列中。下面红框部分就是实现消息接收并通过“ReceivedListener”接口丢入队列的代码。

上面代码中的 shakeHands 表示通信是否已经通过握手。有关 RSF 握手协议在后面我会在专门的 Blog 文章中进行讲解。

最后在“net.hasor.rsf.rpc.caller.remote.RemoteRsfCaller”类中 RSF 会负责接收“ReceivedListener”接口丢过来的 Request对象并放入队列。

这里把“ReceivedListener”接口设计成中转站的目的是是为了实现“网络通信层”和“RPC调用层”之间的解耦。最后整体架构上就会变成我们预想的样子。

RPC调用部分(RSF-Biz)

在上面网络部分,我们已经知道网络 IO 线程的工作原理,现在我们在来看看负责处理RPC调用部分的 work 线程是如何工作的。

首先这里的 work 指的不是 Netty 层面上的 Work 线程。Netty 层面上的 Work 线程对应的是我们刚刚讨论的 网络 IO 线程(RSF-Nio)。我们这里即将讨论的 work 线程是专门用来处理 RPC 调用的线程(RSF-Biz)。

RSF-Biz 的线程入口类是“net.hasor.rsf.rpc.caller.remote.RemoteRsfCallerProcessing”,每当网络 IO 线程收到 Request 之后都会创建一个“RemoteRsfCallerProcessing”对象并将这个对象扔到“Executor”里面,具体为 java 自带的并发框架“java.util.concurrent.Executor”。

由于“Executor”是一个有序的队列。因此在真正执行“RemoteRsfCallerProcessing”的时候,我们并不知道这个Rsf Request从进入队列到它执行期间一共等待了多久。因此在“RemoteRsfCallerProcessing”正式处理调用之前先要做的就是判断是否超时、要调用的服务是否存在等等检测,最后执行“Method.invoke” 执行调用。返回结果。

为了简单的说明 RSF “RemoteRsfCallerProcessing”都做了哪些事我把代码的执行流程简要列一下:

  1. 正确性检验
  2. 检查timeout
  3. 准备参数
  4. 执行调用
  5. 将Response写入客户端

其中正确性校验会检查本地是否注册 RsfBindInfo,如果有注册是否为服务提供者(Provider)。而 timeout 检测会判断当前时间和数据包接收时间之间是否超过规定时间,如果超过规定时间也放弃不在执行。

这里最有必要说一下的就是“准备参数”这个环节,在 RSF 中参数的反序列化和参数个数校验都在这里进行。换句话说 RSF 的 IO线程并不负责处理序列化和反序列化,而是交给了业务执行线程。下面是参数反序列化的代码。

然后在最后部分,RSF 还没有忘记服务端的 RsfFilter 扩展机制实现。

有兴趣的同学可以去分析 RSF 的源码,这里就不在逐个展开说明,接下来我们来说一下主要线程中唯一没有讨论到的“定时器线程”。

重要线程

这个线程用一句话来概括就是干的活比较杂,例如:当 RSF 请求发出之后,会启动一个对应的 Timer。Timer的目的是用来处理,请求发出之后过了很久都没有 Respnse 回来的情形。遇到这种情形,Timer 超时的时候就会自己写入一个 Timout 异常。

这段逻辑位于“net.hasor.rsf.rpc.caller.RsfRequestManager”类中“startRequest”方法。有兴趣的同学可以去看 RSF 代码。

项目介绍:https://www.oschina.net/p/Hasor-RSF
源码位置:http://git.oschina.net/zycgit/rsf or https://github.com/zycgit/rsf
RSF系列文章:https://my.oschina.net/u/1166271/blog?catalog=574765&temp=1477997059095

转载于:https://my.oschina.net/ta8210/blog/779361

RSF 分布式服务框架设计:线程模型相关推荐

  1. RSF 分布式服务框架设计

    为什么80%的码农都做不了架构师?>>>    是时候设计一个分布式服务框架了.我先将它定名为 Hasor-RSF,"RSF"为 Remote Service F ...

  2. RSF 分布式服务框架-传输协议层设计

    为什么80%的码农都做不了架构师?>>>    这是接上一篇文章<RSF 分布式服务框架设计>之后的续作,主要是 Hasor-RSF 协议层的设计. RSF 的协议层设计 ...

  3. RSF 分布式服务框架-服务端工作原理

    为什么80%的码农都做不了架构师?>>>    这是接上一篇文章<RSF 分布式服务框架设计>之后的续作,主要是 Hasor-RSF 的请求响应工作原理以及设计思路. 非 ...

  4. C++高性能协程分布式服务框架设计

    本项目将从零开始搭建出一个基于协程的异步RPC框架. 学习本项目需要有一定的C++,网络,RPC知识 项目地址:zavier-wong/acid: A high performance fiber R ...

  5. 分布式服务框架设计笔记一

    一.服务发展历程: 传统MVC->  SOA ->微服务 SOA也是服务化一种,它与微服务的区分主要在:1.服务化粒度  2.微服务强调独立布署独立测试及独立发布 3.注册服务微服务是动态 ...

  6. 分布式服务框架学习笔记2 常用的分布式服务框架 与 通信框架选择

    传统垂直架构改造的核心就是要对应用进行服务化,服务化改造使用到的核心技术就是分布式服务框架. 分布式服务框架演进 应用从集中式走向分布式 大规模系统架构的设计一般原则就是尽可能地拆分,以达到更好的独立 ...

  7. 分布式服务框架之服务化最佳实践

    在服务化之前,业务通常都是本地API调用,本地方法调用性能损耗较小.服务化之后,服务提供者和消费者之间采用远程网络通信,增加了额外的性能损耗,业务调用的时延将增大,同时由于网络闪断等原因,分布式调用失 ...

  8. 分布式服务框架(一)

    转载自:https://www.cnblogs.com/jiyukai/p/9459983.html 分布式服务框架(一) 一.RPC RPC(Remote Process Call),即远程服务调用 ...

  9. 华为18级大牛倾情奉送:分布式服务框架和微服务设计原理实战文档,啃完发现涨薪如此简单

    前言 分布式服务框架不仅仅包含核心的运行时类库,还包括服务划分原则.服务化最佳实践.服务治理.服务监控.服务开发框架等,它是一套完整的解决方案,用来协助应用做服务化改造,以及指导用户如何构建适合自己业 ...

最新文章

  1. bose耳机信号断续_挥汗如雨的夏季将至,5款运动型蓝牙耳机安利给你
  2. 0402封装ESD二极管选型
  3. C++异常处理try throw catch
  4. tensorflow实现宝可梦数据集迁移学习
  5. pytorch 图像分割的交并比_级联多对抗的LAPGAN(二)pytorch实现
  6. 小哥送一单外卖应该拿多少钱?
  7. lua 和 c交互详解(一)
  8. LeetCode: Single Number I II
  9. Visual C# .Net 环境中编程实现浮动工具栏
  10. Spring声明式事务管理示例——MyBatis学习笔记之十六
  11. android 拦截qq消息,[Android] QNotified_v0.7.1-beta_QQ辅助增强XP模块【可屏蔽下拉小程序/屏蔽@全体/消息防撤回】...
  12. python饼状图显示其比例_Python学习笔记(matplotlib篇)--使用matplotlib绘制饼状图
  13. 《Solar Energy Materials and Solar Cells》期刊介绍(SCI 2区)
  14. 打印插件Lodop响应慢、卡顿问题分析与解决方案以及常见问题
  15. 麒麟子Cocos Creator实用技巧九:棋牌UI全分辨率适配方案
  16. Cannot construct instance of `com.baomidou.mybatisplus.core.metadata.IPage`
  17. USACO-Preface Numbering
  18. 唯样商城:电路板上的字母都代表什么意思?
  19. Day03-JavaScript01
  20. 清理Git提交记录最简单的方法

热门文章

  1. 《Gartner2016年度新兴技术成熟度曲线》全解读
  2. g mysql windows_Windows平台配置5.7版本+MySQL数据库服务
  3. linux服务器查看显卡信息
  4. 【转载】详解Android中接口回调、方法回调
  5. 不喜欢现在的领导,怎么办?不懂跟领导相处,你到哪都混不好
  6. 【C++ Primer Plus】第6章 分支语句和逻辑运算符
  7. 细致琐碎的事才是工作的主旋律
  8. C++ 定时每天十二点做某事
  9. bigworld源码分析(1)—— 研究bigworld的意义和目标
  10. mysql查询汉字拼音首字母的方法_MySQL查询汉字拼音首字母的方法