netcore 中的动态代理与RPC实现(微服务专题)
一、關于RPC的調用
1. 調用者(客戶端Client)以本地調用的方式發起調用;
2. Client stub(客戶端存根)收到調用后,負責將被調用的方法名、參數等打包編碼成特定格式的能進行網絡傳輸的消息體;
3. Client stub將消息體通過網絡發送給服務端;
4. Server stub(服務端存根)收到通過網絡接收到消息后按照相應格式進行拆包解碼,獲取方法名和參數;
5. Server stub根據方法名和參數進行本地調用;
6. 被調用者(Server)本地調用執行后將結果返回給server stub;
7. Server stub將返回值打包編碼成消息,并通過網絡發送給客戶端;
8. Client stub收到消息后,進行拆包解碼,返回給Client;
9. Client得到本次RPC調用的最終結果。
參考https://www.cnblogs.com/FG123/p/10261676.html
參考https://www.jianshu.com/p/bb9beca7f7bc?第四節
二、關于RPC調用方式的思考(為什么要用代理類)
RPC的方便之處我們已經看到了,
假設在系統中要調用多個服務,如果寫一個函數,每次將這個服務的名字,參數,和其他信息通過一個方法來調用遠程服務,假設這個方法叫做getService(methodname,object[],參數3,參數4)? ??
我們在各個消費類中來調用這個方法似乎也能得到結果。
在每個調用遠程服務的地方都要反射出 類的方法名稱,參數等其他信息以能傳給getService 是不是很麻煩?
要知道遠程服務每個服務返回的結果不會是一樣的類型,那我們在客戶端還要每次都轉換getService的結果,是不是很麻煩?
有沒有好的解決方案?
--請使用代理類,我們在代理類中反射代理接口得到這個方法的各種屬性(名稱&參數&其他),遠程調用傳遞給遠程服務,并轉換得到的結果。看起來這種方法和上文的getService 差不多嘛!那我們為什么要使用代理類呢?(我也不知道,但看起來很吊的樣子。)這看起來并沒有很好的樣子,況且如果有多個類要調用遠程服務,那豈不是要寫很多代理類?
思考:調用getService 后每次都要在消費類中轉換結果,使用代理類后將這個轉換過程放入了代理類中,這樣消費類就不用關注RPC的調用結果的類型的轉換了。
于是人們發明了動態代理? ?--來自《魯迅先生說革命》
人們發現每個類都要寫個代理。現在小明要在項目中寫1000個代理類,直接氣炸了,對!炸了!。
經過了N代的小明客戶鉆研和發現,總結了一套可以很省力氣的方法。--動態代理
簡單的來說:動態創建代理類(https://www.cnblogs.com/netqq/p/11452374.html),這樣就不用給每個消費類都寫一個代理類了,是不很爽
三、動態代理與RPC
?在網上找到了一個簡單的RPC 示例,非常適合初學者學習??https://github.com/Coldairarrow/DotNettyRPC?
?下載項目后先運行 Server 項目,再運行client項目
看到再server的控制臺上輸出了hello 字符串。這是客戶端程序調用了server的IHello.SayHello()的服務輸出的。
我們來看下作者的客戶端調用
?
RPCClientFactory源碼如下
在示例中,程序調用的GetClient?
?實際上也是動態生成的代理類,返回了IHello類型的對象。
我們先拋開該作者的程序,用我們自己的動態代理類來實現相同的效果。
在DotNettyRPC項目中添加ProxyDecorator<T> 類。???需要nuget下載System.Reflection.DispatchProxy.dll
在添加ProxyDecorator 和編譯的時候會遇到問題,我們將server、 client項目和DotNettyRPC? 轉為NETCORE項目才能正常執行 ,因為?System.Reflection.DispatchProxy.dll 只NETCORE 類庫,不支持NET Framework項目
ProxyDecorator<T>? 源碼
這個類的源碼與上一篇反向代理文章中所講的核心區別是 Invoke 的實現,上篇文章中其調用的是本地的一個類實體的方法,本文中其調用的是遠程服務中的類實體的方法
client調用代碼如下
?重新啟動Server 和Client 執行效果如下
和原作者的執行結果一致,那么我們換個接口來試試:創建IMail? 和Mail兩個類,并包含一個成員string? Send(string? name)//IMail和Mail的成員??
Client端調用代碼
服務端添加服務監控
預計客戶端輸出:
你的名字是張三豐
完成?
服務端輸出是:
張三豐
我們先后啟動server 和 client 兩個端來看看
至此動態代理的應用示例已經演示完畢。
在查看? ?寒空飛箭? ?git 源碼時候我們發現??RPCClientProxy 類和我們的ProxyDecorator<T> 類? 實現了相同的效果,寒空飛箭的實現方式也是很令人振奮,獨辟蹊徑,非常值得學習。下篇文章將會分析他的用法。感興趣的可以自行查看作者的源碼。
參考文獻:
https://www.cnblogs.com/coldairarrow/p/10193765.html
?說明:
RPC功能的實現是直接引用作者?寒空飛箭?的代碼,對此向?寒空飛箭?表示感謝
相關文章:
netcore 之動態代理(微服務專題)
原文鏈接:https://www.cnblogs.com/netqq/p/11462054.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總?http://www.csharpkit.com?
總結
以上是生活随笔為你收集整理的netcore 中的动态代理与RPC实现(微服务专题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【全】Docker(二)-在Docker
- 下一篇: 谈谈“学习”这件事儿