Dapr 牽手 DotNET 學習筆記:跨物理機負載均衡服務調用

dpar 在同一臺電腦上不能 run 相同 appid,這個在上篇說過,所以就用外部負載均衡 nginx 來對應,那在不同的 host 中跑同一服務,看看 dapr 內部的負載均衡是怎麼實現的。

說說現有的服務,兩個服務,訂單服務,支付服務;下完訂單後同步調支付服務。

一、demo 項目的 mock 代碼

OrderSystem 項目,端口 5000

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
using System.Threading.Tasks;
namespace OrderSystem.Controllers;
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{
    private readonly ILogger<HomeController> _logger;
    private readonly IHttpClientFactory _clientFactory;
    private readonly string? _payUrl;
    public HomeController(ILogger<HomeController> logger, IHttpClientFactory clientFactory, IConfiguration configuration)
    {
        _payUrl = configuration.GetSection("payurl").Value;
        _clientFactory = clientFactory;
        _logger = logger;
    }
    [HttpGet("/order")]
    public async Task<IActionResult> Order()
    {
        _logger.LogInformation($"下單開始");
        await Task.Delay(400);
        _logger.LogInformation($"訂單完成   調用支付系統");
        var client = _clientFactory.CreateClient();
        var content = await client.GetStringAsync(_payUrl);
        return new JsonResult(new { pay_result = content });
    }
}

appsettings.json

{
  "Urls": "http://*:5000",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "PayUrl""http://localhost:3500/v1.0/invoke/payment/method/pay"
}

PaymentSystem 項目,端口 6000

using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Net;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
namespace PaymentSystem.Controllers;
[ApiController]
[Route("[controller]")]
public class HomeController : ControllerBase
{
    private readonly ILogger<HomeController> _logger;
    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }
    [HttpGet("/pay")]
    public async Task<IActionResult> TestGet()
    {
        _logger.LogInformation($"開始支付");
        await Task.Delay(200);
        _logger.LogInformation($"支付完成");
        return new JsonResult(new { result = true, message = "支付成功", host = Dns.GetHostName() });
    }
}

appsettings.json

{
  "Urls": "http://*:6000",
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

二、應用部署調用關係圖

在 windows10 部署 order 服務,並啓動 sidecar

dapr run --app-id order --app-port 5000  --dapr-http-port 3500

在 windows10 和 mac 下分別部署 pay 服務,並啓動 sidecar

dapr run --app-id pay --app-port 6000 --dapr-http-port 3600

三、測試

postman 調用地址:localhost:3500/v1.0/invoke/order/method/order

在多次調用中,支付接口返回的結果中的 host 是在變換的,說明 pay 達到了負載均衡的效果(dapr 本地部署負載均衡的服務發現是用 mDNS 來實現的,通過 sidecar 把各自代碼服務的信息多路廣播到局域網中的其他 sidecar,來共享同步服務的相關信息)。

返回結果 1:

返回結果 2:

心得:

受到傳統的負載均衡器的測試影響,總想把 Pay 服務在兩個電腦上跑起來,用 postman 直接連 http://localhost:3600/v1.0/invoke/pay/method/pay 調用,看兩個服務是不是輪詢訪問,這裏就與 dapr 的思想不一致了。

dapr 最核心的功能通過 sidecar 代表應用,來處理一切事務,sidecar 是全權代表,意思調用者也有自己的 sidecar,給自己的 sidecar 索要外部資源。上例中 order 端口 5000,sidecare 的 http 端口是 3500,它們是一組;pay 端口是 6000,sidecar 的 http 端口是 3600;如果 order 調用 pay,那 order 應該在自己 sidecare 的 3500 端口上調用 pay,所以調用地址是:http://localhost:3500/v1.0/invoke/pay/method/pay。

換句話說,如果想用 postman 調用 pay 服務,同理,需要給 postman 起個 3400 的 sidecare,也可以用 postman 調 http://localhost:3400/v1.0/invoke/pay/method/pay 來訪問 pay 服務了,相當於 postman 和 3400 的 sidecar 是一家人,內部調用,全權代理,這樣被調用的 pay 就會在 win 和 mac 上輪詢調用了。

所以這裏需要默唸 10 次:服務和它的 sidecar 是一家人,有困難找自己的 sidecar……

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