===== 服务端 ===== - 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}}