I. Introduction

The most common application of gRPC is in the microservices scenario, so service registration and discovery problems are inevitable. The services we use gRPC can use Consul or etcd as service registration and discovery centers. This article mainly introduces Consul.

Consul Introduction

Consul is a service network solution that connects and protects services across any operating platform and public or private cloud. It lets you discover services and protect network traffic. It can be used in Kubernetes to implement service discovery and service grid functions (k8s default etcd). Provides security service communications, protecting and observing communications between services without modifying their code. Provides dynamic load balancing, using Consul and HAProxy, Nginx or F5 to automatically perform load balancer configuration. Consul can be used for service discovery and service grids.

Translated from official website

Three. Consul installation and configuration

installation

Consul download address:
https://www.consul.io/downloads.html

Choose according to your own system, I chose the Windows version here, and you can run it directly by decompressing it.

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_0.png

start up

consul agent -dev -ui

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_1.png

This article does not introduce the use of Consul in detail.

Choice of .NET Core Consul Client

Consul provides HTTP API for communication. We can directly call the API or use a third-party packaged client component. Nuget search can find many.

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_2.png

There I did eleven test, but currently the most amount of Consulcomponents does not support setting GRPC health check, and also stopped updating github.

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_3.png

So I fork this repository and then add GRPC health check support . This library will also be used in this article. Welcome everyone:

Because the original warehouse is already Archived, I just fork it and change it myself. The changes are small and do not affect the original stability.

Nuget:
https://www.nuget.org/packages/NConsul/

Github:
https://github.com/stulzq/NConsul

Find a star

About the benefits of supporting GPRC health checks:

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_5.png

Lazy, not translating, from the GRPC official documentation

V. Registration of GRPC Service and Health Check

Demo based on the previous article (
ASP.NET Core uses gRPC

)

1. Install for server project NConsul.AspNetCore(
https://www.nuget.org/packages/NConsul.AspNetCore

)

Adapted to AspNetCore here, easy to use.

2. Startup the ConfigureServicesconfiguration method of the

public void ConfigureServices(IServiceCollection services)
{
    services.AddGrpc();

    services.AddConsul("http://localhost:8500")
        .AddGRPCHealthCheck("localhost:5000")
        .RegisterService("grpctest","localhost",5000,new []{"xc/grpc/test"});
}

AddConsul Add the Consul Server address.

AddGRPCHealthCheckAdd GRPC health checks, health checks that is taking the GRPC agreement, the value GRPC address of the service, does not require path , do not need to provide http / https

RegisterService Registration service

At this point, you cannot start running. If you run a health check, it will fail.

3. Writing a Health Check service **

For the health check of GRPC, the official has a standard definition , create a new proto file and name itHealthCheck.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);
}

The content in it must not be changed. It is an official standard.

Compile the project here to generate code automatically.

Then, add a service implementation class 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:logic check
        await responseStream.WriteAsync(new HealthCheckResponse()
            {Status = HealthCheckResponse.Types.ServingStatus.Serving});
    }
}

The sample code directly returns the inspection results. In actual use, you should write the inspection logic here, and then return the corresponding inspection results according to the situation. There are three cases of inspection results:





Result type
Description




Unknown
Unknown state


Serving
normal


NotServing
Exception, cannot provide service


Finally don’t forget to register for the service:

4. Test run

Start the GRPC service

Then visit http://localhost:8500/uivisit Consul console

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_7.png

You can see that the service is successfully registered and the health check has passed. From the console log, you can also see requests for health checks:

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_8.png

Six. Clients use service discovery

The client program installed Consulcomponents, and then reform under the code:

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($"not found {serviceName}");
    }

    var service = services.Response[0];
    var address = $"http://{service.ServiceAddress}:{service.ServicePort}";

    Console.WriteLine($"get :{address}");

  
    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("call :"+ catReply.Message);
    Console.ReadKey();
}

Get the service address by service name and then access it.

Run the test:

ASP.NET_Core_gRPC_uses_Consul_service_to_register_and_discover_9.png

As you can see, we successfully obtained our service address from Consul and then called it.

Six. References

Orignal link:https://www.cnblogs.com/stulzq/p/11942691.html