ASP.NET Core gRPC 使用 Consul 服务注册发现
一. 前言
gRPC 在當(dāng)前最常見的應(yīng)用就是在微服務(wù)場(chǎng)景中,所以不可避免的會(huì)有服務(wù)注冊(cè)與發(fā)現(xiàn)問(wèn)題,我們使用gRPC實(shí)現(xiàn)的服務(wù)可以使用 Consul 或者 etcd 作為服務(wù)注冊(cè)與發(fā)現(xiàn)中心,本文主要介紹Consul。
二. Consul 介紹
Consul是一種服務(wù)網(wǎng)絡(luò)解決方案,可跨任何運(yùn)行平臺(tái)以及公共或私有云來(lái)連接和保護(hù)服務(wù)。它可以讓你發(fā)現(xiàn)服務(wù)并保護(hù)網(wǎng)絡(luò)流量。它可以在Kubernetes中使用,實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)和服務(wù)網(wǎng)格功能(k8s默認(rèn)etcd)。提供安全服務(wù)通訊,保護(hù)和觀察服務(wù)之間的通信,而無(wú)需修改其代碼。提供動(dòng)態(tài)負(fù)載平衡, 使用Consul和HAProxy,Nginx或F5自動(dòng)執(zhí)行負(fù)載均衡器配置。Consul 可以用于服務(wù)發(fā)現(xiàn)和服務(wù)網(wǎng)格。
翻譯自官網(wǎng)
三. Consul 安裝配置
安裝
Consul 下載地址:https://www.consul.io/downloads.html
根據(jù)自己的系統(tǒng)來(lái)選擇,我這里選擇的是 Windows 版本的,直接解壓即可運(yùn)行。
啟動(dòng)
consul agent -dev -ui本文不詳細(xì)介紹Consul使用,如需請(qǐng)自行查看相關(guān)資料
四. .NET Core Consul 客戶端的選擇
Consul 提供了 HTTP API 的方式來(lái)進(jìn)行通訊,我們可以直接調(diào)用API或者是使用第三方封裝好的客戶端組件,通過(guò)Nuget搜索可以發(fā)現(xiàn)許多。
這里面我沒有一一測(cè)試,但是目前使用量最多的?Consul?組件是不支持設(shè)置 GRPC 健康檢查的,而且 github 也停止了更新。
所以我 Fork 了這個(gè)倉(cāng)庫(kù),然后添加了 GRPC 的健康檢查支持,本文也將使用這個(gè)庫(kù),歡迎大家使用:
因?yàn)樵瓊}(cāng)庫(kù)已經(jīng) Archived 了,所以我才 Fork 了自己改一下,改動(dòng)很小,不影響原來(lái)的穩(wěn)定性。
Nuget:https://www.nuget.org/packages/NConsul/
Github:https://github.com/stulzq/NConsul
求個(gè)star?
關(guān)于支持 GPRC 健康檢查的好處:
偷個(gè)懶,不翻譯了,摘自GRPC官方文檔
五. 注冊(cè)GRPC服務(wù)與健康檢查
基于前文(ASP.NET Core 使用gRPC)的Demo
1.為服務(wù)端項(xiàng)目安裝?NConsul.AspNetCore?(?https://www.nuget.org/packages/NConsul.AspNetCore?)
這里面對(duì) AspNetCore 做了適配,使用簡(jiǎn)單。
2.在 Startup 的?ConfigureServices方法內(nèi)進(jìn)行配置
public void ConfigureServices(IServiceCollection services){
services.AddGrpc();
services.AddConsul("http://localhost:8500")
.AddGRPCHealthCheck("localhost:5000")
.RegisterService("grpctest","localhost",5000,new []{"xc/grpc/test"});
}
AddConsul?添加 Consul Server 地址。
AddGRPCHealthCheck?添加 GRPC 健康檢查,即健康檢查走的是 GRPC 協(xié)議,該值為 GRPC 服務(wù)的地址,不需要path,不需要提供 http/https
RegisterService?注冊(cè)服務(wù)
到這步,還不能啟動(dòng)運(yùn)行,如果運(yùn)行健康檢查是會(huì)失敗的。
3.編寫 Health Check 服務(wù) **
對(duì)于 GRPC 的健康檢查,官方有標(biāo)準(zhǔn)的定義,新建一個(gè) proto 文件,命名為?HealthCheck.proto
syntax = "proto3";package grpc.health.v1;
message HealthCheckRequest {
string service = 1;
}
message HealthCheckResponse {
enum ServingStatus {
UNKNOWN = 0;
SERVING = 1;
NOT_SERVING = 2;
}
ServingStatus status = 1;
}
service Health {
rpc Check(HealthCheckRequest) returns (HealthCheckResponse);
rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse);
}
這里面的內(nèi)容不得更改,是官方標(biāo)準(zhǔn),資料見后文
這里編譯一下項(xiàng)目,以便自動(dòng)生成代碼。
然后,添加一個(gè)服務(wù)的實(shí)現(xiàn)類?HealthCheckService
public class HealthCheckService:Health.HealthBase{
public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
{
//TODO:檢查邏輯
return Task.FromResult(new HealthCheckResponse(){Status = HealthCheckResponse.Types.ServingStatus.Serving});
}
public override async Task Watch(HealthCheckRequest request, IServerStreamWriter<HealthCheckResponse> responseStream, ServerCallContext context)
{
//TODO:檢查邏輯
await responseStream.WriteAsync(new HealthCheckResponse()
{Status = HealthCheckResponse.Types.ServingStatus.Serving});
}
}
示例代碼直接返回了檢查結(jié)果,實(shí)際使用中應(yīng)該在這里編寫檢查邏輯,然后根據(jù)情況返回相應(yīng)的檢查結(jié)果。檢查結(jié)果有3種情況:
| Unknown | 未知狀態(tài) |
| Serving | 正常 |
| NotServing | 異常,不能提供服務(wù) |
最后別忘了注冊(cè)服務(wù):
4.測(cè)試運(yùn)行
啟動(dòng) GRPC 服務(wù)
然后訪問(wèn)?http://localhost:8500/ui?訪問(wèn) Consul 控制臺(tái)
可以看到服務(wù)成功注冊(cè),并且健康檢查也是通過(guò)了的。通過(guò)控制臺(tái)日志,還可以看到健康檢查的請(qǐng)求:
六. 客戶端使用服務(wù)發(fā)現(xiàn)
客戶端項(xiàng)目安裝?Consul?組件,然后改造下代碼:
static async Task Main(string[] args){
var serviceName = "grpctest";
var consulClient = new ConsulClient(c => c.Address = new Uri("http://localhost:8500"));
var services = await consulClient.Catalog.Service(serviceName);
if (services.Response.Length == 0)
{
throw new Exception($"未發(fā)現(xiàn)服務(wù) {serviceName}");
}
var service = services.Response[0];
var address = $"http://{service.ServiceAddress}:{service.ServicePort}";
Console.WriteLine($"獲取服務(wù)地址成功:{address}");
//啟用通過(guò)http使用http2.0
AppContext.SetSwitch(
"System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
var channel = GrpcChannel.ForAddress(address);
var catClient = new LuCat.LuCatClient(channel);
var catReply = await catClient.SuckingCatAsync(new Empty());
Console.WriteLine("調(diào)用擼貓服務(wù):"+ catReply.Message);
Console.ReadKey();
}
通過(guò)服務(wù)名稱獲取服務(wù)地址,然后來(lái)進(jìn)行訪問(wèn)。
運(yùn)行測(cè)試:
可以看到,成功的從Consul獲取了我們的服務(wù)地址,然后調(diào)用。
六. 參考資料
gRPC in Asp.Net Core :官方文檔
GPRC Health Check Doc:點(diǎn)我
本文 Demo:點(diǎn)我
本系列文章目錄:點(diǎn)我
NConsul:https://github.com/stulzq/NConsul
.NET Core微服務(wù)之基于Consul實(shí)現(xiàn)服務(wù)治理?by Edison Zhou
總結(jié)
以上是生活随笔為你收集整理的ASP.NET Core gRPC 使用 Consul 服务注册发现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: .NET Core on K8S 学习与
- 下一篇: [ASP.NET Core 3框架揭秘]