聊一聊Yarp結合Nacos完成服務發現

背景

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章