gRPC в теме о XHTTP
Я понимаю, что тема о XHTTP, но увидел, что целых два человека используют «конские» таймауты, которые могут привести к проблемам. Поэтому решил предупредить, что это чревато.
К тому же XHTTP всё-таки использует внутри себя gRPC, так что подобный конфиг вполне может использоваться и для XHTTP.
Таймауты
Вы правильно считаете, что лучше не делать их слишком маленькими, но, скорее всего, немного путаете их предназначение.
Это не счётчики, которые определяют время жизни активного соединения. Таймауты отсчитывают время после прекращения передачи данных, «отрезая» зависшие или медленные соединения. Они не действуют на соединения, данные в которых активно передаются.
При нормальной работе прокси-сервера таймаутов в 60 секунд должно вполне хватать, к тому же это значение для большинства таймаутов в Nginx по умолчанию. Если данные не передаются более 60 секунд, скорее всего, с соеднинением что-то случилось, поэтому лучше его закрыть.
Если конкретнее, в контексте создания прокси-серверов вместе с Xray-core в конфигурации Nginx обычно используются следующие таймауты [1, 2]:
1. keepalive_timeout
keepalive_timeout
определяет, сколько времени соединение будет поддерживаться открытым после обработки последнего запроса. Значение в 60s будет держать соединение открытым до тех пор, пока с момента обработки последнего запроса не пройдёт 60 секунд. Тогда Nginx закроет это соединение.
Например, в YouTube скачивание фрагментов видео происходит примерно каждые 2 секунды, то есть 60 секунд ожидания должно хватить.
Конечно, если поставить видео на паузу и подождать 60 секунд, соединение закроется. Но за это время успеет накопиться большой буфер (в 20 секунд, например), и продолжив воспроизведение, вряд ли вы заметите, что установление нового соединения задержало загрузку буфера на несколько миллисекунд.
Вы же, скорее всего, имели в виду keepalive_time
— это, действительно, абсолютное ограничение времени жизни соединения, — несмотря на то, передаёт оно данные или зависло. Но это не таймаут.
2. client_header_timeout
client_header_timeout
определяет, как долго Nginx будет ждать полной передачи заголовков HTTP-запроса от клиента.
Заголовки — это просто метаданные запроса, не сама полезная нагрузка. Они не должны весить много, поэтому передаваться обычно должны меньше секунды. 60 секунд точно хватит, чтобы их передать. В ином случае соединение, скорее всего, зависло, либо слишком медленное, поэтому лучше его закрыть.
3. client_body_timeout
client_body_timeout
определяет, как долго Nginx будет ждать после операции чтения тела запроса, если тело так и не было отправлено до конца. Похоже на keepalive_timeout
, но разница в том, что это ожидание не после каждого запроса, а после каждой операции чтения тела запроса.
То есть, если клиент начал отправлять запрос, но вдруг остановился, так и не отправив его до конца, Nginx подождёт 60 секунд, прежде чем закрыть соединение. Это снова нужно для того, чтобы закрывать зависшие соединения.
Например, если вы что-то скачиваете, то это может быть только один файл. Может быть, в таком случае скачивание будет считаться за единый запрос. В таком случае соединение закроется только в том случае, если передача данных прекратилась на 60 секунд.
Ладно: возможно, в этом случае можно и побольше сделать таймаут, например в 2-3 минуты, чтобы уменьшить вероятность того, что скачивание большого файла начнётся заново (если это вообще так работает. То есть если переустановление соединения точно приведёт к полной потере прогресса загрузки. Но я сомневаюсь, что это действительно так работает).
4. grpc_read_timeout
grpc_read_timeout
определяет, как долго Nginx будет ждать ответа от Xray-core, чтобы вернуть клиенту то, что он запросил. Если Xray-core в течение 60 секунд так и не ответит, Nginx закроет соединение.
Что в итоге?
Честно говоря, я не очень понимаю, как gRPC используется в XHTTP, но в описании XHTTP написано, что для того, чтобы XHTTP проходил через Cloudflare, в настройках Cloudflare нужно включить поддержку gRPC. Таким образом, gRPC явно как-то задействуется в XHTTP.
Таймауты же нужны, чтобы закрывать зависшие соединения. Они не трогают активные соединения. И 60 секунд — обычно достаточный запас ожидания, чтобы соединение «ожило». Если за это время оно не «оживёт», лучше его закрыть, чтобы оно не занимало память. В крайнем случае можно сделать таймауты в 2-3 минуты, но зачем держать мёртвое соединение 52 недели?