===== 服务端 =====
- netty接收到一个调用信息
- 将请求放入一个线程池处理(默认200个线程,队列长度0)关键步骤
- 放入线程池时会提供 2个参数。
- 请求数据 :用于计算请求结果
- channel : 用于发送结果到客户端
- 由于netty所有的io操作都放在NioEventLoop中。在线程池中调用channel.write()时会创建一个异步任务放入NioEventLoop的任务队列中
- 处理请求,经过各种filter
- ContextFilter 填充上线文信息
- TimeoutFilter 处理超时
- ExceptionFilter 处理异常
- 构造到一个response, 里面携带request 的 id,并返回
===== 客户端 =====
将方法名称,方法的参数通过netty发到服务端,并等待服务端返回结果
- 将方法名,方法参数构造成一个Request
- 根据loadbalance选择一个服务端
- 决定重试次数
- 然后经过各种filter
- FutureFilter 决定请求是同步还是异步(默认同步)
- 选择一个Client发送数据,对应一个netty连接,对应一个NioSocketChannel (dubbo连接使用长连接,并只创建一个连接并复用)
- 返回一个DefaultFuture(里面有request的id),将其放入静态全局map结构,并同步等待 关键步骤
- 收到服务端的返回
- 根据返回的Responsed对象中的request_id从全局map结构中获取正在等待的DefaultFuture,并通知该DefaultFuture已经成功了(DefaultFuture从wait状态中醒来)
- 一次调用完成
{{:pasted:20180630-164506.png}}
===== 细节点 =====
如上图最后边的部分
- 服务端selector收到客户端的请求信息
- processSelectedKeys将请求放入业务线程池处理
- 业务线程池处理完后调用channel.write()回写结果
- 当调用write是发现当前线程不在channle所属的NioEventLoop的线程中,所以创建一个异步write任务放入NioEventLoop的任务队列
{{:pasted:20180630-173256.png}}
{{:pasted:20180630-172854.png}}