1. 程式人生 > 實用技巧 >.net core Ocelot+consul實現閘道器及服務註冊和服務發現

.net core Ocelot+consul實現閘道器及服務註冊和服務發現

  Ocelot是一個用.NET Core實現並且開源的API閘道器。對於閘道器概念不是很清楚的可以參照https://www.jianshu.com/p/7baab672b822,這位大佬講到感覺滿到位哈。

Consul 是 HashiCorp 公司的一個用於實現分散式系統的服務發現與配置工具。Consul內建了服務註冊與發現框 架、分佈一致性協議實現、健康檢查、Key/Value儲存、多資料中心方案。

這篇文章將一步一步介紹如何使用Ocelot+consul實現閘道器及服務註冊和服務發現功能。

  一、我們使用.net core 新建一個閘道器專案和兩個webApi專案。建好後的專案結構如下圖。

  二、ApiGateway是閘道器專案,新增Ocelot和consul包,為了在Ocelot中使用Consul來實現服務發現,這裡需要使用Ocelot提供Consul支援的NuGet包。具體的依賴包如下圖。

ConfigureServices新增Ocelot和Consul的注入,AddJsonFile("ocelot.json")指定了ocelot的配置檔案。

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.AddOcelot(
new ConfigurationBuilder() .AddJsonFile("ocelot.json") .Build()).AddConsul(); }

Configure方法中新增ocelot中介軟體。

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseOcelot();
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints 
=> { endpoints.MapControllers(); }); }

新增ocelot.json配置檔案,可以配置服務發現、路由、負載均很、鑑權、熔斷限流等。這裡只演示路由和服務發現功能,如下圖。

Routes配置路由資訊,"UseServiceDiscovery": true,表示使用服務發現功能,

"DownstreamPathTemplate": "/{url}",
"DownstreamScheme": "http",

指定了下游的url及使用的通訊協議,{url}是通配的意思。

"ServiceName": "ServiceA",指定下游使用的服務名是什麼,使用這個服務名到consul伺服器去找到下游對應的IP及埠。

"UpstreamPathTemplate": "/ServiceA/{url}",
"UpstreamHttpMethod": [ "Get" ]

指定了上游的訪問路由格式及請求方式。

"GlobalConfiguration": {
"BaseUrl": "https://192.168.0.103:5000",
"ServiceDiscoveryProvider": {
"Host": "192.168.0.101",
"Port": 8500,
"Type": "Consul"
}
}

這段是全域性配置,BaseUrl表示ocelot上游使用的IP及埠。ServiceDiscoveryProvider指定Consul的伺服器和埠,用於服務發現。至此,api閘道器部分已經完成。

三、webapi配置

為ServiceA和ServiceB分別新增consul的nuget包。

然後在appsettings.json中配置consul伺服器的配置資訊。如下圖

這裡需要注意ServiceName,在Ocelot中使用的服務發現名也就是這個名字,也就是說,服務需要先到Consul上註冊,然後才能發現。

接著我們新增兩個檔案ConsulBuilderExtensions.cs和ConsulOption.cs用於註冊Consul.

 public static class ConsulBuilderExtensions
    {
        public static IApplicationBuilder RegisterConsul(this IApplicationBuilder app, IApplicationLifetime lifetime, ConsulOption consulOption)
        {
            var consulClient = new ConsulClient(x =>
            {
                // consul 服務地址
                x.Address = new Uri(consulOption.Address);
            });

            var registration = new AgentServiceRegistration()
            {
                ID = Guid.NewGuid().ToString(),
                Name = consulOption.ServiceName,// 服務名
                Address = consulOption.ServiceIP, // 服務繫結IP
                Port = consulOption.ServicePort, // 服務繫結埠
                Check = new AgentServiceCheck()
                {
                    DeregisterCriticalServiceAfter = TimeSpan.FromSeconds(5),//服務啟動多久後註冊
                    Interval = TimeSpan.FromSeconds(10),//健康檢查時間間隔
                    HTTP = consulOption.ServiceHealthCheck,//健康檢查地址
                    Timeout = TimeSpan.FromSeconds(5)
                }
            };

            // 服務註冊
            consulClient.Agent.ServiceRegister(registration).Wait();

            // 應用程式終止時,服務取消註冊
            lifetime.ApplicationStopping.Register(() =>
            {
                consulClient.Agent.ServiceDeregister(registration.ID).Wait();
            });
            return app;
        }
    }
 /// <summary>
    /// Consul 註冊發現相關引數
    /// </summary>
    public class ConsulOption
    {
        /// <summary>
        /// 服務名稱
        /// </summary>
        public string ServiceName { get; set; }

        /// <summary>
        /// 服務IP
        /// </summary>
        public string ServiceIP { get; set; }

        /// <summary>
        /// 服務埠
        /// </summary>
        public int ServicePort { get; set; }

        /// <summary>
        /// 服務健康檢查地址
        /// </summary>
        public string ServiceHealthCheck { get; set; }

        /// <summary>
        /// Consul 地址
        /// </summary>
        public string Address { get; set; }
    }

然後在startup.cs中使用consul中介軟體

   public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IApplicationLifetime lifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseAuthorization();
            var consulOption = new ConsulOption
            {
                ServiceName = Configuration["ServiceName"],
                ServiceIP = Configuration["ServiceIP"],
                ServicePort = Convert.ToInt32(Configuration["ServicePort"]),
                ServiceHealthCheck = Configuration["ServiceHealthCheck"],
                Address = Configuration["ConsulAddress"]
            };
            app.RegisterConsul(lifetime, consulOption);
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }