【最佳實踐】- RPC

概述

本文介紹如何玩轉 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 彩蛋

剛開始寫博客, 希望大家支持, 如果有沒疑問或不清楚的地方可以留言噢!

下週再見~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章