上一篇【.Net Core微服務入門全紀錄(三)——Consul-服務註冊與發現(下)】已經使用Consul完成了服務的註冊與發現,實際中光有服務註冊與發現每每是不夠的,咱們須要一個統一的入口來鏈接客戶端與服務。html
官網:https://ocelot.readthedocs.io/
Ocelot正是爲.Net微服務體系提供一個統一的入口點,稱爲:Gateway(網關)。git
首先建立一個空的asp.net core web項目。
注意ocelot.json是咱們添加的Ocelot的配置文件,記得設置生成時複製到輸出目錄。ocelot.json的文件名不是固定的,能夠本身定義。github
NuGet安裝一下Ocelot:
web
只需簡單的修改幾處默認代碼:
Program.cs:docker
public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureAppConfiguration((hostingContext, config) => { config.AddJsonFile("ocelot.json"); }) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); }
Startup.cs:json
public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { //添加ocelot服務 services.AddOcelot(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { //設置Ocelot中間件 app.UseOcelot().Wait(); } }
ocelot.json:api
{ "Routes": [ { "DownstreamPathTemplate": "/products", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 9050 }, { "Host": "localhost", "Port": 9051 }, { "Host": "localhost", "Port": 9052 } ], "UpstreamPathTemplate": "/products", "UpstreamHttpMethod": [ "Get" ], "LoadBalancerOptions": { "Type": "RoundRobin" //負載均衡,輪詢機制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions } }, { "DownstreamPathTemplate": "/orders", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "localhost", "Port": 9060 }, { "Host": "localhost", "Port": 9061 }, { "Host": "localhost", "Port": 9062 } ], "UpstreamPathTemplate": "/orders", "UpstreamHttpMethod": [ "Get" ], "LoadBalancerOptions": { "Type": "RoundRobin" //負載均衡,輪詢機制 LeastConnection/RoundRobin/NoLoadBalancer/CookieStickySessions } } ], "GlobalConfiguration": { "BaseUrl": "http://localhost:9070" } }
咱們先暫時忽略Consul,將服務實例的地址都寫在配置文件中。要知道Consul、Ocelot等組件都是能夠獨立存在的。
配置文件中的Routes節點用來配置路由,Downstream表明下游,也就是服務實例,Upstream表明上游,也就是客戶端。咱們的路徑比較簡單,只有/products、/orders,路徑中若是有不固定參數則使用{}匹配。咱們這個配置的意思呢就是客戶端訪問網關的/orders、/products,網關會轉發給服務實例的/orders、/products,注意這個上游的路徑不必定要和下游一致,好比上游路徑能夠配置成/api/orders,/xxx均可以。
LoadBalancerOptions節點用來配置負載均衡,Ocelot內置了 LeastConnection、RoundRobin、NoLoadBalancer、CookieStickySessions 4種負載均衡策略。
BaseUrl節點就是配置咱們ocelot網關將要運行的地址。瀏覽器
目前不考慮網關集羣,就不放在docker裏了。直接控制檯執行:`dotnet Ocelot.APIGateway.dll --urls="http://*:9070"
app
用瀏覽器測試一下:
測試正常,咱們經過網關能夠正常的訪問到服務實例。負載均衡
由於改動太多就直接新建一個GatewayServiceHelper來作。
GatewayServiceHelper:
/// <summary> /// 經過gateway調用服務 /// </summary> public class GatewayServiceHelper : IServiceHelper { public async Task<string> GetOrder() { var Client = new RestClient("http://localhost:9070"); var request = new RestRequest("/orders", Method.GET); var response = await Client.ExecuteAsync(request); return response.Content; } public async Task<string> GetProduct() { var Client = new RestClient("http://localhost:9070"); var request = new RestRequest("/products", Method.GET); var response = await Client.ExecuteAsync(request); return response.Content; } public void GetServices() { throw new NotImplementedException(); } }
而後在Startup中修改一下注入的類型,別的就不用改了,這就是依賴注入的好處之一。。。
Startup.ConfigureServices():
//注入IServiceHelper //services.AddSingleton<IServiceHelper, ServiceHelper>(); //注入IServiceHelper services.AddSingleton<IServiceHelper, GatewayServiceHelper>();
Startup.Configure():
//程序啓動時 獲取服務列表 //serviceHelper.GetServices();
運行客戶端測試:
好了,如今客戶端對服務的調用都經過網關進行中轉,客戶端不再用去關心那一堆服務實例的地址,只須要知道網關地址就能夠了。另外,服務端也避免了服務地址直接暴露給客戶端。這樣作對客戶端,服務都很是友好。
至於咱們的api網關呢,又要說到服務發現的問題了。目前咱們的服務地址是寫在ocelot.json配置文件裏的,固然這種作法在服務實例不常常變化的狀況下是沒有問題的,一旦服務變化,須要人爲的修改配置文件,這又顯得不太合理了。
固然,強大的Ocelot爲咱們提供了服務發現的方案。
代碼放在:https://github.com/xiajingren/NetCoreMicroserviceDemo
未完待續...