Ocelot——初識基於.Net Core的API網關


前言

前不久看到一篇《.NET Core 在騰訊財付通的企業級應用開發實踐》,給現在研究.Net Core及想往微服務方向發展的人來了一劑強心針。於是我也就立刻去下Ocelot的源碼及去閱讀官方文檔。
Ocelot的Github地址:https://github.com/TomPallister/Ocelot
官方文檔地址:http://ocelot.readthedocs.io

環境及安裝

目前版本的Ocelot是基於.Net core 2.0開發的,所以你的項目也得是.net core2.0及以上的。

  1. 新建一個netcoreapp2.0 項目
 dotnet new console -n ApiGateway
  1. 安裝Ocelot
dotnet add package Ocelot
  1. 編寫代碼
    Progarm.cs
using System;
using System.IO;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;

namespace ApiGateway
{
    class Program
    {
        static void Main(string[] args)
        {
            IWebHostBuilder builder = new WebHostBuilder();

            builder.ConfigureServices(s => {
                s.AddSingleton(builder);
            });

            builder.UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>();

            var host = builder.Build();
            
            host.Run();
        }
    }
}

Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;
using CacheManager.Core;
using ConfigurationBuilder = Microsoft.Extensions.Configuration.ConfigurationBuilder;
using System;

namespace ApiGateway
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddJsonFile("configuration.json")
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot(Configuration); //此處添加Ocelot服務
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));

            app.UseOcelot().Wait();//此處使用Ocelot服務
        }
    }
}

  1. 編寫配置文件
    大家可能看到了上述代碼中使用了幾個json文件,我們將configuration.json走位Ocelot的配置文件使用,具體配置內容下面會細說
{
    "ReRoutes": [],
    "GlobalConfiguration": {}
}

至此,一個可運行的API網關即搭建完成(雖然什么都沒有)

配置

Ocelot的使用基本是靠配置完成,我根據官方文檔整理了一份對配置文件的理解,請參考下面注釋

{
    "ReRoutes": [
    {//官方文檔ReRoutes全節點示例
      //Upstream表示上游請求,即客戶端請求到API Gateway的請求
      "UpstreamPathTemplate": "/", //請求路徑模板
      "UpstreamHttpMethod": [ //請求方法數組
        "Get"
      ],

      //Downstreamb表示下游請求,即API Gateway轉發的目標服務地址
      "DownstreamScheme": "http", //請求協議,目前應該是支持http和https
      "DownstreamHost": "localhost", //請求服務地址,應該是可以是IP及域名
      "DownstreamPort": 51779, //端口號
      "DownstreamPathTemplate": "/", //下游請求地址模板
      "RouteClaimsRequirement": { //標記該路由是否需要認證
        "UserType": "registered" //示例,K/V形式,授權聲明,授權token中會包含一些claim,如填寫則會判斷是否和token中的一致,不一致則不准訪問
      },
      //以下三個是將access claims轉為用戶的Header Claims,QueryString,該功能只有認證后可用
      "AddHeadersToRequest": { //
        "UserType": "Claims[sub] > value[0] > |", //示例
        "UserId": "Claims[sub] > value[1] > |"//示例
      },
      "AddClaimsToRequest": {},
      "AddQueriesToRequest": {},

      "RequestIdKey": "", //設置客戶端的請求標識key,此key在請求header中,會轉發到下游請求中
      "FileCacheOptions": { //緩存設置
        "TtlSeconds": 15, //ttl秒被設置為15,這意味着緩存將在15秒后過期。
        "Region": "" //緩存region,可以使用administrator API清除
      },
      "ReRouteIsCaseSensitive": false, //路由是否匹配大小寫
      "ServiceName": "", //服務名稱,服務發現時必填

      "QoSOptions": { //斷路器配置,目前Ocelot使用的Polly
        "ExceptionsAllowedBeforeBreaking": 0, //打開斷路器之前允許的例外數量。
        "DurationOfBreak": 0,                 //斷路器復位之前,打開的時間(毫秒)
        "TimeoutValue": 0                     //請求超時時間(毫秒)
      },
      "LoadBalancer": "", //負載均衡 RoundRobin(輪詢)/LeastConnection(最少連接數)
      "RateLimitOptions": { //官方文檔未說明
        "ClientWhitelist": [],
        "EnableRateLimiting": false,
        "Period": "",
        "PeriodTimespan": 0,
        "Limit": 0
      },
      "AuthenticationOptions": { //認證配置
        "AuthenticationProviderKey": "", //這個key對應的是代碼中.AddJWTBreark中的Key
        "AllowedScopes": []//使用范圍
      },
      "HttpHandlerOptions": {
        "AllowAutoRedirect": true, //指示請求是否應該遵循重定向響應。 如果請求應該自動遵循來自Downstream資源的重定向響應,則將其設置為true; 否則為假。 默認值是true。
        "UseCookieContainer": true //該值指示處理程序是否使用CookieContainer屬性來存儲服務器Cookie,並在發送請求時使用這些Cookie。 默認值是true。
      },
      "UseServiceDiscovery": false //使用服務發現,目前Ocelot只支持Consul的服務發現
    }
    ],
    "GlobalConfiguration": {}
}

路由 Routing

路由是API網關的標配,Ocelot會將上游請求(Upstream)轉發到下游請求(Downstream)
示例:

{
    "DownstreamPathTemplate": "/api/posts/{postId}",
    "DownstreamScheme": "https",
    "DownstreamPort": 80,
    "DownstreamHost" "localhost",
    "UpstreamPathTemplate": "/posts/{postId}",
    "UpstreamHttpMethod": [ "Put", "Delete" ]
}

其中使用{任意字符}括住的作為占位符變量使用,轉發請求時,會將下游請求的{任意字符}替換為上游請求的{任意字符}。
Ocelot的默認路由是不區分大小寫的,如果需要區分大小寫,需要增加如下配置

"ReRouteIsCaseSensitive": true

了解路由后一個基礎的API網關就建立而成了,下一篇講介紹下其他功能


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM