背景
Yarp 這個反向代理出來後,相信還是有不少人在關注的。
在 Yarp 中,反向代理的配置默認也是基於配置文件的,也有不少大佬已經把這個配置做成了數據庫配置+可視化界面。
仔細想了想,做成數據庫配置,好像只是便於配置的管理,對服務註冊和發現這一塊還是偏弱。
好比訂單服務加了 3 個實例,這個時候要去配置一下,把這 3 個實例加進去。
如果增加的服務多了,頻率高了,肯定是不太想人工去介入的,會嫌麻煩。
尤其是在引入了註冊中心的情況下,都會想讓它自動適配這些變化。
基於這個情況,老黃花時間嘗試了一下把 Yarp 和 Nacos 結合,讓服務和實例的新增、減少做了一個適配,可以動態化,一定程度減少了人爲的干預。
下面簡單看看。
示例服務
準備下面的服務
- YarpWithNacosSample 反向代理集成
- OrderSvcA 訂單服務-A
- OrderSvcB 訂單服務-B
- UserSvc 用戶服務
其中兩個訂單服務是爲了模擬服務實例上下線的,用戶服務是模擬服務上下線的。
下面三個業務服務,代碼基本一樣
只貼出用戶服務的。
using Nacos.AspNetCore.V2;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddNacosAspNet(builder.Configuration);
builder.Services.AddControllers();
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/", () =>
{
return Results.Ok("user svc 9001");
});
});
app.Run("http://*:9001");
然後是配置
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Nacos.AspNetCore": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"nacos": {
"ServerAddresses": [ "http://localhost:8848" ],
"DefaultTimeOut": 15000,
"Namespace": "yarp",
"ListenInterval": 1000,
"ServiceName": "usersvc",
"GroupName": "DEFAULT_GROUP",
"ClusterName": "DEFAULT",
"Weight": 100,
"RegisterEnabled": true,
"InstanceEnabled": true,
"Ephemeral": true,
"Secure": false,
"ConfigUseRpc": true,
"NamingUseRpc": true
}
}
再來看看重點的反向代理這一塊。
using global::Nacos.V2.DependencyInjection;
using Yarp.ReverseProxy.Configuration;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddNacosV2Naming(x =>
{
x.ServerAddresses = new List<string> { "http://localhost:8848/" };
x.Namespace = "yarp";
x.NamingUseRpc = true;
});
builder.Services.AddReverseProxy()
.AddNacosServiceDiscovery(
groupNames: "DEFAULT_GROUP",
percount:100,
enableAutoRefreshService: true,
autoRefreshPeriod: 30);
var app = builder.Build();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/yarp", (IProxyConfigProvider provider) =>
{
var res = provider.GetConfig();
return Results.Ok(res);
});
endpoints.MapReverseProxy();
});
app.Run("http://*:9091");
可以看到,反向代理這個項目並沒有註冊到 Nacos 上面去,因爲它只需要發現其他服務,並不需要被其他服務發現。
先啓動 OrderSvcA,讓其註冊到 Nacos。
再啓動反向代理項目,這個時候可以看到日誌,有輸出 OrderSvcA 加入的痕跡。
然後訪問 localhost:9091/yarp
看一下當前的配置。
再通過反向代理訪問一下 OrderSvc。
接下來啓動 OrderSvcB,讓其註冊到 Nacos。
這個時候,反向代理項目會顯示把這個新實例加進去了。
這個時候訪問會有負載均衡的策略去訪問 ordersvc。
最後再來看看新服務上線的情況,啓動 UserSvc。
再訪問的話,也是正常的。
這裏需要注意的是,新加的服務,不會實時更新到配置中,取決於自動刷新的間隔,因爲 Nacos 目前沒有提供服務變動的通知,只有服務實例的,所以這一塊是要定時主動去查詢的。
到這裏的話,基本上演示就結束了。
不過有人應該會對轉發規則那一塊有疑問,爲什麼是 【反向代理地址/服務名/服務的相對路徑】
這一個是默認的實現,因爲規則這一塊,一百個人就會有一百個不一樣的,有想放請求頭的,查詢參數的等等,所以這一個是開放的,可以自由替換。
寫在最後
Yarp 還是個比較有意思的項目,後面應該會有不少人使用。
目前這個擴展包還是預覽版,沒有發佈正式版,主要是想豐富一下內容。
nacos-sdk-csharp 的地址 :https://github.com/nacos-group/nacos-sdk-csharp
nacos-csharp-extensions 的地址: https://github.com/catcherwong/nacos-csharp-extensions
本文示例代碼的地址 :https://github.com/catcherwong-archive/2021/tree/main/YarpWithNacosSample