概述
本文介紹如何玩轉 RPC, 可以說是 RPC 開發規範, 也可以理解爲 RPC 最佳實戰.
一、接口設計
- 寫入的服務保證冪等性,不冪等則要求有排重處理。
- 方法上面要求顯式的拋出可能出現的異常,即使是自定義Runtime異常(不使用拋出 Dubbo 的異常,可能引起特殊處理例如重試)。
- 方法名要求含義明確且唯一,不能使用重載方法。
- 自定義對象數據結構要求儘量簡潔,儘量不要多層循環嵌套。
- 儘量避免接口參數使用父類,調用時傳入子類的設計。
- 修改自定義對象參數或者返回值時,要考慮接口上下兼容,保證自定義對象裏的字段順序。
- 接口中的參數是爲了 數據交換(相互交流信息) , 而不是邏輯實現. 比如k/v型的數據, 應該用普通的HashMap, 而不應該用 CurrentHashMap
二、服務發佈和調用
- 開發環境和測試環境使用不同的alias。
- 開發環境自己測試可以使用直連,防止調用到別的機器。
<dubbo:consumer url="dubbo://127.0.0.1:20880;……" />
- 一個機器上發佈多個不同 Dubbo 應用時,儘量自定義端口段。
<dubbo:server id="dubbo" protocol="dubbo" port="22000" />
- 在 Dubbo 調用鏈中(例如A調B,B裏面調C),外層調用的超時時間要求大於內層調用的超時時間(即A調B的超時時間要大於B調C的超時時間)
- 同一接口同一alias下的全部實例應該是 對等 的; 如果一個接口要按業務區分的,則要求使用不同服務別名alias或者拆爲兩個接口。
三、運維
- 可以按機房,運維重要等級分組
- 及時關注服務健康情況,如果有垃圾節點可主動清理
- 對網絡要求較高的接口,可以開啓同機房優先調用功能
- 調用端或者服務端用 API 的方式啓動服務, 頻繁啓動停止, 產生頻繁的註冊/反註冊, 導致註冊中心存在大量過期數據
- 頻繁地用程序通過管理端 url 摘取數據, 導致 dubbo 數據庫訪問量高
- 接口不區分 alias, 發佈大量的 provider 實例. 建議切分成不同的 alias 保留支持相應調用量的 provider, 讓不同的用戶調用, 減少服務端維持的客戶端連接數
四、代碼層面
- join 三張表以上
- 日誌輸出沒有采用條件方式或者佔位符方式
- 重複打印日誌
- try 塊放到了事務代碼中
- 循環體中含有低性能的語句
- 鎖代碼塊中進行 Dubbo 調用
五、常見問題
序列化問題
- 依賴的包不一致(客戶端與服務端引用 的僅有接口, 入參和出參的jar包或者maven引用不一致,導致序列化問題)
- 參數字段不一致(入參或出參字段臨時有變動,沒有按照規範增加字段,入參字段和你子類的字段順序, 導致序列化問題)
- 匿名的集合類(用 jdk 自身的可序列化集合類, 但使用方法塊的方式初始化 如: new HashMap(){{put(xx,xx)}}, 或者使用類似 list.subList, 本質上是使用了匿名類, 導致序列化問題)
- 複雜的數據結構 (入參或出參的結構複雜, 導致序列化過慢, 影響性能)
- 錯誤的異常類定義(服務端招聘自己封裝的業務異常, 沒有無參的構造方法, 導致序列化問題, 無法在調用端拿到正確的異常)
- 接口能力不一致(同一 server 發佈耗時差異比較大的接口, 建議耗時長和短的接口分別指向不同的 server, 即線程池隔離)
666 彩蛋
剛開始寫博客, 希望大家支持, 如果有沒疑問或不清楚的地方可以留言噢!
下週再見~