歡迎光臨
每天分享高質量文章

記一次Java動態代理實踐

導語:在Java生態中,我們經常直接或者間接的用到動態代理,比如透過動態代理呼叫遠端服務,再比如透過動態代理實現解耦。本文結合京東服務框架JSF,講述京東使用動態代理進行抽象的一次實踐,以達到升級資料庫訪問層的目的。

劉世傑,京東商城Java高階開發工程師,一直從服務端研發工作,目前主要負責京東海外站商品主資料基礎服務。個人喜歡讀原始碼,註重細節,有些許程式碼潔癖。對高可用、高效能、高併發方面的技術保持持續關註。

1. 背景


最近在做資料庫(MySQL)方面的升級改造。現狀是資料庫同時被多個應用直連,存在了一些問題:


  1. 有大量的重覆程式碼,維護成本較高,也不優雅;

  2. 出現SQL陳述句質量的問題無法很快定位到是哪個應用導致的;

  3. 資料庫呼叫方過於分散,不便於統一控制,比如部分業務資料的讀寫、遮蔽等;

  4. 業務的發展,有的表資料量已經到了一定的規模,幾百萬到幾千萬不等,資料庫儲存拆分是必須要進行的事情。


解決問題的方式很簡單,就是把各應用中與此業務相關的dao層抽象成為一個單獨應用(以下稱為internal-rpc-app),進行統一管理。


2. 具體實現


具體的業務應用與internal-rpc-app的內部通訊使用公司內部具有服務治理功能的RPC框架JSF,JSF是一款穩定高效的框架,它對服務治理的粒度是介面,介面透過Spring做服務的釋出和呼叫配置。每個介面對應一個資料表的CURD及特殊業務。


2.1 標準版本 1.0


2.1.1. 介面註冊申請


註冊介面: com.jd.xx.BizRpcService1

註冊介面: com.jd.xx.BizRpcService2

註冊介面: com.jd.xx.BizRpcService3

……

註冊介面: com.jd.xx.BizRpcServiceN

2.1.2. 服務提供方配置


……

2.1.3. 客戶端呼叫方配置


……

2.1.4 小結


此版本實現了我們的最初的目的,但是有一個不太好的地方,就是配置的工作量太高,前面有說到JSF框架的治理維度是介面。這也意味著,每次新增介面都要提交申請操作,同時要在consumer和provider做相對應的配置,幾個還好,如果資料表有幾十個上百個,重覆的工作量就很大。同時內部介面也不需要做太細粒度的服務治理。於是有了第二版,主要目的是簡化大量重覆配置。


2.2 最佳化呼叫體驗版本2.0


2.2.1 內部實現 – 客戶端


首先定義呼叫API:

BizRpcService1 bizRpcService1 = InternalPrxoyServices.BizRpcService1;

bizRpcService1.method1(param1, param2);

InternalPrxoyServices關鍵程式碼:


BizProxyRpcService1關鍵程式碼:


BaseProxyService關鍵程式碼:


InternalRpcService介面定義:


2.2.2 內部實現-服務端


服務端實現比較簡單,直接根據介面傳過來當serviceName、methodName、objects即可定位到具體service到方法,直接執行即可。


2.2.3 小結


到這裡,我們透過靜態代理實現了具體的標的,透過實現具體的介面類。我們不再需要定義過多的配置了,客戶端呼叫也變得簡單明瞭。


那麼,結束了嗎?並沒有,在解決了大量配置的問題的同時,因為要寫大量的代理類,又引入了新的工作量。


2.3 最終版本3.0


在這一版,我們很自然的引入了動態生成代理。


2.3.1 客戶端具體實現


因為引入了動態代理,所以要重新改寫InternalPrxoyServices


ProxyServiceFactory關鍵程式碼:


InternalRpcProxy關鍵程式碼:


2.4 小結


至此,已經解決了2.2.3提到的大量建立代理類的問題。當然我們還做了很多文章中沒有提及的事情,比如:


  • 透過宣告哪些介面可以走動態代理

  • 方法重名、客戶端介面合法性等校驗

  • 將method存入快取


3. 總結


透過建立獨立的應用,解決了前面資料庫被多應用讀寫所產生的問題,透過開發了統一介面解決了服務端和客戶端配置過多的問題。程式碼經過一步步抽象後,最終發現實現了一個簡單的RPC雛形,只不過通訊層是基於公司的JSF框架。這引發了一些框架方面的思考:


  1. 是否應該去掉人工審批類似的流程?

  2. 是否應該允許更靈活的釋出服務?比如:根據註解自動掃描釋出服務、根據註解自動獲取服務。


這不是技術問題,而是怎麼權衡的問題。 


Java招聘:

我們團隊主要負責京東海外站業務,目前發展快速。團隊氛圍open,領導nice,福利多多。急需Java研發加入我們,初級高階都可。

歡迎傳送簡歷至liujunhua@jd.com;liushijie@jd.com


相關閱讀:


高可用架構

改變網際網路的構建方式

長按二維碼 關註「高可用架構」公眾號

贊(0)

分享創造快樂