nginx, fastcgi и открытые сокеты

Я экспериментирую с fastcgi на nginx, но столкнулся с некоторыми проблемами. Nginx не использует повторно соединения, он дает 0 в флагах BeginRequest , поэтому приложение должно закрыть соединение после завершения запроса.

У меня есть следующий код для закрытия:

socket.shutdown(SocketShutdown.BOTH);
socket.close();

Проблема в том, что соединения на самом деле не закрыты .. Они остаются в TIME_WAIT, и nginx (или что-то в этом роде) не может открывать новые соединения. {{1} } Я предполагаю, что при закрытии сокетов я что-то делаю не так, но я не знаю, что ... Кстати, как я могу заставить nginx поддерживать соединения открытыми?

Это использует nginx 1.0.6 и D 2.055

РЕДАКТИРОВАТЬ: Я не подошел ближе, но я также проверил опцию задержки, и она выключена:

linger l;
socket.getOption(SocketOptionLevel.SOCKET, SocketOption.LINGER, l);
assert(l.on == 0); // off

getOption возвращает 4, хотя .. Понятия не имею, что это значит. Возвращаемое значение недокументировано.

РЕДАКТИРОВАТЬ: Я также пробовал использовать TCP_NODELAY в последнем отправленном сообщении, но это тоже не имело никакого эффекта:

socket.setOption(SocketOptionLevel.SOCKET, SocketOption.TCP_NODELAY, 1);

РЕДАКТИРОВАТЬ: Поддерживаются nginx 1.1.4. соединения. Это работает не так, как ожидалось. Правильно сообщает, что сервер отвечает за управление временем жизни соединения, но он по-прежнему создает новый сокет для каждого запроса.

28
задан simendsjo 1 October 2011 в 14:21
поделиться

1 ответ

Keepalive прокси NGINX

Относительно keepalive nginx (v1.1) для fastcgi. Правильный способ его настройки заключается в следующем:

upstream fcgi_backend {
  server localhost:9000;
  keepalive 32;
}

server {
  ...
  location ~ \.php$ {
    fastcgi_keep_conn on;
    fastcgi_pass fcgi_backend;
    ...
  }
}

TIME_WAIT

Состояние соединения TCP TIME_WAIT не имеет ничего общего с задержками, tcp_no_delays, тайм-аутами и т. Д. Он полностью управляется ядром ОС и может зависеть только от общесистемных параметров конфигурации. Как правило, это неизбежно. Так работает протокол TCP. Читайте об этом здесь и здесь .

Наиболее радикальный способ избежать TIME_WAIT - сбросить (отправить RST пакет) TCP-соединение при закрытии, установив linger = ON и linger_timeout = 0. Но делать это не рекомендуется для нормальной работы, так как вы можете потерять неотправленные данные. Сбрасывать сокет только в случае ошибки (таймауты и т. Д.).

Я бы попробовал следующее. После того, как вы отправите все свои данные, вызовите socket.shutdown (WRITE) (это отправит пакет FIN другой стороне) и пока не закроете сокет. Затем продолжайте чтение из сокета, пока не получите индикацию о том, что соединение закрыто другим концом (в C, который обычно обозначается как read 0) (). После получения этого указания закройте розетку. Подробнее об этом здесь .

TCP_NODELAY & amp; TCP_CORK

Если вы разрабатываете какой-либо тип сетевого сервера, вы должны изучить эти параметры, так как они влияют на производительность. Без их использования вы можете столкнуться с задержкой ~ 20 мс ( задержка Нэгла ) для каждого пересылаемого пакета. Хотя эти задержки выглядят небольшими, они могут отрицательно повлиять на статистику запросов в секунду. Хорошее чтение об этом здесь .

Другая хорошая ссылка для чтения о сокетах здесь .

О FastCGI

Я согласен с другими комментаторами, что использование протокола FastCGI для вашей серверной части может быть не очень хорошей идеей. Если вы заботитесь о производительности, вам следует реализовать свой собственный модуль nginx (или, если это кажется слишком сложным, модуль для какого-либо другого сервера, такого как NXWEB ). В противном случае используйте HTTP. Его проще реализовать и он гораздо более универсален, чем FastCGI. И я бы не сказал, что HTTP намного медленнее, чем FastCGI.

3
ответ дан 28 November 2019 в 03:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: