Приветствую всех.<br>Тут случилась проблема c&nbsp; nginx &amp; nginx_http_push_module (<a href="http://ru.wikipedia.org/wiki/Comet_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29">http://ru.wikipedia.org/wiki/Comet_%28%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5%29</a>)<br>
Мы используем comet a.k.a Reverse AJAX.<br>Канал у клиентов ADSL. Очень часто рвется соединение по comet-у.<br>Когда из JavaScript вызывается abort для XMLHttpRequest, то соединения не накапливаются.<br>Но когда рвется сеть на физическом уровне, то коннект остается на сервере и висит бесконечно.<br>
Команда netstat четко показывает зависшие ESTABLISHED&nbsp; соединения.<br><br><b>Вопрос:</b> как настроить nginx или sysctl.conf или netfilter,&nbsp; чтобы он гарантированно рвал зависшие соединения?<br><b>Задача,</b> поддержать на сервере ~ 80000 одновременных соединений без утечек памяти по соединениям.<br>
------------------<br>Окружение:<br><b>uname -a :</b> Linux server1 2.6.18-194.el5PAE #1 SMP Fri Apr 2 15:37:44 EDT 2010 i686 i686 i386 GNU/Linux<br><b>OS:</b> CentOs 5.0<br><b>nginx -V:</b><br>nginx version: nginx/0.8.53<br>
built by gcc 4.1.2 20080704 (Red Hat 4.1.2-48)<br>TLS SNI support disabled<br>configure arguments: --user=nginx --group=nginx --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --pid-path=/var/run/nginx.pid --lock-path=/var/lock/subsys/nginx --with-http_secure_link_module --with-http_random_index_module --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_stub_status_module --with-http_perl_module --with-mail --with-mail_ssl_module --with-cc-opt=&#39;-O2 -g -m32 -march=i386 -mtune=generic -fasynchronous-unwind-tables&#39; --with-ipv6 --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/nginx-upstream-fair --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/nginx-upload-progress-module --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/mod_zip-1.1.6 --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/nginx_upload_module-2.2.0 --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/nginx_mod_h264_streaming-2.2.7 --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/nginx_http_push_module-0.692 --add-module=/usr/src/redhat/BUILD/nginx-0.8.53/nginx_upstream_hash-0.3.1<br>
<br><br>------<br>Вот часть конфига nginx.conf:<br><br>#######################################################################<br># GLOBAL PARAMETERS<br>#######################################################################<br>
user&nbsp; root;<br>worker_processes&nbsp; 8;<br>timer_resolution 100ms;<br>worker_rlimit_nofile 1000000;<br>worker_priority -5;<br><br>error_log&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /var/log/nginx/error.log&nbsp; crit;<br>pid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /var/run/nginx.pid;<br><br>
events {<br>&nbsp;&nbsp;&nbsp; worker_connections&nbsp; 100000;<br>&nbsp;&nbsp;&nbsp; use epoll;<br>}<br><br>#######################################################################<br># HTTP PARAMETERS<br>#######################################################################<br>
http {<br>&nbsp;&nbsp;&nbsp; include&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mime.types;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; default_type&nbsp; application/x-javascript;<br><br>&nbsp;&nbsp;&nbsp; log_format main &#39;$remote_addr - $remote_user [$time_local] $request &#39;<br>&nbsp;&nbsp;&nbsp; &#39;&quot;$status&quot; $body_bytes_sent &quot;$http_referer&quot; &#39;<br>
&nbsp;&nbsp;&nbsp; &#39;&quot;$http_user_agent&quot; &quot;$http_x_forwarded_for&quot;&#39;;<br>&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; access_log on;<br>&nbsp;&nbsp;&nbsp; client_header_buffer_size&nbsp;&nbsp;&nbsp; 1k;<br>&nbsp;&nbsp;&nbsp; large_client_header_buffers&nbsp; 4 4k;<br><br>&nbsp;&nbsp;&nbsp; gzip on;<br>&nbsp;&nbsp;&nbsp; gzip_min_length 1100;<br>
&nbsp;&nbsp;&nbsp; gzip_buffers 64 8k;<br>&nbsp;&nbsp;&nbsp; gzip_comp_level 3;<br>&nbsp;&nbsp;&nbsp; gzip_http_version 1.1;<br>&nbsp;&nbsp;&nbsp; gzip_proxied any;<br>&nbsp;&nbsp;&nbsp; gzip_types text/plain application/xml application/x-javascript text/css;<br><br>&nbsp;&nbsp;&nbsp; output_buffers&nbsp;&nbsp; 32 512k;<br>
&nbsp;&nbsp;&nbsp; sendfile_max_chunk&nbsp; 128k;<br>&nbsp;&nbsp;&nbsp; postpone_output&nbsp; 1460;<br>&nbsp;&nbsp;&nbsp; server_names_hash_bucket_size 64;<br>&nbsp;&nbsp;&nbsp; client_max_body_size 15m;<br><br>&nbsp;&nbsp;&nbsp; sendfile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br>&nbsp;&nbsp;&nbsp; tcp_nopush&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br>&nbsp;&nbsp;&nbsp; tcp_nodelay&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; on;<br>
&nbsp;&nbsp; #send_lowat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 12000;<br><br>&nbsp;&nbsp;&nbsp; #timeouts<br>&nbsp;&nbsp;&nbsp; keepalive_timeout&nbsp;&nbsp; 60 60;<br>&nbsp;&nbsp;&nbsp; client_header_timeout&nbsp; 1m;<br>&nbsp;&nbsp;&nbsp; client_body_timeout&nbsp;&nbsp;&nbsp; 1m;<br>&nbsp;&nbsp;&nbsp; send_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1m;<br>&nbsp;&nbsp;&nbsp; reset_timedout_connection on;<br>
...<br>---------<br>Мой sysctl.conf:<br>-----------<br><br># Kernel sysctl configuration file for Red Hat Linux<br># version 1.1 <br># For binary values, 0 is disabled, 1 is enabled.&nbsp; See sysctl(8) and<br># sysctl.conf(5) for more details.<br>
<br># Controls IP packet forwarding<br>net.ipv4.ip_forward = 0<br><br># Controls source route verification<br>net.ipv4.conf.default.rp_filter = 0<br><br># Do not accept source routing<br>net.ipv4.conf.default.accept_source_route = 0<br>
<br># Controls the System Request debugging functionality of the kernel<br>kernel.sysrq = 0<br><br># Controls whether core dumps will append the PID to the core filename<br># Useful for debugging multi-threaded applications<br>
kernel.core_uses_pid = 1<br><br># Controls the use of TCP syncookies<br>net.ipv4.tcp_syncookies = 1<br><br># Controls the maximum size of a message, in bytes<br>kernel.msgmnb = 65536<br><br># Controls the default maxmimum size of a mesage queue<br>
kernel.msgmax = 65536<br><br># Controls the maximum shared segment size, in bytes<br>kernel.shmmax = 4294967295<br><br># Controls the maximum number of shared memory segments, in pages<br>kernel.shmall = 268435456<br><br>
###################<br>#Custom parameters#<br>###################<br><br># We use it always<br># Параметр представляет собой два целых числа, которые определяют диапазон локальных портов,<br># которые используются в клиентских соединениях, т.е. для исходящих<br>
# соединений, которые связывают нашу систему с некоторым узлом сети, где мы выступаем в качестве клиента<br>net.ipv4.ip_local_port_range = 1025 65535<br># Быстрая утилизация сокетов находящихся в состоянии TIME_WAIT<br>net.ipv4.tcp_tw_recycle = 1<br>
# Время пребывания сокета в состоянии FIN-WAIT-2<br>net.ipv4.tcp_fin_timeout = 3<br><br># New param<br># Длина очереди для входящих пакетов<br>net.core.netdev_max_backlog = 10000<br># Количество возможных подключений к сокету, прежде чем будут отброшены<br>
net.core.somaxconn = 262144<br># Буфер под хранение SYN запросов на соединение. Значение по умолчанию 1024, что очень мало для нагруженных серверов.<br>net.ipv4.tcp_max_syn_backlog = 262144<br># Возможное количество сокетов в состоянии TIME_WAIT<br>
net.ipv4.tcp_max_tw_buckets = 720000<br># Опция включена, иначе не будет работать опция tcp_tw_reuse описанная ниже<br>net.ipv4.tcp_timestamps = 1<br># Механизм, разрешающий использовать уже существующие сокеты которые находятся в состоянии TIME_WAIT, если это не повредит безопасности.<br>
net.ipv4.tcp_tw_reuse = 1<br># Временной интервал попытки определения жизнеспособности соединения. <br># По умолчанию 7200, т е через 2 часа после того как через соединение прочел последний пакет,<br># система отправит keep-alive запрос чтобы узнать состояние соединения. Уменьшим этот параметр до 30 минут.<br>
net.ipv4.tcp_keepalive_time = 30<br># Количество посылок keepalive запросов и интервалов между запросами. <br># По умолчанию делается 9 попыток с интервалом в 75 секунд, что в свою очередь займет 9*75=11 минут и 25 секунд, <br>
# что в сочетании с параметром по умолчанию net.ipv4.tcp_keepalive_time = 7200 дает нам <br># значение 2часа 11 минут 25 секунд &mdash; минимальное значение времени после которого соединение будет закрыто нашей стороной<br># после прохождения через это соединение последнего пакета. Это очень большой интервал.<br>
net.ipv4.tcp_keepalive_probes = 2<br>net.ipv4.tcp_keepalive_intvl = 10<br># Максимальный размер буферов по умолчанию для приема и отправки данных через сокеты (в байтах)<br>net.core.wmem_max = 33554432<br>net.core.rmem_max = 33554432<br>
# Размер буферов по умолчанию для приема и отправки данных через сокеты (в байтах)<br>net.core.rmem_default = 8388608<br>net.core.wmem_default = 4194394<br># Настройка буферов для TCP и UDP соединений (min, default, max bytes) (в байтах)<br>
net.ipv4.tcp_rmem = 4096 8388608 16777216<br>net.ipv4.tcp_wmem = 4096 4194394 16777216<br># Этот параметр дает ядру больше памяти для TCP.<br># Это будет необходимо при 50k+ открытых соединений.<br>net.ipv4.tcp_mem = 109568 109568 109568<br>
# Количество попыток закрыть соединение перед тем как оно будет разорвано<br># принудительно. Если вы администрируете http-сервер, который испытывает<br># большие нагрузки, то стоит подумать об уменьшении этого значения.<br>
# Переменная принимает целое число. Значение по-умолчанию&nbsp; 7, что<br># соответствует, примерно, от 50 секунд до 16 минут<br>net.ipv4.tcp_orphan_retries = 3<br># Переменная задает максимальное число осиротевших (не связанных ни с<br>
# одним процессом) сокетов. Если это число будет превышено, то такие<br># соединения разрываются, а в системный журнал пишется предупреждение. Это<br># ограничение существует исключительно ради предотвращения простейших<br>
# разновидностей DoS-атак.<br>net.ipv4.tcp_max_orphans = 300000<br><br>net.ipv4.conf.eth0.rp_filter = 0<br>net.ipv4.conf.all.rp_filter = 0<br># Максимальное значение открытых файлов. Что бы его узнать, выполните<br><br>#net.ipv4.netfilter.ip_conntrack_tcp_timeout_close = 30<br>
#net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 30<br>#net.ipv4.netfilter.ip_conntrack_tcp_timeout_last_ack = 120<br>#net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 30<br>#net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 60<br>
#net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 30<br>#net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_recv = 30<br>#net.ipv4.netfilter.ip_conntrack_tcp_timeout_syn_sent = 30<br><br>net.ipv4.tcp_fin_timeout = 30<br>
net.ipv4.tcp_sack = 0<br>net.ipv4.tcp_timestamps = 0<br><br># команду cat /proc/sys/fs/file-max<br>fs.file-max = 999999<br># Virtual memory<br># Использовать swap только в крайнем случае<br>vm.swappiness = 20<br>-- <br><br>