专栏首页晓晨的专栏ASP.NET Core gRPC 使用 Consul 服务注册发现

ASP.NET Core gRPC 使用 Consul 服务注册发现

一. 前言

gRPC 在当前最常见的应用就是在微服务场景中,所以不可避免的会有服务注册与发现问题,我们使用gRPC实现的服务可以使用 Consul 或者 etcd 作为服务注册与发现中心,本文主要介绍Consul。

二. Consul 介绍

Consul是一种服务网络解决方案,可跨任何运行平台以及公共或私有云来连接和保护服务。它可以让你发现服务并保护网络流量。它可以在Kubernetes中使用,实现服务发现和服务网格功能(k8s默认etcd)。 提供安全服务通讯,保护和观察服务之间的通信,而无需修改其代码。 提供动态负载平衡, 使用Consul和HAProxy,Nginx或F5自动执行负载均衡器配置。 Consul 可以用于服务发现和服务网格。

翻译自官网

三. Consul 安装配置

安装

Consul 下载地址: https://www.consul.io/downloads.html

根据自己的系统来选择,我这里选择的是 Windows 版本的,直接解压即可运行。

启动

consul agent -dev -ui

本文不详细介绍Consul使用,如需请自行查看相关资料

四. .NET Core Consul 客户端的选择

Consul 提供了 HTTP API 的方式来进行通讯,我们可以直接调用API或者是使用第三方封装好的客户端组件,通过Nuget搜索可以发现许多。

这里面我没有一一测试,但是目前使用量最多的 Consul 组件是不支持设置 GRPC 健康检查的,而且 github 也停止了更新。

所以我 Fork 了这个仓库,然后添加了 GRPC 的健康检查支持,本文也将使用这个库,欢迎大家使用:

因为原仓库已经 Archived 了,所以我才 Fork 了自己改一下,改动很小,不影响原来的稳定性。

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

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

求个star

关于支持 GPRC 健康检查的好处:

偷个懒,不翻译了,摘自GRPC官方文档

五. 注册GRPC服务与健康检查

基于前文(ASP.NET Core 使用gRPC)的Demo

1.为服务端项目安装 NConsul.AspNetCore ( https://www.nuget.org/packages/NConsul.AspNetCore )

这里面对 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"});
}

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);
}

这里面的内容不得更改,是官方标准,资料见后文

这里编译一下项目,以便自动生成代码。

然后,添加一个服务的实现类 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});
    }
}

示例代码直接返回了检查结果,实际使用中应该在这里编写检查逻辑,然后根据情况返回相应的检查结果。检查结果有3种情况:

结果类型

说明

Unknown

未知状态

Serving

正常

NotServing

异常,不能提供服务

最后别忘了注册服务:

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("调用撸猫服务:"+ catReply.Message);
    Console.ReadKey();
}

通过服务名称获取服务地址,然后来进行访问。

运行测试:

可以看到,成功的从Consul获取了我们的服务地址,然后调用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 微服务的4个设计原则和19个解决方案

    晓晨
  • ASP.NET Core 依赖注入(DI)简介

    晓晨
  • .net core 实现简单爬虫—抓取博客园的博文列表

    晓晨
  • 什么是微服务?为什么你要用微服务?

    最近几年微服务很火,大家都在建设微服务,仿佛不谈点微服务相关的技术,都显得不是那么主流了。

    phoenix.xiao
  • CRM重构之——微服务设计导读(一)

    在介入正题前,想谈一下如何阅读,因为技术类的文章虽好,但需要一定的门槛,而且会比较枯燥,读后可能很快就会忘记读了什么,只记得读过。 导读 阅 带着兴趣 带着兴趣...

    企鹅号小编
  • 安防摄像机监控网页无插件视频直播综合管理平台EasyNVS如何对服务设备信息进行修改

    运维产品是平安城市发展到一定阶段的必然产物,用户花了大量经费来建设平安城市,随着前端、网络、存储、共享平台、实战平台、智能分析平台等建设的日趋完善,运行维护工作...

    EasyNVR
  • 微服务落地反思以及有效落地

    DevOps时代
  • 微服务系列笔记之什么是微服务

    微服务(Microservice Architecture)是近几年流行的一种架构思想,它的概念没有很明确的指出。ThoughtWorks 公司的首席科学家 M...

    陌无崖
  • 不是银弹:关于微服务的一点思考

    在 reddit 上看到一篇文章(被标题吸引了) Monoliths are the future——作者在吐槽微服务。

    linjinhe
  • 拆解交易系统--性能优化,安全加固与弹性扩缩容

    前几篇文章我们拆解了交易系统架构层次的设计方案,对于代码细节我们讨论很很少,今天基于几个方面简短的介绍一下,未来有时间可以针对性的进行扩展讲解。

    春哥大魔王

扫码关注云+社区

领取腾讯云代金券