У меня есть служба GRPC, связанная с localhohst
, и прокси nginx в качестве терминатора ssl на том же хосте (назовем его localhost-proxy
).Кроме того, у меня есть еще один прокси-сервер nginx grpc, который я хочу использовать как балансировщик + отработка отказа, этот прокси перенаправляет на localhost-proxy
.Проблема в конфигурации отработки отказа пограничного прокси - я не работаю, когда служба переключена, но локальный прокси работает.Когда служба выключена - localhost-proxy возвращает http статус 204
с заголовком grpc-status=14
.Сначала моя конфигурация была:
#localhost-proxy
upstream direct {
server localhost:50032;
keepalive 10;
keepalive_timeout 60s;
}
server {
listen 50042 ssl http2;
ssl_certificate /etc/service/certs/internal_api_server/server.crt;
ssl_certificate_key /etc/service/certs/internal_api_server/server.key;
ssl_client_certificate /etc/service/certs/internal_api_server/clientCA.crt;
ssl_verify_client on;
access_log /var/log/nginx/direct.json grpc_json;
location / {
grpc_set_header X-Real-IP $client_ip;
grpc_pass grpc://direct;
}
include /etc/nginx/errors.grpc.conf;
default_type application/grpc;
}
edge-proxy:
upstream edge {
server localhost-proxy1:50042;
server localhost-proxy2:50042 backup;
keepalive_timeout 60s;
}
server {
listen 50052 ssl http2;
ssl_certificate /etc/service/certs/internal_api_server/server.crt;
ssl_certificate_key /etc/service/certs/internal_api_server/server.key;
ssl_client_certificate /etc/service/certs/internal_api_server/clientCA.crt;
ssl_verify_client on;
access_log /var/log/nginx/edge.json grpc_json;
grpc_ssl_certificate /etc/service/certs/internal_api_client/client.crt;
grpc_ssl_certificate_key /etc/service/certs/internal_api_client/client.key;
grpc_ssl_trusted_certificate /etc/service/certs/internal_api_client/serverCA.crt;
grpc_ssl_verify on;
grpc_ssl_name api.server;
grpc_set_header X-Real-IP $client_ip;
grpc_connect_timeout 5s;
location / {
grpc_connect_timeout 5s;
grpc_pass grpcs://edge;
}
Но при такой конфигурации аварийное переключение работает, только если localhost-proxy выключен.Когда он работает - пограничный прокси просто возвращает ответ от localhost-proxy.Это не то, что я хочу.После того, как я добавил это в конфигурацию localhost-proxy:
...
grpc_pass grpc://direct;
#from here
error_page 502 = /error502grpc;
}
location = /error502grpc {
internal;
default_type application/grpc;
add_header grpc-status 14;
add_header grpc-message "unavailable";
return 502;
}
Он начинает возвращать 502 для edge-proxy, когда служба недоступна.
После этого я попробовал это с помощью edge-прокси:
- Добавить
grpc_next_upstream error timeout http_502 non_idempotent invalid_header;
- без эффекта - Добавить
...
grpc_intercept_errors on;
error_page 502 = @failover;
}
location @failover {
grpc_pass grpcs://edge_failover;
}
upstream edge_failover {
server localhost-proxy2:50052;
keepalive 10;
keepalive_timeout 60s;
}
По-прежнему без эффекта - возвращается тот же 502
ответ.
Я хочу аварийное переключение на пограничном прокси, и оно должно меняться в восходящем направлении, когда служба не работает (независимо от локального прокси-сервера).Но сейчас я не знаю, как это сделать.
ОБНОВЛЕНИЕ
После некоторого исследования в журналах отработки отказа я обнаружил, что с последним вариантом (2) запрос действительно идетв отказоустойчивый бэкэнд, но - nginx пересылает только заголовки grpc, тело запроса (пакет GRPC DATA) не отправляется.Таким образом, аварийное переключение ожидает полного запроса, а затем пограничный прокси-сервер сбрасывает соединение по таймауту.