首页 > 其他分享 >.Net 使用 Consul

.Net 使用 Consul

时间:2024-09-11 17:52:12浏览次数:11  
标签:string Consul consulClient serviceId 使用 var new Net

Consul windows部署见上篇 Consul Windows部署 - 咸鱼翻身? - 博客园 (cnblogs.com)

一、创建Web API 项目并安装Consul包

打开命令行并运行以下命令创建一个新的 Web API 项目:

dotnet new webapi -n ConsulDemo
cd ConsulDemo
dotnet add package Consul
dotnet add package Microsoft.AspNetCore.HealthChecks.UI

二、配置 Consul 客户端

创建一个服务来注册Web API 到 Consul。可以在 Program.cs 中进行配置

Consul 客户端只能接受一个地址,因此需要实现一个逻辑,在连接失败时轮询下一个 Consul 服务器。这里是一个简单的策略,尝试多个 Consul 服务器地址:

(一) ConsulHelper.cs

using Consul;

public class ConsulHelper
{
    private readonly string[] _consulServers;

    public ConsulHelper(string[] consulServers)
    {
        _consulServers = consulServers;
    }

    // 连接到 Consul 并返回连接的 ConsulClient
    public async Task<ConsulClient> ConnectConsulAsync()
    {
        foreach (var server in _consulServers)
        {
            try
            {
                var consulClient = new ConsulClient(config =>
                {
                    config.Address = new Uri(server);
                });

                // 测试连接
                var services = await consulClient.Agent.Services();
                Console.WriteLine($"Connected to Consul at {server}");
                return consulClient;
            }
            catch (HttpRequestException)
            {
                Console.WriteLine($"Failed to connect to Consul at {server}, trying next...");
            }
        }

        throw new Exception("Failed to connect to any Consul servers.");
    }

    // 注册服务到 Consul
    public async Task RegisterServiceAsync(ConsulClient consulClient, string serviceId, string serviceName, string address, int port, string[] tags = null)
    {
        var registration = new AgentServiceRegistration()
        {
            ID = serviceId,
            Name = serviceName,
            Address = address,
            Port = port,
            Tags = tags ?? new[] { "api", serviceName },
            Check = new AgentServiceCheck
            {
                HTTP = $"http://{address}:{port}/health",
                Interval = TimeSpan.FromSeconds(10),
                Timeout = TimeSpan.FromSeconds(5)
            }
        };

        await consulClient.Agent.ServiceRegister(registration);
        Console.WriteLine($"Service {serviceName} registered with ID {serviceId}");
    }

    // 注销服务
    public async Task DeregisterServiceAsync(ConsulClient consulClient, string serviceId)
    {
        await consulClient.Agent.ServiceDeregister(serviceId);
        Console.WriteLine($"Service {serviceId} deregistered");
    }
}

(二) Program.cs

using Microsoft.Extensions.Diagnostics.HealthChecks;

var builder = WebApplication.CreateBuilder(args);

// 添加必要的服务
builder.Services.AddControllers();

// 添加健康检查服务
builder.Services.AddHealthChecks()
    .AddCheck("self", () => HealthCheckResult.Healthy("The service is healthy"));

// 创建应用
var app = builder.Build();

// Consul 服务器集群地址
var consulServers = new[]
{
    "http://consul-server-1:8500",
    "http://consul-server-2:8500",
    "http://consul-server-3:8500"
};

// 创建 ConsulHelper 实例
var consulHelper = new ConsulHelper(consulServers);

// 连接到 Consul 并注册服务
var serviceId = $"my-api-20240911";
var consulClient = await consulHelper.ConnectConsulAsync();
await consulHelper.RegisterServiceAsync(consulClient, serviceId, "my-api-service", "<本机ip>", 5048);

// 在应用关闭时注销服务
app.Lifetime.ApplicationStopping.Register(async () =>
{
    await consulHelper.DeregisterServiceAsync(consulClient, serviceId);
});

// 配置 HTTP 请求管道
app.MapControllers();
app.MapHealthChecks("/health");

// 启动应用
app.Run();

运行项目并查看Consul ui

三、客户端调用

(一) 创建控制台项目

使用 .NET CLI 创建控制台项目:

dotnet new console -n ConsulServiceDiscoveryConsole
cd ConsulServiceDiscoveryConsole
dotnet add package Consul

(二) 创建 ConsulServiceDiscovery 类

在控制台项目中创建一个 ConsulServiceDiscovery 类,用来从 Consul 获取已注册的服务。

ConsulServiceDiscovery.cs

using Consul;
using System;
using System.Linq;
using System.Threading.Tasks;

public class ConsulServiceDiscovery
{
    private readonly ConsulClient _consulClient;

    public ConsulServiceDiscovery(string consulAddress)
    {
        // 初始化 Consul 客户端
        _consulClient = new ConsulClient(config =>
                                         {
                                             config.Address = new Uri(consulAddress);
                                         });
    }

    // 获取服务实例的地址
    public async Task<Uri> GetServiceUriAsync(string serviceName, string tag = null)
    {
        // 查询 Consul 中的服务
        var queryResult = await _consulClient.Health.Service(serviceName, tag, passingOnly: true);

        // 选择一个健康的服务实例
        var service = queryResult.Response.FirstOrDefault();

        if (service == null)
        {
            throw new Exception($"Service {serviceName} not found in Consul.");
        }

        var address = service.Service.Address;
        var port = service.Service.Port;

        // 返回服务的 URI
        return new Uri($"http://{address}:{port}");
    }
}

(三) 更新 Program.cs

Program.cs 中使用 ConsulServiceDiscovery 来从 Consul 获取服务信息,并调用 Web API。

Program.cs

class Program
{
    static async Task Main(string[] args)
    {
        // Consul 服务器地址
        string consulAddress = "http://<consul地址>";  // 这里直接取其中一个,如需负载,可轮询或其他方式

        // 创建 ConsulServiceDiscovery 实例
        var serviceDiscovery = new ConsulServiceDiscovery(consulAddress);

        // 目标服务名称(注册到 Consul 中的服务名称)
        string serviceName = "my-api-service";  // 你注册到 Consul 的 Web API 服务名称

        try
        {
            // 获取 Web API 服务的地址
            var serviceUri = await serviceDiscovery.GetServiceUriAsync(serviceName);
            Console.WriteLine($"Discovered service at: {serviceUri}");

            // 使用 HttpClient 进行调用
            var httpClient = new HttpClient();
            string url = $"{serviceUri}health";
            var result = await httpClient.GetStringAsync(url);
            Console.WriteLine($"Service response: {result}");
            Console.ReadKey();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Service discovery failed: {ex.Message}");
        }
    }
}

返回Healthy 调用成功。

标签:string,Consul,consulClient,serviceId,使用,var,new,Net
From: https://www.cnblogs.com/mchao/p/18408638

相关文章

  • Consul Windows部署
    一、Consul下载下载地址:Install|Consul|HashiCorpDeveloper本次使用Windows版本下载解压后,可看到consul.exe文件二、ConsulServer配置为了方便使用增加server-config.hcl和server-start.bat文件(一)server-config.hcl配置文件#节点名称node_name="my-consul......
  • 从注册到实战,超简单图床使用(附代码实现本地图片转换为网络url)
    1.注册一个薄荷图床的的账号,并添加客服申请api测试权限​ 查看api文档 我们只需关注两个必选参数即可,如图中红色标注2.编写pthon代码​ 其他语言也可以,只要发送post请求即可,注意url、token和照片需要更改为你自己的importrequestsdefpython_demo():url='https://......
  • 使用Java实现字符串中的表达式计算
    /***计算字符串表达式的值,不支持小数*<ul>*<li>加法('+')</li>*<li>减法('-')</li>*<li>乘法('*')</li>*<li>除法,保留两位小数('/')</li>*<li>取余,获取商('......
  • 6. 使用 lan口连接上层路由器的lan ,实现openwrt联网
    参考网友帖子:OpenWrt中,旁路由的设置与使用-知乎(zhihu.com)openwrt旁路由设置的正确方式-CSDN博客三分钟搞定OpenWrt网关(旁路由)模式设置小白必备教程适用于N1及所有旁路由设备-斐讯无线路由器以及其它斐迅网络设备-恩山无线论坛(right.com.cn) 配置如下:......
  • Vue中过滤器的使用
    下面是一个日期格式的过滤器用moment.js来做的一个日期过滤器:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><......
  • Ethereum学习笔记 ---- 使用 Remix 调试功能理解 bytes 在 memory 中的布局
    目录编写合约编译、部署、调用合约调试交易1.调用函数bytesInMemory(),分析bytes的MemoryLayout执行RETUR前的最后一刻,stack快照如下执行完毕时刻的MemoryLayout对MemoryLayout的分析2.调用函数bytesArrayInMemmory(4),分析bytes[]的MemoryLayout执行RETUR前......
  • Vue中列表渲染中的v-for的使用
    v-for的使用:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>Document</tit......
  • 使用W外链创建微信短链接的方法
    创建短链是将长链接转换为更短、更易于分享和记忆的链接的过程。W外链是一个提供短链接生成服务的平台,它支持多种功能,包括但不限于:短链制作:用户可以将长链接缩短为易于分享的短链接,还支持自定义短链后缀。防红防封:通过技术手段对原始链接进行加密和伪装,以绕过一些限制和屏蔽......
  • YOLOv9改进策略【Neck】| 使用CARAFE轻量级通用上采样算子
    一、本文介绍本文记录的是利用CARAFE上采样对YOLOv9的颈部网络进行改进的方法研究。YOLOv9采用传统的最近邻插值的方法,仅考虑子像素邻域,无法捕获密集预测任务所需的丰富语义信息,从而影响模型在密集预测任务中的性能。CARAFE通过在大感受野内聚合信息、能够实时适应实例特定......
  • 超声波 HC-SR04 的使用 CubeMx + STM32F103C8T6 【含两个】
    HC-SR04的使用一、超声波模块介绍二、工作原理介绍三、接线方式四、驱动方式方法一方法二五、程序实现串口查看数据方法一HC_SR04.cHC_SR04.hmain.cmain.h串口数据显示方法二main.cmain.h六、数据处理一、超声波模块介绍HC-SR04是一种常用的超声波测距模块。......