Тайм-аут шлюза с облачным шлюзом Spring и Nginx в качестве обратного прокси - PullRequest
10 голосов
/ 01 апреля 2019

Я создал API-шлюз для своего приложения, и он будет выступать в качестве фронт-контроллера для других микросервисов. В моей производственной настройке я использую Nginx в качестве обратного прокси для моего шлюза

Шлюз API работает на порту 8080

Конфигурация Nginx как показано ниже

шлюз-api.conf:

server {
    listen 80;
    server_name api.example.com;
    location / {
        proxy_set_header        X-Real-IP       $remote_addr;
        proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://localhost:30010/;
        keepalive_timeout 500s;
    }
    keepalive_timeout 500s;
    access_log /var/log/nginx/api.log;  
    error_log /var/log/nginx/api_error.log;
}

установка времени ожидания в nginx.conf

proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;

Файл Gradle шлюза Spring Cloud:

compile('org.springframework.cloud:spring-cloud-starter-gateway')
 compile('org.springframework.cloud:spring-cloud-starter-openfeign')
 compile("org.springframework.boot:spring-boot-starter-actuator")
 compile('org.springframework.boot:spring-boot-starter-security')

springBootVersion=2.0.3.RELEASE
springDMPVersion=1.0.4.RELEASE
springPlatformBomVersion=Cairo-SR2
springCloudVersion=Finchley.RELEASE

Приложение шлюза:

@SpringBootApplication
@ComponentScan(basePackages = {"com.example"})
@EntityScan(basePackages = {"com.example"})
@EnableFeignClients(basePackages = "com.example")
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

Постановка задачи:

В одном из моих микросервисов один API REST занял более 3 минут. Если я вызываю этот API через nginx (api.example.com), он выходит из строя ровно через 1 мин и дает статус HTTP 504

локон:

curl --request GET \
  --url http://api.example.com/hellomicroservice/api/take/moretime

ошибка:

504 Timeout while reading the response from Server

Нет журналов ошибок в nginx и API-шлюзе

Журнал доступа из nginx:

203.129.213.102 - - [01/Apr/2019:08:14:33 +0000] "GET hellomicroservice/api/take/moretime HTTP/1.1" 499 0 "-" "PostmanRuntime/7.3.0"

Но когда я вызываю тот же API напрямую к шлюзу (через порт 8080 шлюза), процесс запроса успешно

curl с портом шлюза:

curl --request GET \
  --url http://api.example.com:8080/hellomicroservice/api/take/moretime

Edit: Если я применяю настройки тайм-аута Nginx менее чем за 60 секунд (например, 30 секунд), запрос истекает по истечении указанного интервала времени. Но если я установлю тайм-аут Nginx более 60 секунд, то есть 300 секунд, запрос истечет через 60 секунд.

Ответы [ 3 ]

0 голосов
/ 09 апреля 2019

Keepalive может все еще не быть включен для восходящего потока из-за вашей конфигурации, пропускающей ключ proxy_http_version.

Цитата из: https://www.nginx.com/blog/tuning-nginx/#proxy_http_version

Чтобы включить keepalive-соединения с вышестоящими серверами, вы также должны включить в конфигурацию следующие директивы:

proxy_http_version 1.1;
proxy_set_header Connection "";

Я бы также сохранил keepalive_timeout в конфигурации, как предложил Крис.

0 голосов
/ 10 апреля 2019

Попробуйте поместить свои настройки времени ожидания в /etc/nginx/conf.d/timeout.conf (если его там нет, создайте его).Установите ниже настройки,

proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
0 голосов
/ 08 апреля 2019

Кажется, что тайм-ауты запроса не проблема для вас.Это время ожидания соединения.Я думаю, что нам нужно посмотреть на заголовок

Соединение

AFAIK, заголовок Connection определяет, соединение должно быть постоянным или кто имеет полномочия на обслуживание/закрой его.Если соединение было keep-alive, то соединение будет постоянным.Для соединений keep-alive клиент иногда отправляет пинг TCP, чтобы убедиться, что сервер все еще активен и удерживает соединение.Согласно curl это время по умолчанию каждые 60 секунд.

Теперь необходимо настроить nginx для приема соединений и поддержания их на некоторое время, используя директиву keepalive_timeout.Если его там нет, nginx не будет поддерживать соединения .

Это должно быть причиной, по которой nginx говорит 499 в журналах. HTTP499 - ошибка cutom в nginx, которая говорит, что клиент закрыл соединение.В вашем случае curl закрыл его.Почему curl закрыл это?потому что nginx не ответил на эхо-запрос TCP в течение 60 секунд, поскольку функция keep-alive не включена.

Добавление значения keepalive_timeout в ~ 500 или более высокое значение, чем время ожидания приложения, должнорешить вашу проблему.

Теперь, почему он работал с tomcat напрямую?Я думаю, что весна позволяет живому таймауту быть бесконечным или очень высоким значением.Обычно в коте также его 60 секунд.

Надеюсь, это решит вашу проблему.

...