使用Ocelot構建GateWay


添加Nuget包:Ocelot

添加配置文件Ocelot.json 具體配置可以看另一篇 Ocelot配置

 

Json配置文件主要包含兩個根節點:

ReRoutes:路由重定向配置 都是數組結構 可以配置多個

GlobalConfigrations:全局配置

ReRoutes 主要包含了上下游的路徑、方式、限流、負載等設置

我們先配置一個最簡單的設置:

這里我做了一個負載,把api部署了2份做了一個簡單的分布式,當我訪問test的時候會被轉發到20001或者 20002上

{
  "ReRoutes": [
    {
      "DownstreamPathTemplate": "/api/values/getuser",
      "DownstreamScheme": "http",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 20001
        },
        {
          "Host": "localhost",
          "Port": 20002
        }
      ],
      "UpstreamPathTemplate": "/test",
      "UpstreamHttpMethod": [ "Get" ],
      "LoadBalancer": "LeastConnection",
      "ServiceName": "userservices",
      "UseServiceDiscovery": true
    }
  ],

  "GlobalConfiguration": {
  "BaseUrl": "http://localhost:20000",
    "ServiceDiscoveryProvider": {
      "Host": "localhost",
      "Port": 8500

    }

  }
}

這里我結合了Consul來實現,關於Consul的使用可以看官方文檔:

需要下載consul.exe程序並將其啟動起來 這是一個服務發現健康檢查的組件 如果沒有添加系統path設置就直接進入consul.exe目錄啟動起來

httpServer的默認地址是8500,訪問下會進入consul的ui

 

 訪問 :http://localhost:20000/test

訪問:http://localhost:20001/api/values/getuser

得到一樣的結果,這里已經被轉發了,因為我們配置負載均衡及健康監測

從而保證了在服務器宕機后或者在高QPS下的正常訪問

 在APIGateWay網關里添加對Ocelot的設置

 public static IWebHost BuildWebHost(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
            .ConfigureAppConfiguration((hostingContext, builder) =>
            {
                builder
                .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                .AddJsonFile("Ocelot.json");
            })
                .UseStartup<Startup>()
            .UseUrls("http://localhost:20000")
                .Build();

添加相關服務注冊及configure

 services.AddOcelot();

 app.UseOcelot().Wait();

網關配置好后,需要對業務接口服務實現健康檢查,設置好先關的參數處理consul的頻率

DeregisterCriticalServiceAfter 失敗多久后注銷服務的
Interval 檢查發送的評率
HTTP 檢查的地址
 
 applicationLifetime.ApplicationStarted.Register(() =>
            {

                //自動獲取當前接口服務地址

                var features = app.Properties["server.Features"] as FeatureCollection;
                var addessess = features.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url));

                foreach (var address in addessess)
                {
                  
                    var httpcheck = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(userappsetting.Value.DeregisterCriticalServiceAfter),
                        Interval = TimeSpan.FromSeconds(userappsetting.Value.Interval),
                        HTTP = new Uri(address, "/api/Check").OriginalString,
                       

                    };
                    //這里可以注入配置
                    var agentReg = new AgentServiceRegistration()
                    {
                        ID = $"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}",
                        Check = httpcheck,
                        Name = userappsetting.Value.ServiceName,
                        Address = address.Host,
                        Port = address.Port
                      
                    };
                    client.Agent.ServiceRegister(agentReg).ConfigureAwait(false);
                }


            });
            applicationLifetime.ApplicationStopped.Register(() =>
            {
                var features = app.Properties["server.Features"] as FeatureCollection;
                var addessess = features.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url));
                foreach (var address in addessess)
                {
                    client.Agent.ServiceDeregister($"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}").GetAwaiter().GetResult();
                }
            });

 注:上述代碼注冊指適用於 Hosting方式  ,如果你用的IIS做寄宿,

 var addessess = features.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url)); 

 獲取到的地址不是你期待的地址,它是本地 127.0.0.1:隨機端口 ,會導致健康檢查服務注冊了之后無法進行健康檢查

可以配置下不同的啟動方式來設置

  applicationLifetime.ApplicationStarted.Register(() =>
            {


                if (userappsetting.Value.IsIISHost)
                {
                    #region IIS 寄宿方式
                    var httpcheck = new AgentServiceCheck()
                    {
                        DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(userappsetting.Value.DeregisterCriticalServiceAfter),
                        Interval = TimeSpan.FromSeconds(userappsetting.Value.Interval),
                        HTTP = new Uri(new Uri(userappsetting.Value.CurrentIISUrl), userappsetting.Value.MatchPath).OriginalString

                    };
                    //這里可以注入配置
                    var agentReg = new AgentServiceRegistration()
                    {
                        ID = $"{userappsetting.Value.ServiceName}_{userappsetting.Value.CurrentIISUrl}_{userappsetting.Value.CurrentIISPort}",
                        Check = httpcheck,
                        Name = userappsetting.Value.ServiceName,
                        Address = userappsetting.Value.CurrentIISUrl,
                        Port = userappsetting.Value.CurrentIISPort

                    };
                    client.Agent.ServiceRegister(agentReg).ConfigureAwait(false);
                    #endregion
                }
                else
                {
                    #region 服務注冊健康檢查 Hosting寄宿
                    var addessess = app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url));

                    foreach (var address in addessess)
                    {
                        var httpcheck = new AgentServiceCheck()
                        {
                            DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(userappsetting.Value.DeregisterCriticalServiceAfter),
                            Interval = TimeSpan.FromSeconds(userappsetting.Value.Interval),
                            HTTP = new Uri(address, userappsetting.Value.MatchPath).OriginalString

                        };
                        //這里可以注入配置
                        var agentReg = new AgentServiceRegistration()
                        {
                            ID = $"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}",
                            Check = httpcheck,
                            Name = userappsetting.Value.ServiceName,
                            Address = address.Host,
                            Port = address.Port

                        };
                        client.Agent.ServiceRegister(agentReg).ConfigureAwait(false);
                    }
                    #endregion

                }


            });
            applicationLifetime.ApplicationStopped.Register(() =>
            {
                if (userappsetting.Value.IsIISHost)
                {
                    client.Agent.ServiceDeregister($"{userappsetting.Value.ServiceName}_{userappsetting.Value.CurrentIISUrl}_{userappsetting.Value.CurrentIISPort}").GetAwaiter().GetResult();
                }
                else
                {

                    var addessess = app.ServerFeatures.Get<IServerAddressesFeature>().Addresses.Select(url => new Uri(url));
                    foreach (var address in addessess)
                    {
                        client.Agent.ServiceDeregister($"{userappsetting.Value.ServiceName}_{address.Host}_{address.Port}").GetAwaiter().GetResult();
                    }
                }

            });
            return applicationLifetime;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM