要实时就用同步,要吞吐率就用异步。负载均衡
流程略框架
实现负载均衡:链接池中创建了与一个RPC-server集群的链接,链接池在返回链接的时候,须要具有负载均衡策略。
实现故障转移:链接池中创建了与一个RPC-server集群的链接,当链接池发现某一个机器的链接异常后,须要将这个机器的链接排除掉,返回正常的链接,在机器恢复后,再将链接加回来。
实现发送超时:由于是同步阻塞调用,拿到一个链接后,使用底层socket带超时的send/recv便可实现带超时的发送和接收。异步
流程略socket
为何要待发送队列、待接收队列?
由于要将工做线程和io收发线程二者的同步关系解除,从而引入工做线程池和io收发线程池。函数
为何要上下文
由于请求包的发送,响应包的callback回调不在同一个工做线程中完成,须要一个context来记录一个请求的上下文,把请求-响应-回调等一些信息匹配起来。经过rpc框架的内部请求id做为key,来保存调用开始时间time,超时时间timeout,回调函数callback,超时回调timeout_callback等信息。
注意:请求id由client端服务调用时生成,会序列化成字节流发送给server端,server端会返回该请求id。线程
负载均衡,故障转移
与同步调用的链接池思路基本相同。
注意:因为同步调用的链接池使用阻塞方式收发,须要与一个服务的一个server ip创建多条链接来保证client端多个服务同时路由到同一个server时不会阻塞。而因为异步调用,server端会很快返回response,因此client端多个服务同时路由到同一个server的状况是不多的,所以一个服务的一个server ip只须要创建少许的链接。server
超时发送与接收
超时管理器启动timer对上下文管理器中的全部context进行扫描,看上下文中请求发送时间是否过长,若是过长,就再也不等待result包,将该context从上下文管理器中移除,直接执行timeout_callback。
注意:若是timeout_callback执行后,client端接收到了server端的result包,此时由于经过req-id在上下文管理器里找不到对应的context(说明已经超时处理过了),就直接将请求丢弃。队列