Ocelot和Consul 實現閘道器API 服務註冊 負載均衡
Ocelot和Consul 實現閘道器API 服務註冊 負載均衡
Ocelot是一個用.NET Core實現並且開源的API閘道器,它功能強大,包括了:路由、請求聚合、服務發現、認證、鑑權、限流熔斷、並內建了負載均衡器與Service Fabric、Butterfly Tracing整合。這些功能只都只需要簡單的配置即可完成
Consul服務發現
在Ocelot已經支援簡單的負載功能,也就是當下遊服務存在多個結點的時候,Ocelot能夠承擔起負載均衡的作用。但是它不提供健康檢查,服務的註冊也只能通過手動在配置檔案裡面新增完成。這不夠靈活並且在一定程度下會有風險。這個時候我們就可以用Consul來做服務發現,它能與Ocelot完美結合。
Consul是什麼
Consul是一個服務網格(微服務間的 TCP/IP,負責服務之間的網路呼叫、限流、熔斷和監控)解決方案,它是一個一個分散式的,高度可用的系統,而且開發使用都很簡便。它提供了一個功能齊全的控制平面,主要特點是:服務發現、健康檢查、鍵值儲存、安全服務通訊、多資料中心。
安裝Consul:windos環境
https://www.consul.io/downloads.html 下載檔案
放到D盤下
開啟powershell 執行 命令啟動一個Agent的開發模式:
啟動完成:開啟localhost:8500 預設埠8500 就可以看到一個視覺化consul介面了,可以看到預設啟動了一個consul 服務
下面,使用netcore通過Ocelot搭建API閘道器 服務註冊 負載均衡
新建一個api1:nuget 新增一個consul 依賴
startup 新增程式碼
public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApplicationLifetime lifetime) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); }//註冊專案啟動的方法 lifetime.ApplicationStarted.Register(OnStart); //註冊專案關閉的方法 lifetime.ApplicationStarted.Register(OnStopped); app.UseMvc(); } //關閉的時候在consul中移除 private void OnStopped() { var client = new ConsulClient(); //根據ID在consul中移除當前服務 client.Agent.ServiceDeregister("servicename:93"); } private void OnStart() { var client = new ConsulClient(); //健康檢查 var httpCheck = new AgentServiceCheck() { //服務出錯一分鐘後 會自動移除 DeregisterCriticalServiceAfter = TimeSpan.FromMinutes(1), //每10秒傳送一次請求到 下面的這個地址 這個地址就是當前API資源的地址 Interval = TimeSpan.FromSeconds(10), HTTP = $"http://localhost:93/HealthCheck" }; var agentReg = new AgentServiceRegistration() { //這臺資源服務的唯一ID ID = "servicename:93", Check = httpCheck, Address = "localhsot", Name = "servicename", Port = 93 }; client.Agent.ServiceRegister(agentReg).ConfigureAwait(false); }
新增一個健康檢查介面
[Route("HealthCheck")] [ApiController] public class HealthCheckController : ControllerBase { // GET: api/HealthCheck [HttpGet] [HttpHead] public IActionResult Ping() { return Ok(); } }
修改ValuesController
[Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { // GET api/values [HttpGet] public string Get() { return "這是1資源伺服器API"; } }然後 copy 一份api1 為api2,,我們啟用埠為92 ,細節........
新增專案Api.Gateway(Ocelot閘道器伺服器)新增Ocelot包 新增Ocelot.Json配置 Ocelot伺服器埠為91
Ocelot,Json
{ "ReRoutes": [ { //暴露出去的地址 "UpstreamPathTemplate": "/api/{controller}", "UpstreamHttpMethod": [ "Get" ], //轉發到下面這個地址 "DownstreamPathTemplate": "/api/{controller}", "DownstreamScheme": "http", //資源伺服器列表 "DownstreamHostAndPorts": [ { "host": "localhost", "port": 92 }, { "host": "localhost", "port": 93 } ], //決定負載均衡的演算法 "LoadBalancerOptions": { "Type": "LeastConnection" }, "UseServiceDiscovery": true } ], //對外暴露的訪問地址 也就是Ocelot所在的伺服器地址 "GlobalConfiguration": { "BaseUrl": "http://localhost:91" } }
Startup 修改
public void ConfigureServices(IServiceCollection services) { services.AddOcelot(); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseOcelot().Wait(); app.UseMvc(); }
Program 修改
public class Program { public static void Main(string[] args) { CreateWebHostBuilder(args).Build().Run(); } public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, builder) => { builder .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath) .AddJsonFile("Ocelot.json"); }) .UseUrls("http://+:91") .UseStartup<Startup>(); }
啟動 api3 和api2
再啟動Api.Gateway
執行 http://localhost:91/api/values
再執行
我們這裡負載均衡演算法是:LeastConnection
當然還可以選擇其他的:
- RoundRobin - 輪詢,挨著來
- LeastConnection - 最小連線數,誰的任務最少誰來
- NoLoadBalance - 不要負載均衡
如果api1 我們關掉 ,那麼就只會請求到api2 ,api1的服務自動斷開