一、簡(jiǎn)介
上一篇文章介紹了.NET Core 中使用gRPC,在微服務(wù)中,我們通常要把服務(wù)做成服務(wù)注冊(cè),服務(wù)發(fā)現(xiàn)的方式,那么這里來說一下gRPC是如何注冊(cè)到Consul中的。
Consul的安裝這里就不介紹了,在之前的篇文章中已經(jīng)寫過:Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服務(wù)注冊(cè),服務(wù)發(fā)現(xiàn)
這里Consul已經(jīng)安裝好。
?
?
?二、gRPC注冊(cè)到Consul
1.擴(kuò)展gRPC注冊(cè)到Consul封裝類
這里沿用上一篇的gRPC的代碼,如果服務(wù)帶api和gRPC的話用http的方式或gRPC的方式注冊(cè)到可以,http的方式上面文章中的Consul注冊(cè)和發(fā)現(xiàn)中已經(jīng)有,這里介紹單gRPC的服務(wù)的注冊(cè)。
先在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封裝注冊(cè)到Consul的類
/// <summary> /// Consul注冊(cè) /// </summary> public static class ConsulRegister { //服務(wù)注冊(cè) public static IApplicationBuilder UseConsul(this IApplicationBuilder app, IConfiguration configuration) { // 獲取主機(jī)生命周期管理接口 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"]; //優(yōu)先接收變量的值 string port = configuration["port"]; //優(yōu)先接收變量的值 string currentIp = configuration["Consul:currentIP"]; string currentPort = configuration["Consul:currentPort"]; ip = string.IsNullOrEmpty(ip) ? currentIp : ip; //當(dāng)前程序的IP port = string.IsNullOrEmpty(port) ? currentPort : port; //當(dāng)前程序的端口 string serviceId = $"service:{ip}:{port}";//服務(wù)ID,一個(gè)服務(wù)是唯一的 //服務(wù)注冊(cè) client.Agent.ServiceRegister(new AgentServiceRegistration() { ID = serviceId, //唯一的 Name = configuration["Consul:serviceName"], //組名稱-Group Address = ip, //ip地址 Port = int.Parse(port), //端口 Tags = new string[] { "api站點(diǎn)" }, Check = new AgentServiceCheck() { Interval = TimeSpan.FromSeconds(10),//多久檢查一次心跳 GRPC = $"{ip}:{port}", //gRPC注冊(cè)特有 GRPCUseTLS=false,//支持http Timeout = TimeSpan.FromSeconds(5),//超時(shí)時(shí)間 DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5) //服務(wù)停止多久后注銷服務(wù) } }).Wait(); //應(yīng)用程序終止時(shí),注銷服務(wù) lifetime.ApplicationStopping.Register(() => { client.Agent.ServiceDeregister(serviceId).Wait(); }); return app; } }
Program.cs增加使用這個(gè)擴(kuò)展類
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, visit https://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.創(chuàng)建健康檢查gRPC服務(wù)
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.新建健康檢查服務(wù)實(shí)現(xiàn)上面proto協(xié)議HealthCheckService.cs
public class HealthCheckService : Health.HealthBase { public override 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 }); } public override async Task Watch(HealthCheckRequest request, IServerStreamWriter<HealthCheckResponse> responseStream, ServerCallContext context) { //TODO:檢查邏輯 await responseStream.WriteAsync(new HealthCheckResponse() { Status = HealthCheckResponse.Types.ServingStatus.Serving }); } }
3.在Program.cs中把服務(wù)注冊(cè)到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, visit https://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();
到這里服務(wù)注冊(cè)就完成了,服務(wù)發(fā)現(xiàn)和上面簡(jiǎn)介的鏈接文章中一模一樣,啟動(dòng)項(xiàng)目查看效果。
?
?
?
本文摘自 :https://www.cnblogs.com/