EngineeringSolution ArchitectAzure Playbooks

Azure Service Bus + Azure Functions – Playbook Tích Hợp Enterprise

Kịch bản

Một micro-service .NET xuất bản (publish) các sự kiện domain (domain events) lên Azure Service Bus (gói Standard). Một Azure Function (được trigger bởi Service Bus) xử lý sự kiện, thực hiện xác thực, làm giàu dữ liệu (enrichment), và lưu trữ xuống Azure SQL.

Yêu cầu trước

  • Azure subscription với tên miền Service Bus đã được tạo.
  • Azure Function App (v4, .NET 8) với bộ Service Bus trigger.
  • Service Principal với quyền Contributor trên cả hai tài nguyên.
  • Tuỳ chọn: Managed Identity cho Function để truy cập Azure SQL mà không cần chuỗi bí mật (secrets).

Các bước thực hiện

  1. Tạo Service Bus Namespace & Queue
    bash
    az servicebus namespace create \
        --resource-group rg-prod \
        --name sb-namespace \
        --sku Standard
    az servicebus queue create \
        --resource-group rg-prod \
        --namespace-name sb-namespace \
        --name orders-queue
    
  2. Thêm Shared Access Policy (Chỉ cho phép gửi - Send đối với app .NET)
    bash
    az servicebus namespace authorization-rule create \
        --resource-group rg-prod \
        --namespace-name sb-namespace \
        --name sb-send-policy \
        --rights Send
    
    Lấy giá trị của PrimaryKey; lưu nó trong Azure Key Vault.
  3. Tạo Azure Function (C#)
    csharp
    public class OrderProcessor
    {
        private readonly ILogger<OrderProcessor> _log;
        private readonly IDbConnection _db;
    
        public OrderProcessor(ILogger<OrderProcessor> log, IDbConnection db)
        {
            _log = log;
            _db = db;
        }
    
        [Function("ProcessOrder")]
        public async Task Run([ServiceBusTrigger("orders-queue", Connection = "ServiceBusConnection")] string message)
        {
            var order = JsonSerializer.Deserialize<OrderDto>(message);
            // Xác thực nghiệp vụ
            if (order.Total < 0) throw new InvalidOperationException("Negative total");
            // Làm giàu dữ liệu (ví dụ: lấy dữ liệu khách hàng)
            var enriched = await EnrichAsync(order);
            // Lưu xuống DB
            await _db.ExecuteAsync("INSERT INTO dbo.Orders ...", enriched);
            _log.LogInformation("Order {Id} processed", order.Id);
        }
    }
    
    • Chuỗi kết nối Connection string (ServiceBusConnection) được đọc từ App Settings (hoặc Managed Identity).
    • Đăng ký IDbConnection trong Program.cs qua hệ thống tiêm phụ thuộc DI.
  4. Cấu hình Settings cho Function App
    json
    {
      "ServiceBusConnection": "Endpoint=sb://sb-namespace.servicebus.windows.net/;SharedAccessKeyName=sb-send-policy;SharedAccessKey=<key>"
    }
    
    Thay vì nhúng trực tiếp, tốt nhất là tham chiếu tới Key Vault secret: @Microsoft.KeyVault(SecretUri=https://kv-prod.vault.azure.net/secrets/ServiceBusConnection).
  5. Triển khai - Deploy Function
    bash
    func azure functionapp publish func-order-processor --csharp
    
  6. Publish sự kiện (Events) xuất từ dịch vụ .NET
    csharp
    var client = new ServiceBusClient(Environment.GetEnvironmentVariable("ServiceBusConnection"));
    var sender = client.CreateSender("orders-queue");
    var message = new ServiceBusMessage(JsonSerializer.Serialize(orderDto));
    await sender.SendMessageAsync(message);
    
    Sử dụng cấu hình RetryOptions và đảm bảo Idempotency (ví dụ: đi kèm thuộc tính định danh MessageId).
  7. Giám sát & Cảnh báo
    • Thiết lập các số đo hiệu năng Azure Monitor cho dữ liệu thống kê từ Service Bus (Dead-letter count, tin nhắn Đến/Đi).
    • Thiết lập Application Insights cho hệ thống giám sát Function (tự động nhận message logs, lỗi hệ thống - exceptions, số đo khoảng xử lý - duration).
    • Thiết lập tự động Alert cảnh báo các tin failed trên hàng đợi (dead-letter > 0) để tự động kích hoạt PagerDuty incident.

Mẹo thực hành tốt nhất

  • Dùng Sessions nếu muốn giữ thứ tự processing chính xác dựa trên từng đối tượng tương tác.
  • Hệ thống hỗ trợ xử lý thông báo thất bại Dead-letter handling: Đối lập lỗi domain ngoại lệ catch exception với await args.DeadLetterMessageAsync(reason) nếu không muốn hệ thống treo tự giải phóng process.
  • Logic lập xử lý tránh trùng Idempotent processing: Dữ lại MessageId lưu riêng qua DB table sau lần đầu và sử phạt tin nhắn tới trùng lặp.
  • Hệ thống hỗ trợ mở rộng quy mô thông minh Scale-out: Bản Standard tích hợp Service Bus hỗ trợ lên 1000 lệnh function cùng thi hành. Lập điều hướng qua biến parameter json điều khiển maxConcurrentCalls tham khảo trong host.json.
  • Hệ bảo mật thông tin biến cấu hình Secure secrets: Cài điều hướng bảo vệ từ client cho chuỗi strings điều hướng truy cập qua app bằng config API kết hợp xác thực server Managed Identity kèm Key Vault.

Các tài liệu được sắp xếp vào thư mục con thuộc chuyên trang wiki dành cho Senior, vui lòng kiểm tra khoá tham chiếu - phân loại mục Azure Playbooks.