Nguon: Microsoft Learn · .NET 8.0

YARP — Session Affinity (Ái lực phiên)

Nguồn: YARP Session Affinity

Khái niệm

Session affinity (ái lực phiên) là cơ chế để ràng buộc (affinitize — gắn kết) một chuỗi request liên quan nhân quả với destination đã xử lý request đầu tiên khi tải được phân bổ giữa nhiều destination. Nó hữu ích trong các kịch bản mà hầu hết các request trong một chuỗi làm việc với cùng dữ liệu và chi phí truy cập dữ liệu khác nhau giữa các node (destination) xử lý request. Ví dụ phổ biến nhất là caching tạm thời (ví dụ: in-memory) trong đó request đầu tiên tải dữ liệu từ bộ lưu trữ bền vững chậm hơn vào cache cục bộ nhanh, và những request sau chỉ làm việc với dữ liệu đã được cache, từ đó tăng throughput.

Cấu hình

Đăng ký services và middleware

Các service session affinity được đăng ký tự động trong DI container bởi AddReverseProxy(). Middleware UseSessionAffinity() được bao gồm mặc định trong phương thức MapReverseProxy không có tham số. Nếu bạn đang tùy chỉnh pipeline proxy, hãy đặt middleware này trước khi thêm UseLoadBalancing().

Ví dụ:

csharp
app.MapReverseProxy(proxyPipeline =>
{
    proxyPipeline.UseSessionAffinity();
    proxyPipeline.UseLoadBalancing();
});

Lưu ý Một số triển khai session affinity phụ thuộc vào Data Protection (bảo vệ dữ liệu), sẽ yêu cầu cấu hình bổ sung cho các kịch bản như nhiều proxy instance. Xem Key Protection để biết chi tiết.

Cấu hình Cluster

Session affinity được cấu hình theo cluster theo sơ đồ cấu hình sau.

json
"ReverseProxy": {
  "Clusters": {
    "<cluster-name>": {
      "SessionAffinity": {
        "Enabled": "(true|false)", // mặc định là 'false'
        "Policy": "(HashCookie|ArrCookie|Cookie|CustomHeader)", // mặc định là 'HashCookie'
        "FailurePolicy": "(Redistribute|Return503Error)", // mặc định là 'Redistribute'
        "AffinityKeyName": "Key1",
        "Cookie": {
          "Domain": "localhost",
          "Expiration": "03:00:00",
          "HttpOnly": true,
          "IsEssential": true,
          "MaxAge": "1.00:00:00",
          "Path": "mypath",
          "SameSite": "Strict",
          "SecurePolicy": "Always"
        }
      }
    }
  }
}

Các thuộc tính để cấu hình cookie được dùng với các policy HashCookie, ArrCookie và Cookie có thể được cấu hình bằng SessionAffinityCookieConfig:

csharp
new ClusterConfig
{
    ClusterId = "cluster1",
    SessionAffinity = new SessionAffinityConfig
    {
        Enabled = true,
        FailurePolicy = "Return503Error",
        Policy = "HashCookie",
        AffinityKeyName = "Key1",
        Cookie = new SessionAffinityCookieConfig
        {
            Domain = "mydomain",
            Expiration = TimeSpan.FromHours(3),
            HttpOnly = true,
            IsEssential = true,
            MaxAge = TimeSpan.FromDays(1),
            Path = "mypath",
            SameSite = Microsoft.AspNetCore.Http.SameSiteMode.Strict,
            SecurePolicy = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest
        }
    }    
}

Affinity Key (Khóa ái lực)

Sự ràng buộc request-to-destination được thiết lập thông qua affinity key (khóa ái lực) xác định destination mục tiêu. Khóa đó có thể được lưu ở các phần khác nhau của request tùy thuộc vào triển khai session affinity, nhưng mỗi request không thể có nhiều hơn một khóa như vậy. Ngữ nghĩa của khóa phụ thuộc vào triển khai, nhưng các policy tích hợp hiện tại sử dụng DestinationId làm affinity key.

Thiết kế hiện tại không yêu cầu khóa phải xác định duy nhất một destination được gắn kết. Có thể thiết lập affinity (ái lực) cho một nhóm destination. Trong trường hợp đó, destination chính xác để xử lý request sẽ được xác định bởi load balancer.

Thiết lập affinity mới hoặc giải quyết affinity đã tồn tại

Khi một request đến và được định tuyến đến một cluster có session affinity được bật, proxy tự động quyết định liệu có nên thiết lập affinity mới hay cần giải quyết một affinity đã có dựa trên sự hiện diện và tính hợp lệ của affinity key trên request:

  1. Request không chứa key. Việc giải quyết bị bỏ qua và một affinity mới sẽ được thiết lập đối với destination được load balancer chọn.
  2. Affinity key được tìm thấy trên request và hợp lệ. Cơ chế affinity cố gắng tìm tất cả destination lành mạnh khớp với key, và nếu tìm thấy, nó chuyển request xuống pipeline. Nếu tìm thấy nhiều destination khớp, load balancer được gọi để chọn destination mục tiêu duy nhất.
  3. Affinity key không hợp lệ hoặc không tìm thấy destination lành mạnh. Được coi là lỗi và được xử lý bởi failure policy.

Nếu một affinity mới được thiết lập cho request, affinity key sẽ được đính kèm vào response. Biểu diễn và vị trí của khóa phụ thuộc vào triển khai. Sau khi response được giao cho client, client có trách nhiệm đính kèm khóa vào tất cả các request tiếp theo trong cùng phiên. Khi request tiếp theo mang khóa đến proxy, nó giải quyết affinity đã có, nhưng affinity key không được đính kèm lại vào response. Do đó, chỉ response đầu tiên mang affinity key.

Có bốn policy affinity tích hợp sẵn định dạng và lưu trữ khóa khác nhau:

Quan trọng: AffinityKeyName phải là duy nhất trên tất cả các cluster có session affinity được bật để tránh xung đột.

Bảo vệ Key (Key Protection)

Failure policy (Chính sách thất bại)

Nếu affinity key không thể được giải mã hoặc không tìm thấy destination lành mạnh, đây được coi là thất bại và một affinity failure policy được gọi. Policy có toàn quyền truy cập HttpContext và có thể tự gửi response cho client. Nó trả về giá trị boolean cho biết liệu việc xử lý request có thể tiếp tục hay phải kết thúc.

Có hai failure policy tích hợp sẵn. Mặc định là Redistribute.

  1. Redistribute — Cố gắng thiết lập một affinity mới với một trong các destination lành mạnh bằng cách bỏ qua bước tra cứu affinity và truyền tất cả destination lành mạnh cho load balancer. Việc xử lý request tiếp tục.
  2. Return503Error — Gửi response 503 về client và việc xử lý request bị kết thúc.

Request pipeline

Các cơ chế session affinity được triển khai bởi hai middleware sau:

  1. SessionAffinityMiddleware — Điều phối quá trình giải quyết affinity của request. Đầu tiên, nó gọi policy được chỉ định cho cluster. Sau đó, kiểm tra trạng thái giải quyết affinity được trả về bởi policy, và gọi failure handling policy trong trường hợp thất bại. Phải được thêm vào pipeline trước load balancer.
  2. AffinitizeTransform — Đặt khóa trên response nếu một affinity mới đã được thiết lập cho request. Ngược lại, nếu request tuân theo một affinity đã có, nó không làm gì. Transform này được tự động thêm vào như một response transform.