基于Asp.Net Core打造轻量级内部服务治理RPC(一)
? ? ? 繼之前的《Asp.Net Core + Docker 搭建》文章末尾說(shuō)過(guò)的,將陸續(xù)編寫(xiě)基于asp.net core 打造一個(gè)內(nèi)部服務(wù)治理的rpc框架。不過(guò)前端時(shí)間較忙,所以擱置了一段時(shí)間。閑話(huà)不多說(shuō),下面就來(lái)講講為什么需要去做一個(gè)該框架,以及想法的來(lái)源和設(shè)計(jì)思路。
一、產(chǎn)生背景
? ? ? ?公司技術(shù)棧是以微軟棧為主。整個(gè)平臺(tái)的業(yè)務(wù)并不是特別復(fù)雜。因此先前搭建每個(gè)子系統(tǒng)的時(shí)候都是以最簡(jiǎn)單的方式入手(時(shí)間較緊)。但是隨著時(shí)間的推移,各個(gè)子系統(tǒng)之間的交互也是越來(lái)越多,當(dāng)然,我們的做法也是很簡(jiǎn)單,就是通過(guò)暴露rest api ,然后客戶(hù)端通過(guò)http調(diào)用進(jìn)行交互,以至于現(xiàn)在很多系統(tǒng)都會(huì)配置其他系統(tǒng)的調(diào)用信息。日積月累,感覺(jué)系統(tǒng)越來(lái)月凌亂(有潔癖,遇到這種亂,就必須要去重構(gòu)^_^,當(dāng)然也是為后面維護(hù)減少成本),于是就產(chǎn)生了編寫(xiě)一個(gè)內(nèi)部服務(wù)調(diào)用的框架。
二、想法來(lái)源
? ? ? 本著遇到問(wèn)題解決問(wèn)題的目的,最開(kāi)始也想直接使用開(kāi)源的系統(tǒng),如:sugring,orleans等.net 界非常著名的項(xiàng)目。但考慮到我的需求很簡(jiǎn)單(以及我的想法也是做一個(gè)非常簡(jiǎn)單,盡量不依賴(lài)其他重量級(jí)的框架,開(kāi)發(fā)人員都認(rèn)真閱讀代碼后,都能輕易維護(hù)的東西),且對(duì)上述的框架目前應(yīng)用到生產(chǎn)環(huán)境的案例不是很知曉的情況下,于是還是忍痛割?lèi)?ài),最終放棄了。在這里,我想表達(dá)我的目標(biāo)就是我需要像dubbo一樣,調(diào)用方只需要引用服務(wù)提供者定義的相關(guān)接口庫(kù)(.Net 中定義的接口eg:IUserService),就能直接調(diào)用。服務(wù)的調(diào)用方和提供方都注冊(cè)到一個(gè)統(tǒng)一的注冊(cè)中心(我以consul為注冊(cè)中心,無(wú)需安裝其他運(yùn)行時(shí),非常方便)。這樣就不需要關(guān)心服務(wù)的具體地方。(該實(shí)現(xiàn)方式的想法在我今天(2018-12-16)看到的doteasy.rpc中的文章和我的想法幾乎一致,但是我的實(shí)現(xiàn)還是略有不同,它是基于pb進(jìn)行傳輸實(shí)現(xiàn)的,我是完全基于asp.net core 中的webapi進(jìn)行實(shí)現(xiàn))。
三、設(shè)計(jì)思路
? ? ? 其實(shí),asp.net core 已經(jīng)是一個(gè)完善且高效的rpc框架,我們?cè)谡{(diào)用每一個(gè)實(shí)現(xiàn)的web api實(shí)際就是一個(gè)rpc調(diào)用,只是它是基于http協(xié)議,大多數(shù)情況下,數(shù)據(jù)是通過(guò)json序列化和反序列化而已。(其他開(kāi)源的優(yōu)秀框架eg:surgin,oreans,dubbo...實(shí)現(xiàn)了自己高效的通信方式以及協(xié)議)。所以,基于asp.net core來(lái)實(shí)現(xiàn),其實(shí)就是基于它來(lái)擴(kuò)展,并且滿(mǎn)足大多數(shù)公司的業(yè)務(wù)需求的性能要求應(yīng)該不是問(wèn)題(何況我們的spring boot實(shí)現(xiàn)微服務(wù)也是走rest方式^_^)。下面是我的整個(gè)想法構(gòu)思圖。
圖 1
? ? ? 場(chǎng)景:比如我有一個(gè)Service A的集群,依賴(lài)了Service B集群(可運(yùn)行多個(gè)Service B的進(jìn)程實(shí)例)的一個(gè)接口(IUserService,當(dāng)然該接口在Service B中進(jìn)行了實(shí)現(xiàn)UserService)進(jìn)行數(shù)據(jù)獲取(或操作)。就可以通過(guò)啟動(dòng)每個(gè)Service B實(shí)例時(shí)就將Service B要提供的服務(wù)發(fā)布出來(lái)(或叫導(dǎo)出),注冊(cè)到Consul注冊(cè)集群中,同樣,Service A的實(shí)例也需要注冊(cè)到注冊(cè)中心(即使不發(fā)布供其他服務(wù)調(diào)用的接口)。此時(shí),Service A要調(diào)用Service B的服務(wù),首先,通過(guò)HttpServiceProxyFactory服務(wù)代理類(lèi)生成IUserSerivice的代理實(shí)現(xiàn)類(lèi)UserSeriviceImpl(通過(guò)Emit進(jìn)行動(dòng)態(tài)代理),再?gòu)淖?cè)中心獲取到Service B的集群信息,根據(jù)一定的負(fù)載算法(負(fù)載是客戶(hù)端進(jìn)行負(fù)載實(shí)現(xiàn),目前只實(shí)現(xiàn)了簡(jiǎn)單的循環(huán)負(fù)載),選擇一個(gè)Service B的實(shí)例進(jìn)行遠(yuǎn)程調(diào)用。其中UserSeriviceImpl代理實(shí)現(xiàn)類(lèi)中核心的代碼就是通過(guò)HttpClient進(jìn)行數(shù)據(jù)的包裝,然后請(qǐng)求到Service B中的UserService(其實(shí)就是一個(gè)Controller)實(shí)現(xiàn)類(lèi)中。然后在解析UserService處理后返回過(guò)來(lái)的數(shù)據(jù)。
? ? ? 以上就是我整個(gè)Rpc調(diào)用的總體思路。具體每個(gè)模塊的詳細(xì)設(shè)計(jì)與實(shí)現(xiàn),接下來(lái)我會(huì)繼續(xù)寫(xiě)出來(lái),有興趣的朋友可以留言交流也可以加qq:418237014交流。
?
原文地址: https://www.jianshu.com/p/c45f56d2aa21
.NET社區(qū)新聞,深度好文,歡迎訪(fǎng)問(wèn)公眾號(hào)文章匯總 http://www.csharpkit.com
總結(jié)
以上是生活随笔為你收集整理的基于Asp.Net Core打造轻量级内部服务治理RPC(一)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 领域驱动设计,让程序员心中有码(四)
- 下一篇: 开发.NET Core NuGet包并实