1. 程式人生 > >微服務閘道器Ocelot

微服務閘道器Ocelot

微服務閘道器是微服務架構中的核心元件,它是客戶端請求的門戶,它是呼叫具體服務端的橋樑.下面我們將使用開源專案Ocelothttps://github.com/geffzhang/Ocelot)搭建一款輕量級服務閘道器,不過在此之前我們將對微服務閘道器做個詳細介紹,以便大家更加清晰的瞭解什麼是微服務閘道器。

7.1什麼是微服務閘道器

微服務閘道器類似於經典設計模式的Façade模式,它將底層的複雜細節進行遮蔽,對外提供簡單而統一的呼叫方式,通常使用HTTPRESTful API服務。此時,對於客戶端而言,可以是PC端網頁,也可以是移動裝置,客戶端通過HTTP方式呼叫微服務閘道器。

         微服務閘道器也稱為服務閘道器(

ServiceGateway)或API閘道器(API Gateway),下面通過一張架構圖來表達服務閘道器與客戶端以及服務端的關係。

640?wx_fmt=png

我們使用服務閘道器(Service Gateway)來建立客戶端和服務端之間的聯絡。當客戶端傳送請求時,請求首先進入服務閘道器,隨後服務閘道器將服務請求路由轉發到具體的服務端。在路由的過程中,會涉及到具體的路由演算法,最簡單的做法是在服務閘道器中解析客戶端請求中的路徑或請求頭,從而路由到具體的服務端。

         在微服務模式網站上也對服務閘道器進行了說明,可以通過以下地址瞭解API Gateway模式的具體資訊。

         實際上,服務閘道器的路由過程我們稱之為“反向代理”。如果大家曾經使用過

Nginx,對反向代理這個概念不會陌生。說白了就是請求不會直接傳送到目的地,而是通過一箇中間件進行轉發,這個中介軟體就是Nginx,它充當了反向代理的角色。

         在什麼樣場景下我們會考慮使用反向代理技術呢?

  • 使靜態資源與動態資源分離

  • 實現AJAX跨域訪問

  • 搭建統一服務閘道器介面

下面我們將使用Ocelet 實現一個服務閘道器的重要特性之一:反向代理。

7.2 使用Ocelot 實現一個反向代理

         Ocelot是一個使用.NET Core平臺上的一個API Gateway,這個專案的目標是在.NET上面執行微服務架構,它很好的和Identity Server整合,由

Identity Server負責驗證授權。

         使用Ocelot 搭建一個反向代理,僅需要三步:

         第一步,使用VisualStudio 2017 建立一個ASP.NET Core空專案FitApiGateway,通過Nuget安裝Ocelot

Install-PackageOcelot

第二步使用ASP.NET Core應用宿主Ocelot,在Startup.cs中配置,程式碼如下:

publicclassStartup

   {

public Startup(IHostingEnvironment env)

       {

var builder = newConfigurationBuilder()

               .SetBasePath(env.ContentRootPath)

                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)

                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)

               .AddJsonFile("configuration.json")

                .AddEnvironmentVariables();

            Configuration = builder.Build();

       }

// This method gets called by theruntime. Use this method to add services to the container.

// For more information on how toconfigure your application, visithttps://go.microsoft.com/fwlink/?LinkID=398940

publicvoid ConfigureServices(IServiceCollection services)

       {

Action<ConfigurationBuilderCachePart> settings = (x) =>

            {

                x.WithMicrosoftLogging(log=>

                {

                    log.AddConsole(LogLevel.Debug);

                })

                .WithDictionaryHandle();

            };

           services.AddOcelotOutputCaching(settings);

           services.AddOcelotFileConfiguration(Configuration);

            services.AddOcelot();

       }

publicIConfigurationRoot Configuration { get; }

// This method gets called by theruntime. Use this method to configure the HTTP request pipeline.

publicvoid Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

       {

           loggerFactory.AddConsole(Configuration.GetSection("Logging"));

            app.UseOcelot();

       }

    }

路由是Ocelot的核心配置,Ocelot的核心功能就是將到達的Http請求轉發給下游的服務,目前還只能是Http請求,將來支援其他任何傳輸機制。一條路由規則如下:

{

"ReRoutes": [

   {

"DownstreamPathTemplate": "/api/values",

"DownstreamScheme": "http",

"DownstreamHost": "localhost",

"DownstreamPort": 9030,

"UpstreamPathTemplate": "/api/values",

"UpstreamHttpMethod": "Get",

"FileCacheOptions": { "TtlSeconds": 15 }

   }

 ],

"GlobalConfiguration": {

"RequestIdKey": "OcRequestId",

"ServiceDiscoveryProvider": {

"Provider": "Consul",

"Host": "localhost",

"Port": 8500

   }

  }

}

DownstreamPathTemplate, DownstreamScheme,DownstreamPort DownstreamHost組成請求被轉發的URLUpstreamPathTemplateOcelot 用於識別轉發請求,UpstreamHttpMethod用於識別相同的URL請求的不同操作。可以在模板裡使用佔位符{something}要同時出現在DownstreamPathTemplate UpstreamPathTemplate.

Ocelot預設不區分大小寫,可以在配置中指定區分大小寫:

  "ReRouteIsCaseSensitive": true

RequestIdKey

除了記錄訪問記錄外, 在處理每個使用者請求過程中, 涉及業務邏輯處理和後端服務呼叫等, 對某些操作也需要記錄相應日誌和錯誤.對每個請求, 都生成一個唯一的requestID. 在這個請求的生命週期中, 所有列印的日誌都會帶上requestID資訊,通過RequestI還可以構建Http請求路徑,前端一個請求,可能要經過後端好幾個服務,可以在http頭上加上RequestIdRequestIndex把這些服務串起來,例如 A->B->CA服務呼叫B服務的時候,如果發現http head裡面沒有RequestId則可以通過GuId生成一個,同時RequestIndex1 B服務呼叫C服務端時候, 因為RequestId已經有了,就直接傳遞下去,同時RequestIndex1 ,把這些資訊記錄到日誌中,通過分析,整個呼叫就串起來了,通過完整的資料就可以繪製出整個服務的呼叫鏈路圖。 

Ocelot從實現上來說就是一系列的中介軟體組合,在HTTP請求到達Ocelot,經過一系列的中介軟體的處理轉發到下游的服務。

至此,一個ASP.NET Core 反向代理伺服器就搭建完畢,下面我們使用Apache Bench對其效能做個簡單的測試。我們模擬了1000 個使用者,每次併發100個請求,以下是測試結果,機器的配置是CPUIntel i5 2核, 4G記憶體的機器上測試:

D:\Workshop\ab>ab.exe -n 1000 -c 100 http://localhost:5800/api/values/

This isApacheBench, Version 2.3 <$Revision: 1757674 $>

Copyright 1996Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/

Licensed to TheApache Software Foundation, http://www.apache.org/

Benchmarkinglocalhost (be patient)

Completed 100requests

Completed 200requests

Completed 300requests

Completed 400requests

Completed 500requests

Completed 600requests

Completed 700requests

Completed 800requests

Completed 900requests

Completed 1000requests

Finished 1000requests

ServerSoftware:        Kestrel

ServerHostname:        localhost

ServerPort:            5800

DocumentPath:          /api/values/

DocumentLength:        19 bytes

ConcurrencyLevel:      100

Time taken fortests:   0.230 seconds

Completerequests:      1000

Failedrequests:        0

Totaltransferred:      178000 bytes

HTMLtransferred:       19000 bytes

Requests persecond:    4345.52 [#/sec] (mean)

Time perrequest:       23.012 [ms] (mean)

Time perrequest:       0.230 [ms] (mean, acrossall concurrent requests)

Transferrate:          755.37 [Kbytes/sec]received

Connection Times(ms)

              min  mean[+/-sd] median   max

Connect:        0   0   0.3      0      4

Processing:     5  21   9.6     19     66

Waiting:        4  18   9.8     17     65

Total:          6  21   9.6     20     66

Percentage ofthe requests served within a certain time (ms)

  50%    20

  66%    22

  75%    27

  80%    30

  90%    34

  95%    39

  98%    44

  99%    48

 100%    66 (longest request)

可見,平均每秒請求數(吞吐率)為4345.52, 從不同分佈下的請求數來看,響應時間也比較平穩, 相比直接訪問介面的效能相差不大。

ab.exe -n 1000 -c 100http://localhost:9030/api/values/

This is ApacheBench, Version 2.3 <$Revision:1757674 $>

Copyright 1996 Adam Twiss, Zeus Technology Ltd,http://www.zeustech.net/

Licensed to The Apache Software Foundation,http://www.apache.org/

Benchmarking localhost (be patient)

Completed 100 requests

Completed 200 requests

Completed 300 requests

Completed 400 requests

Completed 500 requests

Completed 600 requests

Completed 700 requests

Completed 800 requests

Completed 900 requests

Completed 1000 requests

Finished 1000 requests

Server Software:        Kestrel

Server Hostname:        localhost

Server Port:            9030

Document Path:          /api/values/

Document Length:        19 bytes

Concurrency Level:      100

Time taken for tests:   0.200 seconds

Complete requests:      1000

Failed requests:        0

Total transferred:      158000 bytes

HTML transferred:       19000 bytes

Requests per second:    5011.40 [#/sec] (mean)

Time per request:       19.954 [ms] (mean)

Time per request:       0.200 [ms] (mean, across all concurrentrequests)

Transfer rate:          773.24 [Kbytes/sec] received

Connection Times (ms)

             min  mean[+/-sd] median   max

Connect:       0    0   0.3     0       1

Processing:    3   19   3.4    19      29

Waiting:       2   13   4.8    13      25

Total:         3   19   3.4    20      29

Percentage of the requests served within acertain time (ms)

 50%     20

 66%     20

 75%     21

 80%     21

 90%     22

 95%     23

 98%     25

 99%     25

 100%    29 (longest request)

         Asp.netcore的效能絕不亞於Nginx,但擴充套件性卻遠高於Nginx,我們可以動態的指定被代理的目標地址,而在Nginx中配置的目標地址是靜態的,這一點對於我們將來實現服務發現功能及其重要,因為我們需要從ServiceRegistry中獲取需要代理的微服務資訊(例如IP和埠),並執行反向代理操作,呼叫相應的微服務REST API

         以上實際上是服務閘道器的基礎框架,將來我們會在此基礎上進行擴充套件,實現一個具有反向代理和服務發現的服務閘道器。當然服務閘道器並非僅提供反向代理與服務發現特性,此外還需要具備安全認證、效能監控、資料快取、請求分片、靜態響應等眾多特性,我們可以根據實際情況進行擴充套件。

相關文章:

.NET社群新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關注

640?wx_fmt=jpeg