前言
在實際后臺服務(wù)開發(fā)中嚷辅,比如訂單服務(wù)(開發(fā)者A負(fù)責(zé))需要調(diào)用商品服務(wù)(開發(fā)者B負(fù)責(zé)),那么開發(fā)者B會和A約定調(diào)用API距误,以接口的形式提供給A簸搞。通常都是B把API上傳到Maven私服扁位,然后B開始寫API的實現(xiàn),A只需要引入API依賴進(jìn)行開發(fā)即可趁俊。
上圖簡單的描述了RPC在實際場景中的應(yīng)用贤牛,我們在開發(fā)中當(dāng)然是利用現(xiàn)有的RPC框架來快速實現(xiàn)業(yè)務(wù)需求,比如百度開源了baidu-rpc则酝,阿里的Dubbo早已聲名在外,騰訊自己玩TAF闰集。本篇博客將實現(xiàn)一個迷你版的RPC沽讹,探索下RPC底層實現(xiàn)的奧秘!
動手實現(xiàn)RPC
商品服務(wù)工程
注意武鲁,我將商品服務(wù)的API以及實現(xiàn)分為Maven的2個模塊來開發(fā)爽雄。這里,我們想給定一個商品ID沐鼠,查詢得到商品對象信息挚瘟。
商品對象
要注意的是,Product是可以被序列化的饲梭,Why?
很顯然乘盖,訂單系統(tǒng)調(diào)用商品系統(tǒng)的時候,需要商品系統(tǒng)返回一個商品憔涉,必然涉及到發(fā)生網(wǎng)絡(luò)傳輸订框,這就涉及對象的序列化和反序列化了。
商品查詢API接口
訂單系統(tǒng)調(diào)用商品服務(wù)
在訂單系統(tǒng)工程中需要引入商品服務(wù)API依賴兜叨。
在上圖代碼中穿扳,最重要的就是rpc方法了!
rpc實現(xiàn)方法
第一国旷,我們看到了Proxy.newProxyInstance矛物,很顯然在進(jìn)行動態(tài)代理。也即是說跪但,在訂單服務(wù)調(diào)用商品服務(wù)的代碼中履羞,我們先是通過動態(tài)代理返回一個代理的IProductService類型對象,這意味著當(dāng)代理對象調(diào)用queryById方法的時候特漩,會自動調(diào)用invoke方法吧雹!
第二,我們看看invoke到底做了些什么涂身?
它本質(zhì)上就是進(jìn)行Socket通信雄卷,那么它需要傳遞什么信息給到商品服務(wù)呢?
我們知道訂單系統(tǒng)就是想調(diào)用商品服務(wù)的某個類的某個方法蛤售,然后把這個方法的返回結(jié)果傳輸給訂單系統(tǒng)丁鹉!
想一想妒潭,如何調(diào)用某個類的某個方法呢?
只要我們能確定這個類的全限定類名揣钦、確定方法名雳灾、確定方法的參數(shù)類型,給定方法需要的具體參數(shù)冯凹,通過反射就能實現(xiàn)谎亩。
商品服務(wù)調(diào)用后得到的結(jié)果,我們序列化寫入Socket流中宇姚,在訂單系統(tǒng)中反序列化得到對象即可匈庭。
第三,這里需要思考一個問題:在訂單系統(tǒng)中我們只知道商品服務(wù)的API浑劳,并不知道這背后的API到底是如何實現(xiàn)的阱持,所以我們需要有一個映射,就是商品服務(wù)的API到商品服務(wù)的實現(xiàn)的一個映射關(guān)系魔熏,其實這就是所謂的服務(wù)的注冊衷咽!
商品API的具體實現(xiàn)
商品服務(wù)
從這里,可以清晰的看到蒜绽,商品服務(wù)讀取了訂單系統(tǒng)調(diào)用商品系統(tǒng)時發(fā)送的數(shù)據(jù)镶骗,利用反射機(jī)制,進(jìn)行方法調(diào)用躲雅,并把調(diào)用結(jié)果寫入Socket輸出流卖词。
運行結(jié)果
啟動商品服務(wù)后,通過訂單系統(tǒng)發(fā)起對商品服務(wù)的調(diào)用吏夯。
以前總認(rèn)為RPC是遙不可及的此蜈,感覺是個很神奇的東西,實際上它的底層實現(xiàn)不就是這樣的么~
晚安噪生!
2017.11.17 by zhangfengzhe