微服务-基于Grpc的进程通信-Grpc服务注册与发现 (4-2)

在上一篇《微服务-基于Grpc的进程通信-简单使用 (4)》中,简单介绍了Grpc的使用,本文继续深入,完善Consul的注册和发现功能

1.引入包NConsul.AspNetCore
 
2.Grpc服务注册
创建NConsulHelper帮助类
 1 public static async Task UseGRPCConsul(this IApplicationBuilder app, ConsulConfigModel consulConfigModel, HealConfigMol healConfigMol)
 2 {
 3     using ConsulClient nconsulClient = new ConsulClient(c =>
 4     {
 5         c.Address = new Uri($"http://{consulConfigModel.IP}:{consulConfigModel.Port}");
 6         c.Datacenter = "dc1";
 7     });
 8 
 9     await nconsulClient.Agent.ServiceRegister(new AgentServiceRegistration()
10     {
11         ID = "grpcserviceID" + healConfigMol.IP + ":" + healConfigMol.CheckPort,
12         Name = healConfigMol.GroupName,
13         Address = healConfigMol.IP,
14         Port = healConfigMol.CheckPort,
15         Tags = healConfigMol.Tag,
16         Check = new AgentServiceCheck()
17         {
18             Interval = TimeSpan.FromSeconds(12),
19             Timeout = TimeSpan.FromSeconds(5),
20             DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(20),
21             GRPC = $"{healConfigMol.IP}:{ healConfigMol.CheckPort}",
22             GRPCUseTLS = false
23         }
24 
25     });
26 }
创建 ConsulConfigModel类
public class ConsulConfigModel
{
    public string IP { get; set; }

    public int Port { get; set; }
}

创建 HealConfigMol类

1 public class HealConfigMol
2 {
3     public string GroupName { get; set; }
4     public string IP { get; set; }
5     public int Port { get; set; }
6     public int CheckPort { get; set; }
7     public string[] Tag { get; set; }
8 }

3.Grpc服务的健康检查

安装官方健康检查组件,Grpc.HealthCheck
添加实现类 HealthCheckService继承 Health.HealthBase,重写方法
 1 public class HealthCheckService : Health.HealthBase
 2 {
 3     public override Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
 4     {
 5         //TODO:检查逻辑
 6         return Task.FromResult(new HealthCheckResponse() { Status = HealthCheckResponse.Types.ServingStatus.Serving });
 7     }
 8     
 9     public override async Task Watch(HealthCheckRequest request, IServerStreamWriter<HealthCheckResponse> responseStream, ServerCallContext context)
10     {
11         //TODO:检查逻辑
12         await responseStream.WriteAsync(new HealthCheckResponse()
13         { Status = HealthCheckResponse.Types.ServingStatus.Serving });
14     }
15 }
 
4.Startup.cs配置
 1  app.UseGRPCConsul(
 2             new ConsulConfigModel() { IP = "127.0.0.1", Port = 8500 },
 3             new HealConfigMol
 4             {
 5                 IP = this.Configuration["ip"],
 6                 Port = int.Parse(this.Configuration["Port"]),
 7                 CheckPort = int.Parse(this.Configuration["Port"]),
 8                 GroupName = "GRpcGroupName",
 9                 Tag = new string[] { "Tag" }  
10             });
11       
endpoints.MapGrpcService<HealthCheckService>();
 
5.Consul验证
启动Consul
 

 

 打开http://lcoahost:8500,如下图所示

运行MicService.GrpcServe,cmd中输入命令行:
dotnet MicService.GrpcServer.dll --port=8200 --ip="127.0.0.1" --url="https://*:8200"
 
再次查看Consul界面,GrpcGroupName的服务注册成功,健康检查通过
 

 

 

6.Grpc服务发现
Grpc注册成功后,在客户端通过Consul发现该服务,实际的集群使用过程中,可以配置权重策略实现负载。
客户端引入Consul包
代码如下: 
 1 #region Consul发现
 2 string url = "http://GRpcGroupName";
 3 ConsulClient client = new ConsulClient(s =>
 4 {
 5     s.Address = new Uri("http://127.0.0.1:8500");
 6     s.Datacenter = "dc1";
 7 });
 8 var response = client.Agent.Services().Result.Response;
 9 
10 Uri uri = new Uri(url);
11 string groupame = uri.Host;
12 AgentService agentService = null;
13 
14 var serviceDictionary = response.Where(s => s.Value.Service.Equals(groupame, StringComparison.OrdinalIgnoreCase)).ToArray();
15 {
16 
17     //有多个服务 选择一个 用到负载均衡策略 此处省略策略实现
18 
19     agentService = serviceDictionary[0].Value;
20 }
21 url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}";
22 #endregion
23 
24 
25 AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
26 
27 //创建通道
28 var channel = GrpcChannel.ForAddress(url);
29 
30 //创建客户端代理
31 var clienter = new GreeterClient(channel);
32 
33 //服务端调用
34 var reply = await clienter.SayHelloAsync(new HelloRequest { Name = "客户端传参" });
35 
36 Console.WriteLine(reply.Message);
37 
38 Console.ReadLine();

 

服务端和客服端基本调试完成,但实际开发中,proto文件的拷贝和ItemGroup配置较为繁琐,不适合扩展,引入protobuf-net.Grpc用来简化Grpc的开发
 
以上仅用于学习和总结。
 
参考文档:
 
附源码:
链接:https://pan.baidu.com/s/1NVcb52dGokDP7yODTlNSwg
提取码:yttu

posted @ 2021-01-28 23:39  y_w_k  阅读(761)  评论(0编辑  收藏  举报