YARP Extensibility Configuration Providers (Nhà cung cấp cấu hình mở rộng YARP)
Giới thiệu
Mẫu Basic Yarp Sample cho thấy cấu hình proxy được tải từ appsettings.json. Thay vào đó, cấu hình proxy có thể được tải theo chương trình từ nguồn bạn chọn. Bạn thực hiện điều này bằng cách cung cấp một vài lớp triển khai IProxyConfigProvider và IProxyConfig.
Xem ReverseProxy.Code.Sample để biết ví dụ về custom configuration provider (nhà cung cấp cấu hình tùy chỉnh).
Cấu hình có thể được sửa đổi trong quá trình tải bằng cách sử dụng Configuration Filters.
Cấu trúc
IProxyConfigProvider có một phương thức duy nhất GetConfig() nên trả về một instance của IProxyConfig. IProxyConfig có danh sách các route (tuyến đường) và cluster (cụm) hiện tại, cũng như một IChangeToken để thông báo cho proxy khi thông tin này lỗi thời và cần được tải lại, điều này sẽ khiến GetConfig() được gọi lại.
Routes (Tuyến đường)
Phần routes là một tập hợp không có thứ tự của các route được đặt tên. Một route chứa các điều kiện match (khớp) và cấu hình liên quan. Một route yêu cầu ít nhất các trường sau:
- RouteId - một tên duy nhất
- ClusterId - tham chiếu đến tên của một mục trong phần clusters
- Match - chứa mảng Hosts hoặc chuỗi pattern Path. Path là một ASP.NET Core route template có thể được định nghĩa như giải thích ở đây
Headers, Authorization, CORS, và các policy (chính sách) dựa trên route khác có thể được cấu hình trên mỗi mục route. Để biết thêm các trường, xem RouteConfig.
Proxy sẽ áp dụng các tiêu chí matching và policy đã cho, sau đó chuyển yêu cầu đến cluster được chỉ định.
Clusters (Cụm)
Phần clusters là một tập hợp không có thứ tự của các cluster được đặt tên. Một cluster chủ yếu chứa tập hợp các destination (đích) được đặt tên và địa chỉ của chúng, bất kỳ destination nào đều được coi là có khả năng xử lý các yêu cầu cho một route nhất định. Proxy sẽ xử lý yêu cầu theo cấu hình route và cluster để chọn một destination.
Để biết thêm các trường, xem ClusterConfig.
In Memory Config (Cấu hình trong bộ nhớ)
InMemoryConfigProvider triển khai IProxyConfigProvider và cho phép chỉ định routes và clusters trực tiếp trong code bằng cách gọi LoadFromMemory.
services.AddReverseProxy().LoadFromMemory(routes, clusters);
Để cập nhật cấu hình sau đó, resolve InMemoryConfigProvider từ services container và gọi Update với danh sách mới của routes và clusters.
httpContext.RequestServices.GetRequiredService<InMemoryConfigProvider>().Update(routes, clusters);
Lifecycle (Vòng đời)
Startup (Khởi động)
IProxyConfigProvider nên được đăng ký trong DI container (vùng chứa Dependency Injection) dưới dạng singleton. Khi khởi động, proxy sẽ resolve instance này và gọi GetConfig(). Ở lần gọi đầu tiên này, provider có thể chọn:
- Ném exception nếu provider không thể tạo ra cấu hình proxy hợp lệ vì bất kỳ lý do nào. Điều này sẽ ngăn ứng dụng khởi động.
- Chặn đồng bộ trong khi tải cấu hình. Điều này sẽ chặn ứng dụng khởi động cho đến khi có dữ liệu route hợp lệ.
- Hoặc có thể chọn trả về một instance
IProxyConfigrỗng trong khi tải cấu hình ở chế độ nền. Provider sẽ cần kích hoạtIChangeTokenkhi cấu hình có sẵn.
Proxy sẽ xác thực cấu hình đã cho và nếu không hợp lệ, một exception sẽ được ném ra để ngăn ứng dụng khởi động. Provider có thể tránh điều này bằng cách sử dụng IConfigValidator để pre-validate (xác thực trước) routes và clusters và thực hiện bất kỳ hành động nào nó cho là phù hợp, chẳng hạn như loại trừ các mục không hợp lệ.
Atomicity (Tính nguyên tử)
Các đối tượng và bộ sưu tập cấu hình được cung cấp cho proxy phải là read-only (chỉ đọc) và không được sửa đổi sau khi chúng đã được chuyển cho proxy qua GetConfig().
Reload (Tải lại)
Nếu IChangeToken hỗ trợ ActiveChangeCallbacks, sau khi proxy đã xử lý tập cấu hình ban đầu, nó sẽ đăng ký một callback với token này. Nếu provider không hỗ trợ callbacks thì HasChanged sẽ được poll mỗi 5 phút.
Khi provider muốn cung cấp cấu hình mới cho proxy, nó nên:
- Tải cấu hình đó ở chế độ nền.
- Các đối tượng route và cluster là immutable (bất biến), vì vậy cần tạo instance mới cho bất kỳ dữ liệu mới nào.
- Các đối tượng cho các route và cluster không thay đổi có thể được tái sử dụng hoặc tạo instance mới - các thay đổi sẽ được phát hiện bằng cách diff (so sánh) chúng.
- Tùy chọn xác thực cấu hình bằng IConfigValidator, và chỉ sau đó mới signal (báo hiệu)
IChangeTokentừ instanceIProxyConfigtrước đó rằng có dữ liệu mới. Proxy sẽ gọiGetConfig()lại để lấy dữ liệu mới.
Có những điểm khác biệt quan trọng khi reload cấu hình so với lần tải cấu hình đầu tiên:
- Cấu hình mới sẽ được diff với cấu hình hiện tại và chỉ các route hoặc cluster đã sửa đổi mới được cập nhật. Bản cập nhật sẽ được áp dụng nguyên tử và chỉ ảnh hưởng đến các yêu cầu mới, không phải các yêu cầu đang xử lý.
- Bất kỳ lỗi nào trong quá trình reload sẽ được ghi log và bỏ qua. Ứng dụng sẽ tiếp tục sử dụng cấu hình tốt cuối cùng đã biết.
- Nếu
GetConfig()ném exception, proxy sẽ không thể lắng nghe các thay đổi trong tương lai vìIChangeTokenchỉ dùng một lần.
Sau khi cấu hình mới đã được xác thực và áp dụng, proxy sẽ đăng ký callback với IChangeToken mới. Lưu ý nếu có nhiều lần reload được signal liên tiếp, proxy có thể bỏ qua một số và tải cấu hình tiếp theo có sẵn ngay khi sẵn sàng. Mỗi IProxyConfig chứa trạng thái cấu hình đầy đủ nên không có gì bị mất.
Multiple Configuration Sources (Nhiều nguồn cấu hình)
Kể từ phiên bản 1.1, YARP hỗ trợ tải cấu hình proxy từ nhiều nguồn. Nhiều IProxyConfigProvider có thể được đăng ký như các dịch vụ singleton và tất cả sẽ được resolve và kết hợp. Các nguồn có thể là cùng loại hoặc khác loại như IConfiguration hoặc InMemory. Các route có thể tham chiếu đến các cluster từ các nguồn khác. Lưu ý rằng việc merge cấu hình một phần từ các nguồn khác nhau cho một route hoặc cluster nhất định không được hỗ trợ.
services.AddReverseProxy()
.LoadFromConfig(Configuration.GetSection("ReverseProxy1"))
.LoadFromConfig(Configuration.GetSection("ReverseProxy2"));hoặc
services.AddReverseProxy()
.LoadFromMemory(routes, clusters)
.LoadFromConfig(Configuration.GetSection("ReverseProxy"));Ví dụ
InMemoryConfigProvider cung cấp một ví dụ về IProxyConfigProvider có routes và clusters được tải thủ công vào nó.