基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现
0.簡介
0.1 什么是 Consul
Consul是HashiCorp公司推出的開源工具,用于實現分布式系統的服務發現與配置。
這里所謂的服務,不僅僅包括常用的 Api 這些服務,也包括軟件開發過程當中所需要的諸如 Rpc、Redis、Mysql 等需要調用的資源。
簡而言之 Consul 就是根據 Key/Value 存儲了一套所有服務的 IP/Port 集合,當你 Grpc 客戶端需要請求某種服務的時候,具體的 IP 與端口不需要你自己來進行指定,而是通過與 Consul Agent 通信獲得某個服務下面可用的 IP/Port 集合。
而 Consul 還提供了健康檢查等附加的功能,你可以通過對可用服務節點的遍歷來自己進行負載均衡或者服務選擇。
0.2 為什么要用 Consul
沒用 Consul 之前的情況是,我 new 一個 Channel 的話,需要指定 Grpc Server 的地址與端口,一單服務掛掉或者 Grpc Server 的 IP 地址或者端口有變更,那么我還得重新更改 setting 才能夠使用我的服務。
使用了 Consul 之后我只需要去 Consul Agent 里面查詢我指定的服務有哪些節點可用,返回給我對應的 IP 地址和端口,我就可以進行連接了。
1.準備工作
1.1 Consul 集群安裝與配置
Consul 我是直接使用 Docker 的官方 Consul 鏡像來進行安裝的,直接執行以下命令 pull 到最新的鏡像:
docker pull consul拿到之后我們先運行一個服務:
docker run -d --name=dev-consul-server1 -e CONSUL_BIND_INTERFACE=eth0 consul agent -server -bootstrap之后我們再運行兩個 Consul Server:
docker run -d --name=dev-consul-server2 -e CONSUL_BIND_INTERFACE=eth0 consul agent -server -retry-join 172.17.0.20這里 172.17.0.20 是之前 dev-consul-server1 的 IP 地址。
docker run -d --name=dev-consul-server3 -e CONSUL_BIND_INTERFACE=eth0 consul agent -server -retry-join 172.17.0.20我們可以運行?consul members?命令來查看 Consul 集群信息:
docker exec -t dev-consul-server1 consul members可以看到已經有 3 個 Consul Server 啟動了。
下面我們再來運行一個 Consul Client 作為服務注冊與發現的端口:
docker run -d -p 8500:8500 --name=dev-consul-client -e CONSUL_BIND_INTERFACE=eth0 -e CONSUL_UI_BETA=true consul agent -retry-join 172.17.0.20 -bind 0.0.0.0 -ui -client 0.0.0.0這里注意?-bind?與?-client?命令是你綁定的 IP 地址,這里我直接將其與 0.0.0.0 綁定,而?-e CONSUL_UI_BETA=true?則是用于啟動新版本的 WebUI 界面,-ui?是啟用 WebUI 界面。
啟動完成之后我們可以訪問已經啟動的 Client Agent 了:
2.客戶端與服務端編寫
在這里我以 Abp 框架作為演示,如何編寫一個支持 Consul 的 Grpc 服務端與 Grpc 客戶端,在演示當中所使用到的?Abp.Grpc.Server?包與?Abp.Grpc.Client?包可以從 NuGet 站點當中搜索安裝,其源代碼我托管到 GitHub 上面的,地址為:https://github.com/GameBelial/Abp.Grpc,歡迎 Star。
2.1 Grpc 服務端編寫
2.1.1 Abp 集成
首先建立一個標準的 ASP.NET Core Web Application 程序,引入?Abp、Abp.AspNetCore、Abp.Grpc.Server?包,項目取名為?Abp.Grpc.Server.Demo,類型選擇空項目,在我們的 Startup 類當中編寫如下代碼:
2.1.2 建立項目啟動模塊
新建一個?AbpGrpcServerDemoModule?類,并編寫以下代碼:
2.1.3 編寫健康檢查控制器
新建一個文件夾叫做 Controllers ,并且新建一個?HealthController?類,其內容如下:
2.1.4 編寫 RPC 服務
新建一個 RpcServices 文件夾,并且新建一個 TestGrpcService 文件,其內容如下:
可以看到我們編寫了一個簡單的?Sum?方法,該方法接收兩個?int?類型的參數,計算其和并返回。
2.1.5 編寫 Dockerfile 文件
因為我們的 Consul 是放在 Docker 容器當中的,所以我們將我們的站點發布出去,并且編寫一個 Dockerfile 文件,內容如下:
FROM microsoft/dotnetENV ASPNETCORE_URLS http://+:5000## 開放 5000 網站端口EXPOSE 5000## 開放 5001 RPC 端口EXPOSE 5001WORKDIR /appCOPY ./ .ENTRYPOINT [ "dotnet","Abp.Grpc.Server.Demo.dll" ]將其拷貝到發布好的站點,并且執行 docker build 命令:
PS D:\Project\DEMO\Abp.Grpc.Server.Demo\Abp.Grpc.Server.Demo\bin\Release\netcoreapp2.1\publish> docker build -t grpc-server-demo . Sending build context to Docker daemon ? 29.9MB Step 1/7 : FROM microsoft/dotnet---> d8381e1175a1Step 2/7 : ENV ASPNETCORE_URLS http://+:5000---> Using cache---> da7659cff6d2Step 3/7 : EXPOSE 5000---> Using cache---> 7ecfc480ad43Step 4/7 : EXPOSE 5001---> Using cache---> 75f10934ad1eStep 5/7 : WORKDIR /app ---> Using cache---> dee9739da4cdStep 6/7 : COPY ./ . ---> 1a5acc1f0298Step 7/7 : ENTRYPOINT [ "dotnet","Abp.Grpc.Server.Demo.dll" ] ---> Running in a46efbabc7fcRemoving intermediate container a46efbabc7fc ---> 321201373ecfSuccessfully built 321201373ecf Successfully tagged grpc-server-demo:latestSECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories構建完鏡像之后,我們運行該鏡像:
docker run -d -p 5000:5000 -p 5001:5001 --name=grpc-server-demo grpc-server-demo2.1.6 查看 Consul
來到 Consul 的 UI 界面查看效果:
可以看到已經成功注冊,說明已經成功了。
2.2 Grpc 客戶端編寫
2.2.1 Abp 集成
首先建立一個標準的 .Net Console 程序,引入?Abp.Grpc.Client?包,在我們的 Program 類當中編寫如下代碼:
2.2.2 建立項目啟動模塊
然后我們新建一個?AbpGrpcClientDemoModule?類,該類一樣是一個啟動模塊,用于配置連接信息:
很簡單,直接配置 Consul 注冊的 IP 與端口號即可。
2.2.3 建立 RPC 接口定義
要調用我們 Server 提供的 RPC 端口的話,得編寫一個接口定義,就是我們在 Server 項目里面寫的那個,新建一個?ITestGrpcService?接口,內容如下:
2.2.4 調用 RPC 接口
調用接口的話,需要注入?IGRpcConnectionUtility?工具類,使用其?GetRemoteService?方法就可以調用你的遠程方法,記住一定要傳入有效的服務名稱。
2.2.5 編寫 Dockerfile 文件
一樣的,我們新建一個 Dockerfile 文件,將我們的 client 也打包成鏡像:
FROM microsoft/dotnetWORKDIR /app COPY ./ .ENTRYPOINT [ "dotnet","Abp.Grpc.Client.Demo.dll" ]內容很簡單,一樣的復制到發布成功的文件夾,構建鏡像:
docker build -t grpc-client-demo .構建之后運行:
docker run grpc-client-demo不出意外的話會看到如下輸出:
PS D:\Project\DEMO\Abp.Grpc.Client.Demo\Abp.Grpc.Client.Demo\bin\Release\netcoreapp2.1\publish> docker run grpc-client-demoResult:15Press enter to stop application...Hello World!3.代碼分析
拋開 ABP 框架部分的代碼,其實要實現服務注冊很簡單,核心就是 ConsulClient 這個類,
下面就來分析一下 Abp.Grpc 庫里面的代碼。
3.1 注冊服務
注冊服務其核心就在于?ConsulClient.Agent.ServiceRegister()?方法,通過傳入一個構造好的?AgentServiceRegistration?對象就可以成功注冊一個服務到 Consul。
例如:
構建成功后通過?ConsulClient.Agent.ServiceRegister()?方法即可注冊到 Consul。
取消注冊則是通過?ConsulClient.Agent.ServiceDeregister?方法。
3.2 發現服務
服務發現相較于服務注冊簡單得多,只需要通過?ConsulClient.Catalog.Services?遍歷其結果即可獲得所有節點,并且通過 LINQ 來篩選出指定 tag 的服務。
4.其他相關參考資料
田園里的蟋蟀:Docker & Consul & Fabio & ASP.NET Core 2.0 微服務跨平臺實踐)
Edison Chou:.NET Core微服務之基于Consul實現服務治理
Cecilphillip:Using Consul for Service Discovery with ASP.NET Core
5.所使用到的代碼
Abp.Grpc 庫代碼:https://github.com/GameBelial/Abp.Grpc
DEMO 代碼:
https://github.com/GameBelial/Abp.Grpc.Server.Demo
https://github.com/GameBelial/Abp.Grpc.Client.Demo
相關文章:?
.NET Core微服務之基于Consul實現服務治理
.NET Core微服務之基于Consul實現服務治理(續)
Ocelot + Consul實踐
青客寶團隊Consul內部分享ppt
搭建consul 集群
Redola.Rpc 集成 Consul 服務發現
Consul 服務注冊與服務發現
在Windows 下如何使用 AspNetCore Api 和 consul
原文地址: https://www.cnblogs.com/myzony/p/9168851.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的基于 Consul 实现 MagicOnion(GRpc) 服务注册与发现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用ASP.NET Core 2.1 建立
- 下一篇: 用ASP.NET Core 2.1 建立