(精华)2020年10月28日 Grpc Grpc对接Consul服务注册发现
一. 前言
gRPC 在当前最常见的应用就是在微服务场景中,所以不可避免的会有服务注册与发现问题,我们使用gRPC实现的服务可以使用 Consul 或者 etcd 作为服务注册与发现中心,本文主要介绍Consul。
二. 注册GRPC服务与健康检查
1.为服务端项目安装 nuget包
NConsul.AspNetCore
2.在 Startup 的 ConfigureServices方法内进行配置
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
services.AddConsul("http://localhost:8500")
.AddGRPCHealthCheck("localhost:5000")
.RegisterService("grpctest","localhost",5000,new []{"xc/grpc/test"});
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
AddConsul :添加 Consul Server 地址。
AddGRPCHealthCheck :添加 GRPC 健康检查,即健康检查走的是 GRPC 协议,该值为 GRPC 服务的地址,不需要path,不需要提供 http/https
RegisterService :注册服务
3.编写 Health Check 服务 **
对于 GRPC 的健康检查,官方有标准的定义,新建一个 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);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
这里编译一下项目,以便自动生成代码。
然后,添加一个服务的实现类 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});
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
示例代码直接返回了检查结果,实际使用中应该在这里编写检查逻辑,然后根据情况返回相应的检查结果。检查结果有3种情况:
结果类型 | 说明 |
---|---|
Unknown | 未知状态 |
Serving | 正常 |
NotServing | 异常,不能提供服务 |
注册服务
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GreeterService>();
endpoints.MapGrpcService<LuCatService>();
endpoints.MapGrpcService<HealthCheckService>();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
});
});
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
4.测试运行
启动 GRPC 服务
然后访问 http://localhost:8500/ui 访问 Consul 控制台
可以看到服务成功注册,并且健康检查也是通过了的。通过控制台日志,还可以看到健康检查的请求:
三. 客户端使用服务发现
客户端项目安装 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($"未发现服务 {serviceName}");
}
var service = services.Response[0];
var address = $"http://{service.ServiceAddress}:{service.ServicePort}";
Console.WriteLine($"获取服务地址成功:{address}");
//启用通过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("调用consul服务:"+ catReply.Message);
Console.ReadKey();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
通过服务名称获取服务地址,然后来进行访问。
运行测试:
可以看到,成功的从Consul获取了我们的服务地址,然后调用。
文章来源: codeboy.blog.csdn.net,作者:愚公搬代码,版权归原作者所有,如需转载,请联系作者。
原文链接:codeboy.blog.csdn.net/article/details/109326769
- 点赞
- 收藏
- 关注作者
评论(0)