.NET Core(.NET6)中gRPC注册到Consul详解

2022年5月19日12:19:47

一、简介

上一篇文章介绍了.NET Core 中使用gRPC,在微服务中,我们通常要把服务做成服务注册,服务发现的方式,那么这里来说一下gRPC是如何注册到Consul中的。

Consul的安装这里就不介绍了,在之前的篇文章中已经写过:Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现

这里Consul已经安装好。

.NET Core(.NET6)中gRPC注册到Consul详解

 二、gRPC注册到Consul

1.扩展gRPC注册到Consul封装类

这里沿用上一篇的gRPC的代码,如果服务带api和gRPC的话用http的方式或gRPC的方式注册到可以,http的方式上面文章中的Consul注册和发现中已经有,这里介绍单gRPC的服务的注册。

先在appsettings.json中加入Consul信息代码

{"Logging": {"LogLevel": {"Default":"Information","Microsoft.AspNetCore":"Warning"
    }
  },"AllowedHosts":"*","Kestrel": {"EndpointDefaults": {"Protocols":"Http2"
    }
  },"Consul": {
    "consulAddress": "http://127.0.0.1:8500",
    "serviceName": "api_gRPC",
    "currentIp": "127.0.0.1",
    "currentPort": "5246"
  }
}

然后新建ConsulRegister.cs封装注册到Consul的类

///<summary>/// Consul注册///</summary>publicstaticclass ConsulRegister
    {//服务注册publicstatic IApplicationBuilder UseConsul(this IApplicationBuilder app, IConfiguration configuration)
        {// 获取主机生命周期管理接口var lifetime = app.ApplicationServices.GetRequiredService<IHostApplicationLifetime>();

            ConsulClient client=new ConsulClient(c =>
            {
                c.Address=new Uri(configuration["Consul:consulAddress"]);
                c.Datacenter="dc1";
            });string ip = configuration["ip"];//优先接收变量的值string port = configuration["port"];//优先接收变量的值string currentIp = configuration["Consul:currentIP"];string currentPort = configuration["Consul:currentPort"];

            ip=string.IsNullOrEmpty(ip) ? currentIp : ip;//当前程序的IP
            port =string.IsNullOrEmpty(port) ? currentPort : port;//当前程序的端口string serviceId = $"service:{ip}:{port}";//服务ID,一个服务是唯一的//服务注册
            client.Agent.ServiceRegister(new AgentServiceRegistration()
            {
                ID= serviceId,//唯一的
                Name = configuration["Consul:serviceName"],//组名称-Group
                Address = ip,//ip地址
                Port =int.Parse(port),//端口
                Tags =newstring[] {"api站点" },
                Check=new AgentServiceCheck()
                {
                    Interval= TimeSpan.FromSeconds(10),//多久检查一次心跳
                    GRPC = $"{ip}:{port}",//gRPC注册特有
                    GRPCUseTLS=false,//支持http
                    Timeout = TimeSpan.FromSeconds(5),//超时时间
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5)//服务停止多久后注销服务                }

            }).Wait();//应用程序终止时,注销服务
            lifetime.ApplicationStopping.Register(() =>
            {
                client.Agent.ServiceDeregister(serviceId).Wait();
            });return app;
        }
    }

Program.cs增加使用这个扩展类

using GrpcDemo.Service.Services;using GrpcDemo.Service.Utils;var builder = WebApplication.CreateBuilder(args);// Additional configuration is required to successfully run gRPC on macOS.// For instructions on how to configure Kestrel and gRPC clients on macOS, visithttps://go.microsoft.com/fwlink/?linkid=2099682// Add services to the container.builder.Services.AddGrpc();var app = builder.Build();
IConfiguration _configuration= builder.Configuration;// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGrpcService<OrderService>();
app.MapGrpcService<HealthCheckService>();
app.MapGet("/", () =>"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");app.UseConsul(_configuration);
app.Run();

2.创建健康检查gRPC服务

1.新建健康检查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);
}

2.新建健康检查服务实现上面proto协议HealthCheckService.cs

publicclass HealthCheckService : Health.HealthBase
    {publicoverride Task<HealthCheckResponse> Check(HealthCheckRequest request, ServerCallContext context)
        {
            Console.WriteLine($"This is {nameof(HealthCheckService)} Check");//TODO:检查逻辑return Task.FromResult(new HealthCheckResponse() { Status = HealthCheckResponse.Types.ServingStatus.Serving });
        }publicoverrideasync Task Watch(HealthCheckRequest request, IServerStreamWriter<HealthCheckResponse> responseStream, ServerCallContext context)
        {//TODO:检查逻辑await responseStream.WriteAsync(new HealthCheckResponse()
            { Status= HealthCheckResponse.Types.ServingStatus.Serving });
        }
    }

3.在Program.cs中把服务注册到gRPC管道

using GrpcDemo.Service.Services;using GrpcDemo.Service.Utils;var builder = WebApplication.CreateBuilder(args);// Additional configuration is required to successfully run gRPC on macOS.// For instructions on how to configure Kestrel and gRPC clients on macOS, visithttps://go.microsoft.com/fwlink/?linkid=2099682// Add services to the container.builder.Services.AddGrpc();//配置获取var app = builder.Build();
IConfiguration _configuration= builder.Configuration;// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGrpcService<OrderService>();app.MapGrpcService<HealthCheckService>();
app.MapGet("/", () =>"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");

app.UseConsul(_configuration);
app.Run();

到这里服务注册就完成了,服务发现和上面简介的链接文章中一模一样,启动项目查看效果。

.NET Core(.NET6)中gRPC注册到Consul详解

.NET Core(.NET6)中gRPC注册到Consul详解

  • 作者:包子wxl
  • 原文链接:https://www.cnblogs.com/wei325/p/16154607.html
    更新时间:2022年5月19日12:19:47 ,共 4562 字。