用 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