要實時就用同步,要吞吐率就用異步。負載均衡
流程略框架
實現負載均衡:鏈接池中創建了與一個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(說明已經超時處理過了),就直接將請求丟棄。隊列