用 YARP 當網關

Yarp 是微軟開源的一個用. net 實現的反向代理工具包,github 庫就叫 reverse-proxy(反向代理)(吐槽一下微軟起名字 233333)
nuget 包 preview9 之前都叫 Microsoft.ReverseProxy,preview10 變成 Yarp.ReverseProxy 了
放上鍊接 https://github.com/microsoft/reverse-proxy

使用背景

由於公司技術歷史原因,原來的網關規則是 {paramA}_ {paramB} _ {paramC}_{paramD} 這樣子的。
想要換個新網關,又要兼容舊的這種規則,調研過目前幾種 API 網關發現,apiSix 支持這種操作(用 $1 佔位符匹配參數)。
但是目前暫時不需要功能那麼強大的 api 網關,而且不是. net 技術實現的,出問題不好排查。
這是剛好發現 Yarp 這個東東,剛剛好符合需求,就拿來試試。

怎麼用 Yarp

Yarp 主要要配置的東西就是 Cluster(集羣)和 ProxyRoute(路由)
最簡單的用法直接使用 appsettings.json 配置集羣和路由配置
下面內容照搬 Yarp 的 Getting Started 內容
詳細的配置項可以直接看文檔~~

"ReverseProxy": {
   "Routes": [
     {
       "RouteId": "route1",
       "ClusterId": "cluster1",
       "Match": {
         "Path": "{**catch-all}"
       },
     }
   ],
   "Clusters": {
     "cluster1": {
       "Destinations": {
         "cluster1/destination1": {
           "Address": "https://example.com/"
         }
       }
     }
   }
 }

需要在 startup.cs 中配置 Yarp

public IConfiguration Configuration { get; }

public Startup(IConfiguration configuration)
{
    Configuration = configuration;
}

public void ConfigureServices(IServiceCollection services) 
{ 
    // Add the reverse proxy to capability to the server
    var proxyBuilder = services.AddReverseProxy();
    // Initialize the reverse proxy from the "ReverseProxy" section of configuration
    proxyBuilder.LoadFromConfig(Configuration.GetSection("ReverseProxy"));
} 

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    
    // Enable endpoint routing, required for the reverse proxy
    app.UseRouting();
    // Register the reverse proxy routes
    app.UseEndpoints(endpoints => 
    {
        endpoints.MapReverseProxy(); 
    }); 
}

改造一下用法,使用持久化儲存配置

第一步,翻源碼,找到配置的實體對象,照搬微調一遍,大概就是下圖那麼多個了。

第二步,實現 IProxyConfigProvider 和 IProxyConfig,基本都是照搬原本代碼微整形一下 233333


由於源碼裏面 ICertificateConfigLoader 是 internal 類型,只能自己重新抄一次並實現了。

第三步,用 EFCore 持久化到數據庫
搞個 DBContext,把實體全部加進去,配置好關係之後,CodeFirst 直接生成數據庫哈哈哈哈

第四步,搞幾個 Management 管理數據(CURD)

第五步,實現一下配置熱更新
使用 IChangeToken 接口實現一個 EFCoreReloadToken

在 InStoreConfigProvider 的 GetConfig 用 ChangeToken.OnChange 綁定一下事件

public IProxyConfig GetConfig()
        {
            // First time load
            if (_config == null)
            {
                _subscription = ChangeToken.OnChange(_strore.GetReloadToken, UpdateConfig);
                UpdateConfig();
            }
            return _config;
        }

_strore 是 EFCoreReverseProxyStore 對象,裏面包含 EFCoreReloadToken 對象;

public class EFCoreReverseProxyStore : IReverseProxyStore
    {
        private EFCoreReloadToken _reloadToken = new EFCoreReloadToken();
        private IServiceProvider _sp;
        private IMemoryCache _cache;
        private readonly ICertificateConfigLoader _certificateConfigLoader;

        public EFCoreReverseProxyStore(IServiceProvider sp, IMemoryCache cache, ICertificateConfigLoader certificateConfigLoader)
        {
            _sp = sp;
            _cache = cache;
            _certificateConfigLoader = certificateConfigLoader;
        }
//more code....
}

在要觸發更新配置的時候調用一下 IReverseProxyStore.Reload() 就可以重新加載配置了~~

第六步,再寫個擴展方法替換原本的 IProxyConfigProvider

最後一步,在 Startup 中用一下

services.AddReverseProxy()
                .LoadFromEFCore();

數據管理好了,差個界面(找前端小姐姐要一個)

第一步,搞個控制器,加上簡單 CURD 接口


好了搞完可以用了,試一試

搞一個測試 WebAPi

加一個集羣

加一個路由

用 Postman 測一測

好了正常使用,搞定。

路由匹配可以用多個佔位符自由組合,然後在 PathPattern 轉換裏面可以使用這些參數

測試一下性能 1000 個併發 100000 個請求

最後放下代碼~~

歡迎吐槽提意見或者一起改進哈哈哈
ReverseProxy.Store:https://github.com/fanslead/ReverseProxy.Store

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/IujFaTFT23hcN8NVCaU7YQ