1. 程式人生 > >.NET Core微服務之基於Ocelot實現API閘道器服務

.NET Core微服務之基於Ocelot實現API閘道器服務

一、啥是API閘道器?

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

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

二、開源專案:Ocelot

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

三、快速開始第一個API閘道器

3.1 安裝Ocelot

NuGet>Install-Package Ocelot  

3.2 快速準備兩個API服務

  (1)準備一個ClientService

  

  建立一個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" };
        }

        ......
    }

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檔案

  

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

3.3 測試一下

  (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的方式為我們給出了答案。

四、Ocelot+Consul的結合

4.1 實驗節點部署結構

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

4.2 啟動Consul

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

  

  (2)請求ProductService

  

五、小結

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

示例程式碼

  Click here => 點我下載

參考資料

楊中科,《.NET微服務直播課課件pdf》

作者:周旭龍

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。

相關推薦

.NET Core服務基於Ocelot實現API服務

一、啥是API閘道器?   API 閘道器一般放到微服務的最前端,並且要讓API 閘道器變成由應用所發起的每個請求的入口。這樣就可以明顯的簡化客戶端實現和微服務應用程式之間的溝通方式。以前的話,客戶端不得不去請求微服務A(假設為Customers),然後再到微服務B(假設為Orders),然後是微服

.NET Core服務基於Ocelot實現API服務(續)

一、負載均衡與請求快取 1.1 負載均衡   為了驗證負載均衡,這裡我們配置了兩個Consul Client節點,其中ClientService分別部署於這兩個節點內(192.168.80.70與192.168.80.71)。   為了更好的展示API Repsonse來自哪個節點,我們更改一下

.NET服務體系結構中為什麼使用Ocelot實現API

為什麼要使用API閘道器而不是直接通訊?在微服務架構中,客戶端應用程式通常需要使用

spring cloud 入門系列六:使用Zuul 實現API服務

通過前面幾次的分享,我們瞭解了微服務架構的幾個核心設施,通過這些元件我們可以搭建簡單的微服務架構系統。比如通過Spring Cloud Eureka搭建高可用的服務註冊中心並實現服務的註冊和發現; 通過Spring Cloud Ribbon或Feign進行負載均衡;通過Spring Cloud Hyst

基於.NET CORE服務框架 -Api服務管理

最近也更新了surging新的版本 更新內容: 1. 擴充套件Zookeeper封裝 2. 增加服務元資料 3. 增加API閘道器 開源地址:https://github.com/dotnetcore/surging 2.軟體環境 IDE:Visual Studio 2017 1

基於Ocelot的gRpcHttp

什麼是gRpcHttp閘道器 通俗的講就是將gRpc提供的服務以rest api的形式提供出去,不需要再單獨的寫一個webapi去做這件事。 gRpcHttp閘道器好處 減少不必要程式碼,減少中間層提高通訊效率。 以前可能是這樣 用了gRpc閘道器後是這樣 gRpcHttp閘道器提供哪些功能 可以直接載

Http API服務模組設計方案(服務

Http  API閘道器服務模組設計方案1. 概述                           閘道器作為服務生產者和服務消費者之間的介面,一方面通過“服務路由”為服務消費找到所需服務的具體位置並呼叫;另一方面為後臺伺服器提供負載均衡、安全、流量控制、身份認證等相關功

Spring Cloud Zuul(API服務)(3)

過濾器 在Spring Cloud Zuul中實現的過濾器必須包含4個基本特徵:過濾型別,執行順序,執行條件,具體操作。這就是ZuulFilter介面中定義的4個抽象方法: public abstract String filterType(); public abst

Spring Cloud Zuul(API服務)(2)

路由詳情 傳統路由配置 傳統路由配置方式就是在不依賴與服務發現機制的情況下,通過在配置檔案中具體指定每個路由表示式與服務例項的對映關係來實現API閘道器對外部請求的路由。 單例項配置:通過zuul.routes.<route>.path與zuul.routes.<r

Spring Cloud Zuul(API服務)(1)

API閘道器是一個智慧的應用伺服器,它的定義類似於面向物件設計模式中的Facade模式,它的存在就像是整個微服務架構系統的門面一樣,所有的外部客戶端訪問都需要經過他來進行排程和過濾。它除了要實現請求路由,負載均衡,校驗過濾等功能之外,還需要更多能力,比如與服務治理框架的結合,請求轉發時的熔斷機制

(五)api服務 zuul-路由

路由是微服務架構中必須的一部分,比如,“/” 可能對映到你的WEB程式上,”/api/users “可能對映到你的使用者服務上,“/api/shop”可能對映到你的商品服務商。(註解:我理解這裡的這幾個對映就是說通過Zuul這個閘道器把服務對映到不同的服務商去處理,從而變成了微服務!) 通過Zuu

Spring Cloud系列(二十三) API服務Spring Cloud Zuul(Finchley.RC2版本)

為什麼使用Spring Cloud Zuul? 通過前幾章的介紹,我們對於Spring Cloud Netflix 下的核心元件已經瞭解了大半,利用這些元件我們已經可以構建一個簡單的微服務架構系統,比如通過使用Spring Cloud Eureka實現高可用的服務註冊中

Spring Cloud入門:API服務(Spring Cloud Gateway)

文章例項使用的Spring Cloud版本為Finchley.SR1,Spring Boot版本為2.0.4。 1 Spring Cloud Gateway 在微服務架構中,閘道器作為服務的一個統一入口,所有的外部客戶端訪問都需要經過它來排程和過濾,可以實現的功能包括動

Spring Cloud中的API服務Zuul (13)

轉自 https://blog.csdn.net/u012702547/article/details/77823434 這個系列我感覺真的太好了,可以一步一步的瞭解spring cloud 的搭建以及更深層次的東西,對想學這門技術的朋友真的入門特別的快,感謝這位大哥的分享,我也會持續

java api 驗證框架設計 基於jfinal 設計api

1、api閘道器主要工作: 統一解析引數 、檢驗資料、 2、通過繼承AbstractsApi  自動實現攔截、進行解析,檢驗。 3、整個框架設計圖 介面例項: /** * 內容介面 * * @author OF * @date 2017年12月14日

hystri斷路器+zuul實現ApI+Sidecar異構系統呼叫NodeJS

hystri斷路器:豪豬 代表了一種防禦機制 分散式系統中,依賴呼叫失敗是不可避免的,為了避免一個依賴影響全域性 Netfilx團隊開發了Hystrix,hystrix提供了熔斷 、隔離、fallback、cache、監控等功能,能在一個一個依賴出問題的情況下保證系統可用 請求合併 將一

第七章 API服務:Spring Cloud Zuul

  API閘道器是一個更為智慧的應用伺服器, 它的定義類似於面向物件設計模式中的Facade模式, 它的存在就像是整個微服務架構系統的門面一樣,所有的外部客戶端訪問都需要經過它來進行排程和過濾。它除了要實現請求路由、 負載均衡、 校驗過濾等功能之外, 還需要更多能力, 比如與服務治理框架的結合、 請求轉發時的

.NET Core服務基於Ocelot+Butterfly實現分散式追蹤

一、什麼是Tracing?   微服務的特點決定了功能模組的部署是分散式的,以往在單應用環境下,所有的業務都在同一個伺服器上,如果伺服器出現錯誤和異常,我們只要盯住一個點,就可以快速定位和處理問題,但是在微服務的架構下,大部分功能模組都是單獨部署執行的,彼此通過匯流排互動,都是無狀態的服務,這種架構下,

.NET Core服務基於Ocelot+IdentityServer實現統一驗證與授權

一、案例結構總覽  這裡,假設我們有兩個客戶端(一個Web網站,一個移動App),他們要使用系統

.NET Core服務基於Consul實現服務治理

請求轉發 1.0 asp.net AC port prefix 我們 tle nan 一、Consul基礎介紹   Consul是HashiCorp公司推出的開源工具,用於實現分布式系統的服務發現與配置。與其他分布式服務註冊與發現的方案,比如 Airbnb的Smart