zoukankan      html  css  js  c++  java
  • .NET 5.0实现Consul服务注册

    Consul是什么:(来自官方翻译)

      Consul 是一种服务网格解决方案,提供具有服务发现、配置和分段功能的全功能控制平面。这些功能中的每一个都可以根据需要单独使用,也可以一起使用以构建完整的服务网格。Consul 需要一个数据平面并支持代理和本地集成模型。Consul 附带一个简单的内置代理,因此一切都可以开箱即用,而且还支持 3rd 方代理集成,例如 Envoy。

    Consul 的主要特点:(来自官方翻译)

    • 服务发现:Consul 的客户端可以注册一个服务,例如 apimysql,其他客户端可以使用 Consul 来发现给定服务的提供者。使用 DNS 或 HTTP,应用程序可以轻松找到它们所依赖的服务。

    • 健康检查:Consul 客户端可以提供任意数量的健康检查,要么与给定的服务相关联(“网络服务器是否返回 200 OK”),要么与本地节点(“内存利用率是否低于 90%”)相关联。操作员可以使用此信息来监控集群健康状况,并且服务发现组件可以使用它来将流量路由到不健康的主机之外。

    • KV 存储:应用程序可以将 Consul 的分层键/值存储用于多种目的,包括动态配置、功能标记、协调、领导选举等。简单的 HTTP API 使其易于使用。

    • 安全服务通信:Consul 可以为服务生成和分发 TLS 证书,以建立相互的 TLS 连接。 意图可用于定义允许哪些服务进行通信。可以通过实时更改意图轻松管理服务分段,而不是使用复杂的网络拓扑和静态防火墙规则。

    • 多数据中心:Consul 支持开箱即用的多个数据中心。这意味着 Consul 的用户不必担心构建额外的抽象层以扩展到多个区域。

    Consul 旨在对 DevOps 社区和应用程序开发人员友好,使其非常适合现代、弹性的基础设施。

     

    一.安装Consul

    进入/usr/local/src目录

    cd /usr/local/src

     下载consul安装压缩包

    wget http://releases.hashicorp.com/consul/1.10.1/consul_1.10.1_linux_amd64.zip

    解压压缩包到当前目录

    unzip consul_1.10.1_linux_amd64.zip 

     解压后有一个名字为consul的可执行文件

     查看版本号

    ./consul --version

     版本号为v1.10.1

    创建consul.server目录,并把consul文件移动到coonsul.server目录

    mkdir consul.server
    
    mv consul consul.server

     

    在consul.server目录里创建consul.d目录

    cd consul.server
    
    mkdir consul.d

    在consul.d目录中创建webservice.json文件

    cd consul.d/
    
    touch webservice.json

    ./consul agent -server -ui -bootstrap-expect=1 -data-dir=/usr/local/src/consul.server -node=agent-one -advertise=172.19.43.49 -bind=0.0.0.0 -client=0.0.0.0

     访问8500端口即可看到consul注册节点

     二.注册服务

    创建一个.NET Core工程,添加Consul包。

    添加一个名为HealthController的控制器,并实现一个get请求的接口用于服务健康检查,接口返回StatusCode为200。

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace Pudefu.Web.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class HealthController : ControllerBase
        {
            [HttpGet]       
            public JsonResult Get()
            {
                return new JsonResult("OK");
            }
        }
    }

    在配置文件appsettings.json添加配置

      "ConsulConfig": {
        "ServiceId": "d72e7de8b01a43acac640b1a00b26c81",
        "ServiceName": "pudefu.web",
        "ServiceIP": "xxx.xx.xxx.xx",//当前应用部署的服务器IP地址
        "ServicePort": 8000,//当前应用部署的服务器端口
        "ConsulIP": "xxx.xx.xxx.xx",//Consul部署的服务器IP地址
        "ConsulPort": 8500//Consul端口
      }

    添加服务配置模型

    public class ServiceConfig
        {
            /// <summary>
            /// 服务唯一ID
            /// </summary>
            public string ServiceId { get; set; }
            /// <summary>
            /// 服务部署的IP
            /// </summary>
            public string ServiceIP { get; set; }
            /// <summary>
            /// 服务部署的端口
            /// </summary>
            public int ServicePort { get; set; }
            /// <summary>
            /// 服务名称
            /// </summary>
            public string ServiceName { get; set; }
            /// <summary>
            /// consul部署的IP
            /// </summary>
            public string ConsulIP { get; set; }
            /// <summary>
            /// consul端口
            /// </summary>
            public int ConsulPort { get; set; }
        }

    添加Consul注册类

    public static class AppBuilderExtensions
        {
            public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IHostApplicationLifetime lifetime, ServiceConfig serviceConfig)
            {
                var consulClient = new ConsulClient(x => x.Address = new Uri($"http://{serviceConfig.ConsulIP}:{serviceConfig.ConsulPort}"));
                var httpCheck = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服务器启动5秒后注册
                    Interval = TimeSpan.FromMinutes(1),//每分钟检测一次(健康检查间隔时间)
                    HTTP = $"http://{serviceConfig.ServiceIP}:{serviceConfig.ServicePort}/api/health",//本服务健康检查地址
                    Timeout = TimeSpan.FromSeconds(20),
                };
                var registerAgent = new AgentServiceRegistration()
                {
                    Check = httpCheck,
                    Checks = new[] { httpCheck },
                    ID = serviceConfig.ServiceId,//一定要指定服务ID,否则每次都会创建一个新的服务节点
                    Name = serviceConfig.ServiceName,
                    Address = serviceConfig.ServiceIP,
                    Port = serviceConfig.ServicePort,
                    Tags = new[] { $"urlprefix-/{serviceConfig.ServiceName}" }//添加 urlprefix-/servicename 格式的tag标签,以便Fabio识别
                };
                consulClient.Agent.ServiceRegister(registerAgent).Wait();//服务启动时注册,使用Consul API进行注册(HttpClient发起)
                lifetime.ApplicationStopped.Register(() =>
                {
                    consulClient.Agent.ServiceDeregister(registerAgent.ID).Wait();//服务器停止时取消注册
                });
                return app;
            }
        }

    在Startup中添加注册代码

            public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime lifetime)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
    
                //app.UseHttpsRedirection();
                //DefaultFilesOptions defaultFilesOptions = new DefaultFilesOptions();
                //defaultFilesOptions.DefaultFileNames.Clear();
                //defaultFilesOptions.DefaultFileNames.Add("Index.html");
                //app.UseDefaultFiles(defaultFilesOptions);
    
                app.UseStaticFiles();
    
                app.UseRouting();
    
                app.UseAuthorization();
    
                var serviceConfig = Configuration.GetSection("ConsulConfig").Get<ServiceConfig>();
                app.RegisterConsul(lifetime, serviceConfig);
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapDefaultControllerRoute();
                    endpoints.MapRazorPages();
                });
            }

     发布启动后,可见以下注册成功的服务

    点击pudefu.web(服务名称)这个服务可以查看服务详细信息

    服务健康检查成功:

     服务健康检查失败:

  • 相关阅读:
    pandas 修改指定列中所有内容
    Python 实现获取【昨天】【今天】【明天】日期
    Selenium定位不到指定元素原因之iframe(unable to locate element)
    Pandas 通过追加方式合并多个csv
    python setup.py install 报错:error: [WinError 3] 系统找不到指定的路径。: 'C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\PlatformSDK\lib
    pandas 如何判断指定列是否(全部)为NaN(空值)
    报错:PermissionError: [WinError 5] Access is denied: 'C:\Program Files\Anaconda3\Lib\site-packages\pywebhdfs'
    Node.js的函数返回值
    在Eclipse中使用JSHint检查JavaScript
    Node.js前端自动化工具:gulp
  • 原文地址:https://www.cnblogs.com/pudefu/p/15034011.html
Copyright © 2011-2022 走看看