1. 程式人生 > >體驗用yarp當閘道器

體驗用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](https://microsoft.github.io/reverse-proxy/articles/getting_started.html)內容 詳細的配置項可以直接看文件~~ ``` "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(); }); } ``` ## 改造一下用法,使用持久化儲存配置 第一步,翻原始碼,找到配置的實體物件,照搬微調一遍,大概就是下圖那麼多個了。 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331181153801-1580262166.png) 第二步,實現IProxyConfigProvider和IProxyConfig,基本都是照搬原本程式碼微整形一下233333 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331181346074-309716082.png) ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331181355515-530622593.png) 由於原始碼裡面ICertificateConfigLoader是internal型別,只能自己重新抄一次並實現了。 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331181545590-1553568044.png) 第三步,用EFCore持久化到資料庫 搞個DBContext,把實體全部加進去,配置好關係之後,CodeFirst直接生成資料庫哈哈哈哈 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331181806864-1803492896.png) 第四步,搞幾個Management管理資料(CURD) ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182001582-390252462.png) 第五步,實現一下配置熱更新 使用IChangeToken介面實現一個EFCoreReloadToken ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182105586-2005135769.png) 在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 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182224103-1769406400.png) 最後一步,在Startup中用一下 ``` services.AddReverseProxy() .LoadFromEFCore(); ``` ## 資料管理好了,差個介面(找前端小姐姐要一個) 第一步,搞個控制器,加上簡單CURD介面 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182510065-473355878.png) 第二步,找前端小姐姐要個介面對接一下API ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182656173-1422469742.png) ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182600443-1076466146.png) ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182707406-269059050.png) ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182618126-905576364.png) ## 好了搞完可以用了,試一試 搞一個測試WebAPi ![](https://img2020.cnblogs.com/blog/1313665/202104/1313665-20210401101531535-832182929.png) 加一個叢集 ![](https://img2020.cnblogs.com/blog/1313665/202104/1313665-20210401100047931-1232390057.png) 加一個路由 ![](https://img2020.cnblogs.com/blog/1313665/202104/1313665-20210401095936138-545900188.png) 用Postman測一測 ![](https://img2020.cnblogs.com/blog/1313665/202104/1313665-20210401100321334-1397177029.png) 好了正常使用,搞定。 路由匹配可以用多個佔位符自由組合,然後在PathPattern轉換裡面可以使用這些引數 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331182824810-696147096.png) 測試一下效能1000個併發100000個請求 ![](https://img2020.cnblogs.com/blog/1313665/202103/1313665-20210331183103362-1188285556.png) ## 最後放下程式碼~~ 歡迎吐槽提意見或者一起改進哈哈哈 [ReverseProxy.Store](https://github.com/fanslead/ReverseProxy.Store)