Tip: 此篇已加入.NET Core微服務基礎系列文章索引html
API 網關通常放到微服務的最前端,而且要讓API 網關變成由應用所發起的每一個請求的入口。這樣就能夠明顯的簡化客戶端實現和微服務應用程序之間的溝通方式。之前的話,客戶端不得不去請求微服務A(假設爲Customers),而後再到微服務B(假設爲Orders),而後是微服務C(假設爲Invoices)。客戶端須要去知道怎麼去一塊兒來消費這三個不一樣的service。使用API網關,咱們能夠抽象全部這些複雜性,並建立客戶端們可使用的優化後的端點,並向那些模塊們發出請求。API網關的核心要點是:全部的客戶端和消費端都經過統一的網關接入微服務,在網關層處理全部的非業務功能(好比驗證、鑑權、監控等等)。前端
關於API網關,我的以爲園友楊曉東的這篇文章《談談微服務中的API網關》值得一讀。微服務架構中的任何一個環節,都是能夠說好久的,而我沒有太多經驗,也就很少談了。git
Ocelot是一個使用.NET Core平臺上的一個API Gateway,這個項目的目標是在.NET上面運行微服務架構。Ocelot框架內部集成了IdentityServer(身份驗證)和Consul(服務註冊發現),還引入了Polly(上一篇博文中提到過)來處理進行故障處理。目前,騰訊和微軟是Ocelot在官網貼出來的客戶,我想也是由於這兩家公司都是巨頭,因此要標榜一下,哈哈。github
Ocelot github : https://github.com/TomPallister/Ocelotjson
NuGet>Install-Package Ocelot 後端
(1)準備一個ClientServiceapi
建立一個ASP.NET Core WebAPI程序,保留默認ValuesController,作一下修改:數組
[Route("api/[controller]")] public class ValuesController : Controller { // GET api/values [HttpGet] public IEnumerable<string> Get() { return new string[] { "ClinetService-value1", "ClinetService-value2" }; } ...... }
(2)準備一個ProductService瀏覽器
建立一個ASP.NET Core WebAPI程序,保留默認ValuesController,作一下修改:緩存
[Route("api/[controller]")] public class ValuesController : Controller { // GET api/values [HttpGet] public IEnumerable<string> Get() { return new string[] { "ProductService-value1", "ProductService-value2" }; } ...... }
建立一個ASP.NET Core WebAPI程序,這裏命名爲APIGateway.
(1)新建一個json文件:eg.configuration.json
首先,一個最基本的配置文件以下:
{ "ReRoutes": [], "GlobalConfiguration": { "BaseUrl": "https://api.mybusiness.com" } }
這裏特別注意一下BaseUrl是咱們外部暴露的Url,好比咱們的Ocelot運行在http://123.111.11.1的一個地址上,可是前面有一個Nginx綁定了域名http://api.edisonchou.cn,那這裏咱們的BaseUrl就是 http://api.edisonchou.cn。如今咱們的實驗環境不存在這個條件,因此咱們暫時不須要配置這個option。下面咱們根據模板將剛剛建立並啓動的兩個Service的信息進行了配置:
{ "ReRoutes": [ // API:CAS.ClientService { "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "192.168.2.231", "Port": "8810" } ], "UpstreamPathTemplate": "/ClientService/{url}", "UpstreamHttpMethod": [ "Get", "Post" ] }, // API:CAS.ProductService { "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "DownstreamHostAndPorts": [ { "Host": "192.168.2.231", "Port": "8820" } ], "UpstreamPathTemplate": "/ProductService/{url}", "UpstreamHttpMethod": [ "Get", "Post" ] } ] }
其中,咱們得了解一下微服務架構中的上游服務器和下游服務器,通常下游服務器指的是提供API服務的REST Service Server(好比WebAPI、WCF App等),而上游服務器則指的是提供Web網頁服務的Web Server(好比MVC Application,可能須要訪問REST Service)。那麼,這裏咱們能夠了解到:
經過配置文件,咱們能夠猜想Ocelot的實現原理大體應該就是把客戶端對網關的請求(Request),按照configuration.json的映射配置,轉發給對應的後端http service,而後從後端http service獲取響應(Response)後,再返回給客戶端。固然,具體細節應該十分複雜,等後面有時間深刻看看實現機制。
其餘再也不解釋,能夠看明白,另外,須要對這個配置文件進行如下設置:爲了確保直接運行時可以找到這個configuration.json文件
*.經過配置文件能夠完成對Ocelot的功能配置:路由、服務聚合、服務發現、認證、鑑權、限流、熔斷、緩存、Header頭傳遞等。在配置文件中包含兩個根節點:ReRoutes和GlobalConfiguration。ReRoutes是一個數組,其中的每個元素表明了一個路由,咱們能夠針對每個路由進行以上功能配置。
(2)改寫Program和StartUp類,才能正常使用Ocelot
①在Program類的BuildWebHost中讓程序讀取configuration.json文件
public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) { return WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .UseUrls($"http://{IP}:{Port}") .ConfigureAppConfiguration((hostingContext, builder) => { builder.AddJsonFile("configuration.json", false, true); }) .Build(); } }
②在StartUp類中爲Ocelot注入配置,並啓動Ocelot
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //services.AddMvc(); -- no need MVC // Ocelot services.AddOcelot(Configuration); } // 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.UseMvc(); -- no need MVC // Ocelot app.UseOcelot().Wait(); } }
(1)先啓動ClientService和ProductService => 也能夠經過在VS中更改啓動順序來指定
(2)再啓動APIGateway,在瀏覽器中直接訪問API網關所在的地址和端口(這裏是192.168.2.231:8800)進行測試:先請求ClientService,再請求ProductService,能夠看到API網關對請求進行了轉發,服務消費方不須要記住每一個service所在的IP和端口,而是隻須要告訴網關我須要消費哪一個service便可。
*.tip:這裏配置的PathTemplate大小寫不敏感,能夠選擇經過設置ReRouteIsCaseSensitive:true來實現大小寫敏感
到這裏,第一個API網關的實現就結束了,可是對於衆多的微服務,若是咱們都一一硬編碼地配置其IP和Port在配置文件中,不適合微服務架構的風格,由於衆多的服務地址變化會讓靜態配置的工做變得愈來愈大。所以,咱們學習了服務發現,那麼是否能夠結合服務發現呢?Ocelot + Consul的方式爲咱們給出了答案。
這裏仍然採用以前的Consul實驗集羣,三個Consul Server節點(1個leader,2個follwer),一個Consul Client節點(部署了兩個服務ClientService和ProductService),以及一個API網關節點(基於Ocelot)。
啓動方式以及步驟這裏再也不贅述,如不瞭解請瀏覽個人前兩篇博文《.NET Core微服務之基於Consul實現服務治理》以及《.NET Core微服務之基於Consul實現服務治理(續)》。這裏能夠看到,咱們已經成功地註冊了ClientService和ProductService。
(1)爲了適配Consul服務發現,減小服務IP和Port的hard-code,咱們須要改一下配置文件:
{ "ReRoutes": [ // API01:CAS.ClientService { "UseServiceDiscovery": true, // use Consul service discovery "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "ServiceName": "CAS.ClientService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/api/clientservice/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "ReRoutesCaseSensitive": false // non case sensitive }, // API02:CAS.ProductService { "UseServiceDiscovery": true, // use Consul service discovery "DownstreamPathTemplate": "/api/{url}", "DownstreamScheme": "http", "ServiceName": "CAS.ProductService", "LoadBalancerOptions": { "Type": "RoundRobin" }, "UpstreamPathTemplate": "/api/productservice/{url}", "UpstreamHttpMethod": [ "Get", "Post" ], "ReRoutesCaseSensitive": false // non case sensitive } ], "GlobalConfiguration": { //"BaseUrl": "https://api.mybusiness.com" "ServiceDiscoveryProvider": { "Host": "192.168.80.100", // Consul Service IP "Port": 8500 // Consul Service Port } } }
Ocelot提供了基本的負載均衡選項(LoadBalanceOptions):輪詢和最小鏈接數,若是咱們部署了多個同樣的服務,那麼咱們設置一個選項。
(2)其餘代碼無須更改,對於基本用法,咱們要作的基本只是對配置文件的修改。配置完成後,便可啓動API網關項目。
(1)請求ClientService
(2)請求ProductService
本篇介紹了API網關的基礎概念以及一個基於適合於.NET Core的開源項目Ocelot,並經過兩個小案例(一個靜態配置服務,一個結合Consul服務發現)來了解了API網關的做用和Ocelot的最基礎的用法。下一篇會繼續Ocelot的一些比較有用的功能(好比:限流、熔斷、緩存,以及結合Swagger),繼續作一些實踐,也但願到時能夠總結下來與各位園友分享。
Click here => 點我下載
楊曉東,《談談微服務中的API網關》
桂素偉,《Ocelot + Consul實踐》
楊中科,《.NET微服務直播課課件pdf》
李朝強,《ASP.NET Core API網關Ocelot》
jesse 騰飛,《.NET Core開源API網關 – Ocelot中文文檔》
Ocelot官網:https://github.com/ThreeMammals/Ocelot => tip: 張善友大隊長爲主要貢獻者之一
Ocelot官方文檔:http://ocelot.readthedocs.io/en/latest/index.html