Новинка Виртуальный VDS сервер в Финляндии от 390р
Выберите продукт

Apache: TimeOut, KeepAliveTimeout и RequestReadTimeout — понятные пресеты и ловушки

Таймауты в Apache отвечают за производительность, устойчивость и безопасность. В материале — практические настройки TimeOut, KeepAliveTimeout, RequestReadTimeout и ProxyTimeout, типичные ошибки, пресеты для сайтов, API и крупных загрузок, а также советы по диагностике 408/504 и зависаний.
Apache: TimeOut, KeepAliveTimeout и RequestReadTimeout — понятные пресеты и ловушки

В продакшене веб‑сервис держится на мелочах: от «пустяковых» таймаутов зависит, увидит ли пользователь контент или утонет в 408/504 и бесконечных ретраях. В Apache набор ключевых директив — TimeOut, KeepAliveTimeout, RequestReadTimeout (mod_reqtimeout) и ProxyTimeout — управляет жизненным циклом соединений с клиентом и бэкендом. Разберёмся, как они действительно работают, какие значения выбирать под разные сценарии и как избежать ловушек, которые выливаются в простои и утечки ресурсов.

Карта таймаутов Apache 2.4: кто за что отвечает

Чтобы успешно настраивать таймауты, важно понимать зону ответственности каждой директивы:

  • TimeOut — общий сетевой таймаут (по умолчанию 60 секунд): ожидание завершаемых операций ввода/вывода на клиентском соединении и прокси‑бэкенде, если не переопределено более узкими директивами.
  • KeepAlive и KeepAliveTimeout — политика постоянных соединений HTTP/1.x и ожидание следующего запроса в рамках уже установленного соединения.
  • RequestReadTimeout (модуль mod_reqtimeout) — гибкий контроль скорости/тайминга чтения заголовков и тела запроса; основная защита от Slowloris/slow POST.
  • ProxyTimeout и параметры ProxyPass ... timeout= / connectiontimeout= — таймауты при взаимодействии с upstream (mod_proxy_*), в том числе reverse proxy к приложению или другому веб‑серверу.

Правило большого пальца: TimeOut — «сетевой потолок по умолчанию», от которого вы сознательно «откусываете» поведение более конкретными настройками в нужных местах.

TimeOut: базовый предел ожидания IO

TimeOut — это не «таймаут всего подряд», но именно он определяет, как долго Apache готов ждать завершения блокирующих операций сети там, где нет отдельных переопределений. По умолчанию — 60 секунд. Слишком маленькое значение приведёт к обрывам медленных загрузок или нестабильных сетей, слишком большое — к удержанию воркеров, что под высоким трафиком проявится в утилизации CPU/памяти и очередях.

Где TimeOut влияет в первую очередь:

  • Чтение клиентского запроса (если не включён/не настроен RequestReadTimeout).
  • Ожидание отклика от бэкенда прокси (если не задан ProxyTimeout/ProxyPass timeout=).
  • Передача ответа клиенту, если клиентская сторона «тормозит».

Рекомендованные ориентиры для TimeOut

  • Публичные сайты/лендинги: 30–60 секунд (обычно 30–45 достаточно).
  • API с чёткими SLO: 15–30 секунд (чтобы не «поддерживать» слишком долгие бэкенд‑операции).
  • Тяжёлые загрузки файлов напрямую в Apache: 120–300 секунд, в паре с корректно настроенным RequestReadTimeout (по скорости).

Пример (глобальный минимум):

# /etc/apache2/apache2.conf или httpd.conf
TimeOut 30

Снижать TimeOut ниже 15 секунд без веских причин рискованно: накроете легитимных пользователей с медленным каналом и мобильных клиентов под нагрузкой сети.

KeepAlive и KeepAliveTimeout: экономим рукопожатия, но не держим сеть вхолостую

Постоянные соединения (HTTP/1.1) сокращают латентность за счёт переиспользования TCP и TLS, уменьшая handshake‑издержки. При этом «висящие» keep‑alive‑коннекты занимают дескрипторы и память. Баланс ищется значениями KeepAliveTimeout и лимитом MaxKeepAliveRequests.

  • KeepAlive On — почти всегда верное решение под статический/смешанный контент.
  • KeepAliveTimeout — сколько ждать следующий запрос по уже установленному соединению. По умолчанию 5 секунд (Apache 2.4).
  • MaxKeepAliveRequests — сколько запросов разрешено в одном соединении (по умолчанию 100).

Под MPM event цена «висящих» соединений ниже, чем в worker/prefork, но всё равно не нулевая. На загруженных сайтах обычно достаточно 2–5 секунд; для SPA/рестов — 5–10 секунд; для долгоживущих соединений типа SSE/комет лучше использовать специализированные настройки и отдельные бэкенды, а не пытаться «растянуть» KeepAliveTimeout.

# Глобально
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100

Важно: KeepAliveTimeout относится к ожиданию следующего запроса в HTTP/1.x. Для HTTP/2 (mod_http2) действуют иные лимиты на сессию/потоки, а не KeepAliveTimeout впрямую. Если используете HTTP/2, проверьте соответствующие параметры модуля для тонкой настройки сессий.

Схема, показывающая, где в Apache применяются TimeOut, KeepAliveTimeout, RequestReadTimeout и ProxyTimeout

RequestReadTimeout: точечная защита от Slowloris и «медленных тел»

mod_reqtimeout добавляет умную логику чтения запросов: таймауты на заголовки и тело учитывают скорость поступления данных. Он не столько «жёстко рубит» по времени, сколько «просит» клиента поддерживать минимальную скорость или завершить передачу в разумные сроки.

Синтаксис (упрощённо):

  • RequestReadTimeout header=initial-timeout[-max-timeout][,MinRate=bytes_per_sec]
  • RequestReadTimeout body=initial-timeout[-max-timeout][,MinRate=bytes_per_sec]
  • Опционально env= для включения/исключения правила по переменной окружения запроса.

Базовый безопасный профиль для сайтов и API

# Включаем модуль (Debian/Ubuntu)
a2enmod reqtimeout

# /etc/apache2/conf-available/reqtimeout.conf или в VirtualHost
RequestReadTimeout header=20-40,MinRate=500
RequestReadTimeout body=10,MinRate=1000

Этот профиль говорит: заголовки должны прийти за 20 секунд, но допускается продление до 40 при непрерывной передаче; тело — минимум 1 КБ/с после стартового окна. Значения подбирайте под реальный профиль клиентов (мобайл, развёрнутые по всему миру). Если используете CDN/прокси перед Apache — учтите их буферизацию: Apache видит уже непрерывный поток, и можно быть строже. Кстати, не забудьте про базовые заголовки защиты; подробности в гайде по HTTP Security Headers для Nginx/Apache.

Исключения для WebSocket и долгих аплоадов

WebSocket‑соединения не подходят под логику RequestReadTimeout; их лучше исключить по заголовку Upgrade:

# Исключаем WebSocket из правил (в VirtualHost / Directory)
SetEnvIfNoCase Upgrade websocket is_websocket=1
RequestReadTimeout header=20-40,MinRate=500 env=!is_websocket
RequestReadTimeout body=10,MinRate=1000 env=!is_websocket

Для страниц с большими загрузками (например, до 2 ГБ) разумно ставить минимальную скорость ниже и большее стартовое окно, но не превращать сервер в «бесконечный» буфер. Контролируйте лимиты на стороне приложения и используйте возобновляемые аплоады, если возможно.

ProxyTimeout и таймауты прокси: upstream не должен «висеть»

Если Apache работает как reverse proxy (mod_proxy_http, mod_proxy_fcgi, mod_proxy_uwsgi, mod_proxy_wstunnel и др.), отдельные таймауты на бэкенд критичны. По умолчанию, когда ProxyTimeout не задан, используется значение TimeOut. Это редко оптимально: для API часто нужен более короткий предел, чем для клиентских загрузок.

  • ProxyTimeout — общий таймаут для взаимодействия с бэкендом (чтение/запись), если не переопределено.
  • Параметры ProxyPass: connectiontimeout= (установление TCP к бэкенду), timeout= (ожидание ответа/IO), acquire= (ожидание свободного воркера/соединения), и др. Они перекрывают ProxyTimeout адресно.

Примеры: HTTP‑бэкенд, FCGI и WebSocket

# Глобальный дефолт на прокси короче, чем общий TimeOut
TimeOut 45
ProxyTimeout 20

# Reverse proxy к приложению HTTP
ProxyPass        /api http://127.0.0.1:8080/ retry=0 connectiontimeout=2 timeout=15 acquire=3000
ProxyPassReverse /api http://127.0.0.1:8080/

# FCGI к PHP-FPM (mod_proxy_fcgi)
ProxyPassMatch ^/(.*) fcgi://127.0.0.1:9000/var/www/public/$1 timeout=30

# WebSocket (тоннель без агрессивных таймаутов)
ProxyPass        /ws ws://127.0.0.1:3000/ timeout=0
ProxyPassReverse /ws ws://127.0.0.1:3000/

Пояснения:

  • retry=0 — не пытаться использовать «плохой» бэкенд повторно, если он помечен как down.
  • timeout=0 в mod_proxy_wstunnel позволяет долгоживущим WebSocket‑соединениям жить без искусственного обрыва.
  • Для FCGI лучше задавать явный timeout=, чтобы зависшие скрипты не удерживали воркеры бесконечно.
FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды Финляндия

Зоны видимости директив: где что можно задавать

  • TimeOut, KeepAliveTimeout — только в серверном/глобальном контексте, не в .htaccess.
  • RequestReadTimeout — серверный/виртуальный хост/контекст каталога. Можно в .htaccess, но лучше централизованно.
  • ProxyTimeout — глобально или в виртуальном хосте; параметры ProxyPass — на конкретные локации/маршруты.

Практические пресеты

1) Публичный сайт с кэшем и смешанным контентом

# Глобально
TimeOut 30
KeepAlive On
KeepAliveTimeout 5
MaxKeepAliveRequests 100

# Защита от медленных клиентов
RequestReadTimeout header=20-40,MinRate=500
RequestReadTimeout body=10,MinRate=1000

# Если есть reverse proxy к приложению (например, для /api)
ProxyTimeout 15
ProxyPass /api http://127.0.0.1:8080/ connectiontimeout=2 timeout=12 retry=0
ProxyPassReverse /api http://127.0.0.1:8080/

2) API с жёстким SLO (p95 < 1–2 c, p99 < 10 c)

TimeOut 20
KeepAlive On
KeepAliveTimeout 3
MaxKeepAliveRequests 100

RequestReadTimeout header=10-20,MinRate=1000
RequestReadTimeout body=10,MinRate=2000

ProxyTimeout 10
ProxyPass /v1 http://127.0.0.1:9000/ connectiontimeout=1 timeout=8 acquire=2000 retry=0
ProxyPassReverse /v1 http://127.0.0.1:9000/

Смысл — не давать «висящим» бэкендам съедать пул соединений; ошибки лучше быстро и предсказуемо возвращать клиентам с ретраями по экспоненте.

3) Большие загрузки (несколько гигабайт) напрямую в Apache

TimeOut 180
KeepAlive On
KeepAliveTimeout 10
MaxKeepAliveRequests 200

# Позволяем медленной, но поступательной передаче тела
RequestReadTimeout header=20-60,MinRate=500
RequestReadTimeout body=20,MinRate=500

# Если проксируем загрузки в приложение — учитывайте его лимиты
ProxyTimeout 120
ProxyPass /upload http://127.0.0.1:8081/ connectiontimeout=2 timeout=120 retry=0
ProxyPassReverse /upload http://127.0.0.1:8081/

Не забудьте согласовать лимиты в приложении и в веб‑сервере: размеры тела, буферы, лимиты времени выполнения и число воркеров. Иначе «узкое место» проявится не там, где ожидаете. Для полного стека кеширования и валидаторов подсмотрите приёмы в гайде по Cache-Control и ETag.

Диагностика: как понять, кто виноват — клиент, Apache или бэкенд

Подход «сверху вниз»: метрики, логи, затем точечные проверки.

  • Включите mod_status и наблюдайте состояние воркеров: «Reading Request», «Sending Reply», «Keepalive», «DNS Lookup» — это поможет локализовать фазу зависаний.
  • Добавьте время обработки в формат доступа: %D (микросекунды) и %T (секунды). Если проксируете — логируйте upstream‑тайминги через mod_proxy и маркеры результата.
# Пример расширенного лога
LogFormat "%h %l %u %t \"%r\" %>s %b %D microsec %T sec \"%{Referer}i\" \"%{User-Agent}i\"" combined_time
CustomLog logs/access_time.log combined_time
  • Проверяйте ретраи клиента: curl -v покажет, где происходит обрыв (на чтении заголовков, теле или при ожидании ответа).
  • Смотрите на распределение времени: если %D велик, но бэкенд по своим метрикам быстр — вероятно, клиент «не принимает» ответ, и TimeOut слишком велик для отправки.
  • При 408/504 сравните текущие значения TimeOut, ProxyTimeout, RequestReadTimeout с фактическими длительностями запросов.

Снимок панели mod_status и пример логов с таймингами для диагностики зависаний

Частые ошибки и анти‑паттерны

  • Ставят огромный KeepAliveTimeout «на всякий случай». Итог — тысячи висящих соединений, рост дескрипторов и памяти, падение пропускной способности под пиками.
  • Отключают RequestReadTimeout на публичном фронте. Получают уязвимость к Slowloris/slow POST под малым трафиком ботов.
  • Забывают ProxyTimeout и удивляются 60‑секундным «плато» задержек: по умолчанию используется TimeOut, что для API почти всегда слишком много.
  • Слишком низкие таймауты в регионах с высоким RTT и перегрузкой радиосети: бьют легальных мобильных пользователей. Всегда проверяйте метрики RTT/трэйс и профили клиентов.
  • Смешивание длинных и коротких запросов под один пул без разделения. Решение: разнести локации/виртуальные хосты и дать разным маршрутам собственные таймауты и пулы воркеров. На нагруженных проектах удобно вынести тяжёлые маршруты на отдельный VDS.

Ресурсная модель и оценка влияния

Под MPM event постоянные соединения обрабатываются эффективнее, но всё равно занимают память на контекст соединения и сокет. Прикидывайте верхнюю границу: одновременные соединения × средний объём на соединение плюс буферы ответа. Слишком большие KeepAliveTimeout и TimeOut увеличивают хвост распределений по времени жизни соединений, что при всплесках легко приводит к исчерпанию дескрипторов и росту задержек GC в приложениях за прокси.

Практика: держите короткие дефолты и адресно увеличивайте таймауты только там, где обязательно (загрузки, WebSocket, отчёты), изолируя такие маршруты в конфигурации. Если вы обдумываете архитектурные компромиссы и выбор фронта, загляните в сравнение Nginx vs Apache.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Чек‑лист внедрения

  1. Определите профили трафика: статический сайт, API, загрузки, WebSocket.
  2. Поставьте разумные глобальные дефолты: TimeOut 20–45, KeepAliveTimeout 3–7, MaxKeepAliveRequests 100–200.
  3. Включите и настройте RequestReadTimeout; исключите WebSocket через env.
  4. Для прокси: задайте ProxyTimeout и адресные параметры ProxyPass ... connectiontimeout= timeout=.
  5. Разнесите длинные/короткие запросы по разным локациям/виртуальным хостам с разными таймаутами.
  6. Добавьте метрики/логи времени обработки (%D, %T) и наблюдайте p95/p99 до и после изменений.
  7. Проведите нагрузочные прогоны с эмуляцией медленных клиентов и высоких RTT.
  8. Документируйте принятые значения и бизнес‑требования (макс. время ответа, допустимая скорость загрузки).

FAQ: тонкости и пограничные случаи

  • Влияет ли TimeOut на TLS‑рукопожатие? TLS имеет собственные таймауты в mod_ssl (например, SSLHandshakeTimeout). Но для простоты держите общий TimeOut не экстремально низким и проверяйте настройки mod_ssl, если видите обрывы на handshake под высокой нагрузкой. Если у вас нет корректного TLS — начните с надёжных SSL-сертификаты.
  • Что ставить для долгих SSE/стриминга? Стриминг лучше изолировать на отдельный маршрут/виртуальный хост с осознанными таймаутами или специализированной инфраструктурой. Не пытайтесь «на всех» поднимать KeepAliveTimeout.
  • Почему клиенты получают 408? Чаще всего RequestReadTimeout для заголовков/тела срабатывает раньше, чем клиент успевает прислать данные. Проверьте минимальную скорость и стартовые окна, а также прокси/CDN‑буферы перед Apache.
  • Почему 504 в прокси? Бэкенд не успевает в отведённый ProxyTimeout или ProxyPass timeout=. Смотрите, что медленнее — бэкенд или сеть, и корректируйте либо таймауты, либо производительность.

Итог: таймауты в Apache — это не «магические числа», а интерфейс управления ожиданиями: ваших пользователей, сети и бэкендов. Поставьте короткие дефолты, осознанно выделяйте исключения и измеряйте результат.

Поделиться статьей

Вам будет интересно

Как безопасно выполнить bootstrap MariaDB Galera после полного останова

Как безопасно выполнить bootstrap MariaDB Galera после полного останова

После одновременной остановки всех узлов Galera обычного запуска MariaDB недостаточно. Сначала найдите сервер с последней транзакц ...
CoreDNS в Kubernetes: исправляем CrashLoopBackOff, SERVFAIL и DNS-петлю

CoreDNS в Kubernetes: исправляем CrashLoopBackOff, SERVFAIL и DNS-петлю

Разберём, почему CoreDNS перезапускается или отвечает SERVFAIL, как обнаружить замкнутую пересылку DNS-запросов, проверить доступн ...
Apache Kafka KRaft на VDS: отдельные controller и broker

Apache Kafka KRaft на VDS: отдельные controller и broker

Соберём новый Kafka-кластер без ZooKeeper на шести Linux VDS: три узла controller образуют отказоустойчивый metadata quorum, а три ...