1. 程式人生 > 其它 >Dapr牽手.NET學習筆記:跨物理機負載均衡服務呼叫

Dapr牽手.NET學習筆記:跨物理機負載均衡服務呼叫

  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……

 

  想要更快更方便的瞭解相關知識,可以關注微信公眾號