.NET Core微服務之基於Ocelot實現API網關服務

原文:https://www.cnblogs.com/edisonchou/archive/2018/06/12/9170333.html

一、啥是API網關?


.NET Core微服務之基於Ocelot實現API網關服務

API 網關一般放到微服務的最前端,並且要讓API 網關變成由應用所發起的每個請求的入口。這樣就可以明顯的簡化客戶端實現和微服務應用程序之間的溝通方式。以前的話,客戶端不得不去請求微服務A(假設為Customers),然後再到微服務B(假設為Orders),然後是微服務C(假設為Invoices)。客戶端需要去知道怎麼去一起來消費這三個不同的service。使用API網關,我們可以抽象所有這些複雜性,並創建客戶端們可以使用的優化後的端點,並向那些模塊們發出請求。API網關的核心要點是:所有的客戶端和消費端都通過統一的網關接入微服務,在網關層處理所有的非業務功能(比如驗證、鑑權、監控等等)。

關於API網關,個人覺得園友楊曉東的這篇文章《談談微服務中的API網關》值得一讀。微服務架構中的任何一個環節,都是可以說很久的,而我沒有太多經驗,也就不多談了。

二、開源項目:Ocelot


.NET Core微服務之基於Ocelot實現API網關服務


Ocelot是一個使用.NET Core平臺上的一個API Gateway,這個項目的目標是在.NET上面運行微服務架構。Ocelot框架內部集成了IdentityServer(身份驗證)和Consul(服務註冊發現),還引入了Polly(上一篇博文中提到過)來處理進行故障處理。目前,騰訊和微軟是Ocelot在官網貼出來的客戶,我想也是因為這兩家公司都是巨頭,所以要標榜一下,哈哈。

.NET Core微服務之基於Ocelot實現API網關服務


Ocelot github : https://github.com/TomPallister/Ocelot

三、快速開始第一個API網關

3.1 安裝Ocelot

NuGet>Install-Package Ocelot

3.2 快速準備兩個API服務

(1)準備一個ClientService

.NET Core微服務之基於Ocelot實現API網關服務


創建一個ASP.NET Core WebAPI程序,保留默認ValuesController,做一下修改:

 [Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable Get()
{
return new string[] { "ClinetService-value1", "ClinetService-value2" };
}
......
}

(2)準備一個ProductService

.NET Core微服務之基於Ocelot實現API網關服務

創建一個ASP.NET Core WebAPI程序,保留默認ValuesController,做一下修改:

 [Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
public IEnumerable Get()
{
return new string[] { "ProductService-value1", "ProductService-value2" };
}
......
}

3.3 靜態配置兩個API服務

創建一個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)。那麼,這裡我們可以瞭解到:

  • Downstream 下游服務配置 => 即我們剛剛創建的提供API服務的配置,我們會指定PathTemplate,Host和Port等信息(具體調哪一臺服務器是由我說了算)
  • UpStream上游服務配置 => 即服務消費方(eg.MVC Server, SPA App)的調用配置(你要怎麼按照什麼URL格式和什麼HTTP類型調用我才能理解)

通過配置文件,我們可以猜測Ocelot的實現原理大致應該就是把客戶端對網關的請求(Request),按照configuration.json的映射配置,轉發給對應的後端http service,然後從後端http service獲取響應(Response)後,再返回給客戶端。當然,具體細節應該十分複雜,等後面有時間深入看看實現機制。

其他不再解釋,可以看明白,另外,需要對這個配置文件進行以下設置:為了確保直接運行時能夠找到這個configuration.json文件

.NET Core微服務之基於Ocelot實現API網關服務

*.通過配置文件可以完成對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()
.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();
}
}

3.3 測試一下

(1)先啟動ClientService和ProductService => 也可以通過在VS中更改啟動順序來指定

.NET Core微服務之基於Ocelot實現API網關服務


(2)再啟動APIGateway,在瀏覽器中直接訪問API網關所在的地址和端口(這裡是192.168.2.231:8800)進行測試:先請求ClientService,再請求ProductService,可以看到API網關對請求進行了轉發,服務消費方不需要記住每個service所在的IP和端口,而是隻需要告訴網關我需要消費哪個service即可。

.NET Core微服務之基於Ocelot實現API網關服務


.NET Core微服務之基於Ocelot實現API網關服務


*.tip:這裡配置的PathTemplate大小寫不敏感,可以選擇通過設置ReRouteIsCaseSensitive:true來實現大小寫敏感

到這裡,第一個API網關的實現就結束了,但是對於眾多的微服務,如果我們都一一硬編碼地配置其IP和Port在配置文件中,不適合微服務架構的風格,因為眾多的服務地址變化會讓靜態配置的工作變得越來越大。因此,我們學習了服務發現,那麼是否可以結合服務發現呢?Ocelot + Consul的方式為我們給出了答案。

四、Ocelot+Consul的結合

4.1 實驗節點部署結構


.NET Core微服務之基於Ocelot實現API網關服務

這裡仍然採用之前的Consul實驗集群,三個Consul Server節點(1個leader,2個follwer),一個Consul Client節點(部署了兩個服務ClientService和ProductService),以及一個API網關節點(基於Ocelot)。

4.2 啟動Consul


.NET Core微服務之基於Ocelot實現API網關服務


啟動方式以及步驟這裡不再贅述,如不瞭解請瀏覽我的前兩篇博文《.NET Core微服務之基於Consul實現服務治理》以及《.NET Core微服務之基於Consul實現服務治理(續)》。這裡可以看到,我們已經成功地註冊了ClientService和ProductService。

4.3 啟動API Gateway

(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網關項目。

4.4 測試

(1)請求ClientService

.NET Core微服務之基於Ocelot實現API網關服務

(2)請求ProductService

.NET Core微服務之基於Ocelot實現API網關服務


五、小結

本篇介紹了API網關的基礎概念以及一個基於適合於.NET Core的開源項目Ocelot,並通過兩個小案例(一個靜態配置服務,一個結合Consul服務發現)來了解了API網關的作用和Ocelot的最基礎的用法。下一篇會繼續Ocelot的一些比較有用的功能(比如:限流、熔斷、緩存,以及結合Swagger),繼續做一些實踐,也希望到時可以總結下來與各位園友分享。


楊曉東,《談談微服務中的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

原文:https://www.cnblogs.com/edisonchou/archive/2018/06/12/9170333.html作者:周旭龍出處:http://edisonchou.cnblogs.com本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。


分享到:


相關文章: