一. 前言
gRPC 在当前最常见的应用就是在微服务场景中,所以不可避免的会有服务注册与发现问题,我们使用gRPC实现的服务可以使用 Consul 或者 etcd 作为服务注册与发现中心,本文主要介绍Consul。
二. Consul 介绍
Consul是一种服务网络解决方案,可跨任何运行平台以及公共或私有云来连接和保护服务。它可以让你发现服务并保护网络流量。它可以在Kubernetes中使用,实现服务发现和服务网格功能(k8s默认etcd)。提供安全服务通讯,保护和观察服务之间的通信,而无需修改其代码。提供动态负载平衡, 使用Consul和HAProxy,Nginx或F5自动执行负载均衡器配置。Consul 可以用于服务发现和服务网格。
翻译自官网
三. Consul 安装配置
安装
Consul 下载地址:https://www.consul.io/downloads.html
根据自己的系统来选择,我这里选择的是 Windows 版本的,直接解压即可运行。
启动
consul agent -dev -ui
本文不详细介绍Consul使用,如需请自行查看相关资料
四. .NET Core Consul 客户端的选择
Consul 提供了 HTTP API 的方式来进行通讯,我们可以直接调用API或者是使用第三方封装好的客户端组件,通过Nuget搜索可以发现许多。
这里面我没有一一测试,但是目前使用量最多的Consul
组件是不支持设置 GRPC 健康检查的,而且 github 也停止了更新。
所以我 Fork 了这个仓库,然后添加了 GRPC 的健康检查支持,本文也将使用这个库,欢迎大家使用:
因为原仓库已经 Archived 了,所以我才 Fork 了自己改一下,改动很小,不影响原来的稳定性。
Nuget:/packages/NConsul/
Github:/stulzq/NConsul
求个star
关于支持 GPRC 健康检查的好处:
偷个懒,不翻译了,摘自GRPC官方文档
五. 注册GRPC服务与健康检查
基于前文( Core 使用gRPC)的Demo
1.为服务端项目安装NConsul.AspNetCore
(/packages/NConsul.AspNetCore)
这里面对 AspNetCore 做了适配,使用简单。
2.在 Startup 的ConfigureServices
方法内进行配置
{ services.AddGrpc(); services.AddConsul("http://localhost:8500") .AddGRPCHealthCheck("localhost:5000") .RegisterService("grpctest","localhost",5000,new []{"xc/grpc/test"}); }public void ConfigureServices(IServiceCollection services)
AddConsul
添加 Consul Server 地址。
AddGRPCHealthCheck
添加 GRPC 健康检查,即健康检查走的是 GRPC 协议,该值为 GRPC 服务的地址,不需要path,不需要提供 http/https
RegisterService
注册服务
到这步,还不能启动运行,如果运行健康检查是会失败的。
3.编写 Health Check 服务 **
对于 GRPC 的健康检查,官方有标准的定义,新建一个 proto 文件,命名为HealthCheck.proto
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); }syntax = "proto3";
这里面的内容不得更改,是官方标准,资料见后文
这里编译一下项目,以便自动生成代码。
然后,添加一个服务的实现类HealthCheckService
{ 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}); } }public class HealthCheckService:Health.HealthBase
示例代码直接返回了检查结果,实际使用中应该在这里编写检查逻辑,然后根据情况返回相应的检查结果。检查结果有3种情况:
最后别忘了注册服务:
4.测试运行
启动 GRPC 服务
然后访问http://localhost:8500/ui
访问 Consul 控制台
可以看到服务成功注册,并且健康检查也是通过了的。通过控制台日志,还可以看到健康检查的请求:
六. 客户端使用服务发现
客户端项目安装Consul
组件,然后改造下代码:
{ 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($"未发现服务 {serviceName}"); } var service = services.Response[0]; var address = $"http://{service.ServiceAddress}:{service.ServicePort}"; Console.WriteLine($"获取服务地址成功:{address}"); //启用通过http使用http2.0 AppContext.SetSwitch( ".Http.SocketsHttpHandler.Http2UnencryptedSupport", true); var channel = GrpcChannel.ForAddress(address); var catClient = new LuCat.LuCatClient(channel); var catReply = await catClient.SuckingCatAsync(new Empty()); Console.WriteLine("调用撸猫服务:"+ catReply.Message); Console.ReadKey(); }static async Task Main(string[] args)
通过服务名称获取服务地址,然后来进行访问。
运行测试:
可以看到,成功的从Consul获取了我们的服务地址,然后调用。
六. 参考资料
gRPC in Core :官方文档
GPRC Health Check Doc:点我
本文 Demo:点我
本系列文章目录:点我
NConsul:/stulzq/NConsul
.NET Core微服务之基于Consul实现服务治理by Edison Zhou
如果觉得《ASP.NET Core gRPC 使用 Consul 服务注册发现》对你有帮助,请点赞、收藏,并留下你的观点哦!