У меня была похожая проблема, не мог никак найти проблему в кластере со сквидом (squid >2500 чел + frox, transparent 100Mb/s Fiber в UA-IX, суточный траффик 30-200Gb, главная нода P4 3,06GHz/2Gb RAM/IDE 40Gb HDD/3com 1Gb/s LAN, OS Debian 4.0). Решал следующими способами:
Во-первых, как приходит/уходит траффик?. Если все идет через одну, то если в равной степени нагрузить канал, получается своеобразный DDOS.Как и в твоем случае куча SYN соединений, закрывать их таймаутами бесполезно. Выход - поставить НЕ ВСТРОЕННУЮ сетевуху желательно 1Gb/s 3com или Intel, обязательно с разгрузкой контрольных сумм, поддержкой POLLING, со встроенными в её ЦП аппаратными буфферами. В результате снизишь нагрузку на ЦП, IO на шине.
Во вторых, контролировать количество открытых файловых дескрипторов, иначе софт будет простаивать, ожидая освобождения ФД. Подробнее man ulimit.
В третьих, если канал в какой-то точке от тебя наружу <100Mb/s и загружен до предела, увеличивать буфферы нет смысла. В Generic конфиге линух рассчитан на среднюю нагрузку по 1Гб/с каналу.
В четвертых - немного уменьшить таймауты TCP.
В пятых - увеличить кол-во портов, доступных для userspace приложений.
В шестых - увеличить кол-во сокетов для обслуживания tcp соединений.
В итоге мой sysctl.conf выглядит так:
Код: Выделить всё
fs.file-max=8192
net.ipv4.conf.all.send_redirects=0
net.ipv4.conf.all.accept_redirects=0
net.ipv4.conf.all.secure_redirects=0
net.core.rmem_default=201250
net.core.wmem_default=201250
net.core.rmem_max=256000
net.core.wmem_max=256000
net.ipv4.tcp_fin_timeout=15
net.core.netdev_max_backlog=3000
net.core.somaxconn=3000
net.ipv4.tcp_keepalive_intvl=5
net.ipv4.tcp_keepalive_probes=3
net.ipv4.ip_local_port_range=1024 65000
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_mtu_probing=1
настройка производилась по RHEL Performance Guide и Tuning Suse Enterprise Server 10 guide для Debian 4.0 etch.
И еще совет, неважно, Linux это или фря, поставить мониторинг этих значений например в MRTG. таким способом будет видно реальное соотношение параметрв, их значения в момент времени.
например как в этом примере mrtg.cfg (взято из боевого сервера)
Код: Выделить всё
Target[tcp-est]: `/etc/scripts/est_state.sh`
Title[tcp-est]: Num of connections in ESTABLISHED/SYN_SENT state
PageTop[tcp-est]: <H1>Firebox Num of connections in ESTABLISHED/SYN_SENT state</H1>
Options[tcp-est]: gauge, nopercent, perminute, pngdate
MaxBytes[tcp-est]: 10000
ShortLegend[tcp-est]: Number
YLegend[tcp-est]: Connections
LegendI[tcp-est]: TCP Connections in ESTABLISHED State
LegendO[tcp-est]: TCP Connections in SYN_SENT State
Legend1[tcp-est]: TCP Connections in ESTABLISHED State
Legend2[tcp-est]: TCP Connections in SYN_SENT State
Target[tcp-close]: `/etc/scripts/wait_state.sh`
Title[tcp-close]: Num of connections in TIME_WAIT/CLOSE_WAIT state
PageTop[tcp-close]: <H1>Firebox Num of connections in TIME_WAIT/CLOSE_WAIT state</H1>
Options[tcp-close]: gauge, nopercent, perminute, pngdate
MaxBytes[tcp-close]: 10000
ShortLegend[tcp-close]: Number
YLegend[tcp-close]: Connections
LegendI[tcp-close]: TCP Connections in TIME_WAIT State
LegendO[tcp-close]: TCP Connections in CLOSE_WAIT State
Legend1[tcp-close]: TCP Connections in TIME_WAIT State
Legend2[tcp-close]: TCP Connections in CLOSE_WAIT State
вот так выглядит /etc/scripts/est_state.sh
Код: Выделить всё
#!/bin/sh
echo `netstat -st | grep "connections established" | awk '{print $1}'`
echo `netstat -an | grep "SYN_SENT" | wc -l`
exit 0
вот так /etc/scripts/wait_state.sh
Код: Выделить всё
#!/bin/sh
echo `netstat -an | grep "TIME_WAIT" | wc -l`
echo `netstat -an | grep "CLOSE_WAIT" | wc -l`
exit 0
можно конечно применить RRDTOOL, но имхо, для этого случая мне хватило и MRTG, чтобы найти виновника.