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ụ:
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.
"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ấu hình Cookie
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:
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:
- 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.
- 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.
- 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:
HashCookie,ArrCookievàCookie: lưu khóa dưới dạng cookie (được hash hoặc mã hóa). Tên cookie phải được đặt tường minh quaSessionAffinityConfig.AffinityKeyName.CustomHeader: lưu khóa dưới dạng header được mã hóa. Tên header phải được đặt quaSessionAffinityConfig.AffinityKeyName.
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)
- Policy
HashCookiesử dụng hash XxHash64 để tạo ra định dạng đầu ra nhanh, gọn, bị làm mờ cho giá trị cookie. - Policy
ArrCookiesử dụng hash SHA-256 để tạo đầu ra bị làm mờ cho giá trị cookie khớp với định dạng affinity cookie ARR của IIS. ARR sử dụng tên host của destination làm giá trị đầu vào, vì vậy destination id của YARP cần được cấu hình để khớp nếu dùng kết hợp với ARR. HashCookievàArrCookiekhông cung cấp bảo vệ riêng tư mạnh mẽ và dữ liệu nhạy cảm không nên được đưa vào destination id.- Các policy
CookievàCustomHeadermã hóa khóa bằng Data Protection, cung cấp bảo vệ riêng tư mạnh mẽ nhưng yêu cầu cấu hình bổ sung khi có nhiều hơn một proxy instance.
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.
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.Return503Error— Gửi response503về 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:
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.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.