Случайная задержка в 1 секунду для службы http, развернутой роем, при достижении через прокси - PullRequest
0 голосов
/ 09 июля 2019

Краткое резюме

Я использую HTTP-сервер в качестве службы на Docker Swarm. Я тестирую время запроса, когда curl запускает его в цикле. Если я использую какой-либо прокси, направляющий трафик на сервис, я получаю случайные задержки в 1 секунду. Если я использую порт, опубликованный на рое HTTP-сервером - все в порядке. Если я запускаю тот же сервис без роя (с docker run) и использую тот же прокси-сервер - время тоже в порядке.

Вы получили такой эффект? У кого-нибудь есть советы как от него избавиться?

Подробное описание и сценарии

Это простой docker-compose файл службы HTTP, который я использую:

version: '3.5'

services: 
app:
    image: nginx:latest
    networks:
      - proxy
    ports:
      - 48091:80
    deploy:
      placement:
        constraints:
          - node.hostname == some-node-name
      labels:
        - "traefik.docker.network=proxy"
        - "traefik.port=80"
        - "traefik.frontend.rule=Host:some.test.url.com"

networks:
  proxy:
    external: true

По умолчанию Nginx используется в качестве основного прокси-сервера вне роя, направляя запросы тестового домена к прокси-серверу Traefik, работающему в качестве сервиса внутри роя, и перенаправляет запросы в тестовый HTTP-сервис. Разумеется, опубликованный порт 48091 в этом сценарии не используется.

Я тестирую время запросов с помощью curl из локальной сети, используя простой скрипт:

#!/bin/

for i in {1..1000}; do
    curl -g -so /dev/null -w '%{time_total}\n' http://some.test.url.com
done

Обычное общее время запроса, записанное curl, составляет около 0,006 мс, но время от времени оно прибавляет 1 секунду. Иногда все 1000 запросов выполняются без этой задержки, но при следующем запуске «длинные» времена составляют 2% или 6%. Иногда задержки бывают единичными, но обычно служба блокируется на некоторое время, и я получаю много длинных запросов подряд.

Моей первой мыслью было, что это вызвано Traefik, поэтому я опубликовал порт 48091 на рое и направил запросы от основного Nginx прямо на него, полностью минуя Traefik. Результат был точно таким же - много длинных запросов.

Следующий тест был запущен непосредственно на Traefik - без первого Nginx. Без изменений - все еще сломано.

Но

Служба тестирования без какого-либо прокси-сервера - кажется, что просто направление запросов curl на порт 48091 на узле роя работает нормально. Я запустил несколько сотен тысяч запросов, и ни один из них не был заблокирован.

Кроме того, если я запустил службу HTTP без роя - используя docker run -p 48091:80 nginx:latest на той же машине, что использовалась ранее, и протестировал с передним Nginx - все тоже в порядке.

Подводя итог

Проблема возникает, если я запускаю службу в рое и использую любой прокси перед ним. Если он работает без роя, или я использую непосредственно опубликованный порт - все работает хорошо.

Буду признателен за любую помощь в этом вопросе, поскольку мы планируем запустить большой сайт, и это похоже на шоу-стопор. Переключиться на Kubernetes перед запуском сейчас нереально: (

Редактировать

Я настроил скрипт тестирования, чтобы получить точную информацию о таймингах из curl:

#!/bin/bash

URL="http://some.test.url.com"

OUT="%{time_total} | lookup: %{time_namelookup} | connect: %{time_connect} | appconnect: %{time_appconnect} | pretransfer: %{time_pretransfer} | redirect: %{time_redirect} | starttransfer: %{time_starttransfer}\n"

for i in {1..10000}; do
    curl -g -so /dev/null -w  "$OUT" $URL
done

Теперь результат тестового запуска с Nginx-> Swarm (только длинные запросы) выглядит так:

1.027 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.027
1.028 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.027
1.047 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.047
1.046 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.046
1.049 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.049
1.010 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.009
1.009 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.009
1.009 | lookup: 0.004 | connect: 0.005 | appconnect: 0.000 | pretransfer: 0.005 | redirect: 0.000 | starttransfer: 1.008

Так что задержка всегда на «starttransfer». Если я правильно понимаю это: https://blog.cloudflare.com/a-question-of-timing/ это означает, что существует некоторая проблема с передачей GET-запроса между Nginx и сервисом в Swarm.

...