Провайдеры конфигурации
Загружайте маршруты и кластеры программно вместо файла, реализовав IProxyConfigProvider самостоятельно — это полезно для базы данных, удалённого API или любого другого источника.
Интерфейс провайдера
Файлы конфигурации покрывают распространённый случай загрузки из IConfiguration. Чтобы загружать данные из любого другого источника, реализуйте IProxyConfigProvider и IProxyConfig самостоятельно.
У IProxyConfigProvider есть единственный метод GetConfig(), возвращающий IProxyConfig — снимок текущих маршрутов и кластеров, а также IChangeToken, который провайдер сигнализирует всякий раз, когда этот снимок устаревает, что заставляет прокси-сервер снова вызвать GetConfig().
Прямая загрузка маршрутов и кластеров
Для простейшего случая — когда маршруты и кластеры полностью известны в коде — InMemoryConfigProvider представляет собой готовую реализацию IProxyConfigProvider:
C#services.AddReverseProxy().LoadFromMemory(routes, clusters);Чтобы впоследствии изменить эту конфигурацию, получите InMemoryConfigProvider из контейнера служб и вызовите Update:
C#httpContext.RequestServices.GetRequiredService<InMemoryConfigProvider>()
.Update(routes, clusters);Жизненный цикл провайдера
Запуск
IProxyConfigProvider регистрируется как singleton. При запуске прокси-сервер получает его и один раз вызывает GetConfig(); провайдер может:
- выбросить исключение, если он не может предоставить корректную конфигурацию — это предотвращает запуск приложения;
- синхронно заблокироваться до загрузки конфигурации, что откладывает запуск до появления корректных данных о маршрутах; либо
- немедленно вернуть пустой
IProxyConfigи загружать данные в фоновом режиме, сигнализируя через свойIChangeToken, когда реальные данные будут готовы.
Любая возвращённая конфигурация проверяется, и некорректный результат приводит к исключению, которое предотвращает запуск — вместо этого провайдер может выполнить предварительную проверку с помощью IConfigValidator и самостоятельно исключить некорректные записи.
Объекты маршрутов и кластеров, переданные прокси-серверу, следует считать доступными только для чтения после того, как они возвращены из GetConfig().
Перезагрузка
Если IChangeToken поддерживает активные обратные вызовы при изменении, прокси-сервер регистрирует такой обратный вызов после первоначальной загрузки; в противном случае HasChanged опрашивается каждые 5 минут. Чтобы опубликовать новую конфигурацию, провайдеру следует загрузить её в фоновом режиме — создавая новые экземпляры маршрутов и кластеров, поскольку они неизменяемы (хотя неизменившиеся можно переиспользовать), — при желании проверить её и только после этого сигнализировать через предыдущий IChangeToken. В ответ прокси-сервер снова вызывает GetConfig() и сравнивает результат с текущей конфигурацией, обновляя только то, что изменилось; замена происходит атомарно и затрагивает только новые запросы, а не те, что уже находятся в обработке.
IChangeToken можно использовать только один раз. Если GetConfig() выбрасывает исключение во время перезагрузки, прокси-сервер теряет возможность отслеживать дальнейшие изменения от этого провайдера. Любые другие ошибки перезагрузки вместо этого регистрируются в журнале и подавляются, а прокси-сервер продолжает использовать последнюю известную рабочую конфигурацию.
Если несколько перезагрузок сигнализируются в быстрой последовательности, прокси-сервер может пропустить часть из них и загрузить то, что доступно к моменту, когда он «догоняет» изменения — каждый IProxyConfig представляет собой полный снимок, а не разницу, поэтому пропуск промежуточного снимка ничего не теряет.
Несколько провайдеров
Можно зарегистрировать в качестве singleton более одного IProxyConfigProvider; все они разрешаются, а их конфигурации объединяются — точно так же, как это происходит с несколькими разделами файла конфигурации. Маршрут от одного провайдера может ссылаться на кластер от другого, но отдельный маршрут или кластер нельзя собрать из частичных данных, распределённых между двумя провайдерами.