LinuxForum.Fans
Тема

Высокий LA, периодические зависания соединений

Автор: env 4 сообщений 3756 просмотров
15.11.2022 14:24 #438568

Здравствуйте.
Сервер на SSD, 64GB RAM, 12 ядер, стоит Debian 7, на сервере работают сайты в связке Apache, Nginx, PHP, MySQL, Sphinx.
Долгое время уровень LA держался на уровне 25-30, подтормаживало, не супер критично, работы было много, откладывали это дело всегда в долгий ящик. Когда LA улетал до 50-70-100, перезагружали Apache или сам сервер, LA приходил к норме, работали дальше.
Полгода назад решил заняться этим вопросом. Сам я нуб в Linux, работал на уровне поставить программу по инструкции, покрутить настройки Mysql, Apache по статейкам в интернете (пальцем в небо). Начал разбираться, узнал, что такое access-логи, из них выяснил, что нас долбят огромным количеством спама, разобрался с iptables на уровне забанить IP. Написал простой скрипт, который парсил access-логи и выдавал IP, с которых было огромное количество запросов, потом банил вручную эти IP. В момент повышения нагрузки набаню 20-30 IP, перезагружу сервер, LA становится 10-12, все летает, успокаиваюсь. В течение недели плавно нарастает та же самая шляпа, нужно все повторять. Нашел информацию о сервисе fail2ban, установил, включил – изменений сразу не увидел и забыл про него. Со временем стал замечать, что нагрузка 8-10, боты вроде уже и не долбятся (очень много набанил вручную самых основных + на уровне Nginx настроил 403 ответ по куче юзер-агентов часто встречающихся ботов), но есть странные зависания при работе с сайтами – ходишь по страницам, отправляешь формы, и в какой-то момент бац – 10-15 секунд зависание запроса, который в 90% случаев выполняется, а в 10% отваливается после этого ожидания. Тут же пробуешь повторить действие несколько раз – все в порядке. Через 2-3 минуты опять такое же зависание, клиенты тоже начали на подобное жаловаться, и это поведение спустя полгода начало ухудшаться – уже и пару раз за минуту могло произойти. В этот момент вспомнил про fail2ban, установленный полгода назад и брошенный с настройками по умолчанию (там были включены фильтры для ssh и apache), попробовал его выключить – ситуация с зависаниями очень сильно сократилась, в день выключения заметил 3-5 подвисаний за весь день, что могло и по любым другим причинам произойти. Но! Начала опять расти нагрузка, стало 20-30, как и раньше, и подвисаний вроде и нет, но зато все медленно работает. Решил разобраться с fail2ban, выключил секцию apache, включил apache-badbots, написал для него собственную регулярку со списком постоянно спамящих нас юзер-агентов (за сутки более 600 IP по ним он забанил), также оставил секцию с ssh. Параллельно с этим просмотрел лог медленных запросов MySQL, поисправлял кучу запросов, добавил индексов (при высоком LA, как правило, именно mysqld жрал CPU сильнее всех по команде top), нагрузка спала аж до 3-5 в моменте, все начало летать. Спустя 2 дня опять начинаются подвисания по 10-15 секунд, LA 8-10. Выключил fail2ban, нагрузка 20-30, зато нет зависаний. Моментами спадает нагрузка, может 2 часа держаться в норме, потом опять 20-30. Перезагружаю Apache, нагрузка падает, в течение 10 минут опять вырастает.
Перерыл весь интернет, везде все разное, каждый случай, как я понял, в администрировании уникальный, какой-то конкретной методологии выявления проблем не нашел, хожу по кругу, 10 часов танцев с гуглом (бубном), удается снизить нагрузку, но через 2 дня опять подскоки, причем в час-пик может быть 8-10, а ночью 20, хотя чаще все-таки наоборот. И если с самой нагрузкой еще хоть какие-то наметки понятны, хотя далеко не все, то с зависаниями при включенном fail2ban не улавливаю вообще, ведь он конкретный входящий запрос не трогает – он сканит логи.
Моя логика такая, что из-за того, что на сервере в районе 100 сайтов, которых постоянно посещает куча разных ботов, которые, может, и не такие плохие, и нагрузку на каждый сайт создают небольшую, но если сайтов 100, то и нагрузка x100. Они дергают запросы, каждый запрос – нагрузка на mysql, которая все время "в топе" команды top. Их нужно банить автоматически, с чем справляется fail2ban, но после его включения через некоторое время начинаются какие-то зависания соединений. После его выключения, боты выходят из бана и начинают нас спамить, дергать огромное количество страниц, создавая огромное количество запросов к БД, которая начинает жрать все ресурсы CPU. А может это предположение, потому что в момент этой высокой нагрузки не понимаю, за что зацепиться – и боты, и MySQL жрет CPU, естественно лог медленных запросов растет, а нужно ли их исправлять – да вроде нет, ведь когда нагрузка в норме, лог почти не растет.
В общем хочу обратиться за помощью, с чего начать, чтобы не ходить по кругу от access-логов и fail2ban с iptables до оптимизации кода приложений? Уже умуздыкался, результат всегда один – через некоторое время после 1-2 дней танцев с бубном начинаются ухудшения производительности.

29.11.2022 00:54 · отредактировано #438595

Так сильно достало, что такую "портянку" накатал? Еле осилил. :) Прежде чем заморачиваться этим вопросом хотелось бы сначала увидеть конфиг mysql. Сервер-то физический или виртуальный?

04.12.2022 21:13 #438610

Что имеем в сухом остатке... Куча текстов много буков... Их надо осилить...
Кто держит на одном сервере 100 хостов?
Ну да ладно если держим то следует учитывать что сайты посещают как пользователи, так и поисковые роботы, рекламные роботы...
А далее школота... дос атаки...
Что с поисковыми роботами делать - уменьшить частоту сканирования можно...
Со школотой фильтры по IP и HTTP_USER_AGENT.
Обычно если сервер приуныл всем прикрывается доступ, открывается только себе и анализируется лог.
Нам нужен USER AGENT и IP хостов.
А далее дело техники.

Как то так "#" символы удалить при использовании:

Показать
text
#<LIMIT GET POST PUT>
# order deny,allow
# allow from all
# allow from Мой IP 
# allow from Rizado IP
# deny from 82.102.20.0/24
# deny from 188.165.0.0/16
# deny from 159.65.0.0/16
# deny from 130.61.0.0/16
# deny from 144.24.0.0/16
# deny from 194.163.160.0/19
# deny from 62.133.47.0/24
# deny from 75.119.128.0/19
# deny from 45.160.0.0/11
# deny from 84.16.224.0/19
# deny from 62.149.0.0/24
# deny from 89.237.34.174
# 89.237.32.0/22 orsk russia если что всю подсеть в бан
# deny from 103.130.141.0/24
# deny from 162.219.176.163
# deny from 191.96.168.115
# deny from 14.99.39.14
# deny from 161.97.128.0/19
# deny from 161.97.184.0/22
# deny from 161.97.176.0/21
# deny from 161.97.64.0/18
# deny from 161.97.188.0/23
# deny from 161.97.160.0/20
# deny from 167.99.0.0/16
# </LIMIT>

Вот так я одного школотрона с Хрумером отфильтровал:

Показать
# RewriteCond %{HTTP_USER_AGENT} 20031210|Presto|80legs|abilogic|AddSugarSpiderBot|alltheweb|anyapex|AppEngine-Google|AppleTV|Avant|Baiduspider [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} BecomeBot|BeOS|BillyBobBot|bingbot|BlackBerry|Bloglines|BrowserEmulator|Chrome/72|Chrome/77|CLDC|Control|CSSCheck [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} CUPCAKE|cupcake|Dalvik|datecode|Dillo|DoCoMo|Download|ELinks|Emacs|EmailWolf|everyfeed|Exabot [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} facebookscraper|feedfetcher|Feedfetcher|Firebird/0|Gaisbot|Googlebot-Video/1.0|gregarius|grub-client|GulperBot|HTC [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} HTMLParser|iccenter|iTunes|Java/1|libwww-FM|libwww-perl|Links|lwp-trivial|Lynx/2|Macintosh|Mediapartners-Google|Minefield/3 [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} MMP|Mozilla/1|Mozilla/4|msnbot|NetFront|NetSurf|Nintendo|Nokia|nook|NutchCVS|Offline|Opera/9|Peach/1.01|POLARIS [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} portalmmm|Prevx|Python-urllib|ReqwirelessWeb|SearchExpress|SGHX|SiteBar|Slurp|SonyEricsson|sparc|sparc|spidersoft [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} sproose|Sqworm|SunOS|SuperBot|SymbianOS|Teoma|tnftp|UP.Link|Uzbl|Validator|Vodafone|w3m|WDG|WebCopier [NC,OR]
# RewriteCond %{HTTP_USER_AGENT} webetrex|wget|wii|Win95|Windows.XP|Windows.98|Мozilla/4|Phoenix [NC]
# RewriteRule !^spam/ http://officeofstrategicinfluence.com/spam/ [L,NC,R=302]

А вот так последню ддос атаку

Показать
# Options +FollowSymlinks
# RewriteCond %{HTTP_REFERER} (plugin_googlemap) [NC,OR]
# RewriteCond %{HTTP_REFERER} validator.w3.org [NC,OR]
# RewriteCond %{HTTP_REFERER} web-sniffer.net [NC,OR]
# RewriteCond %{HTTP_REFERER} ^http://.* [NC]
# RewriteRule .* – [F]

Вывод... Фильтровать по юзерагенту проще чем по Ip.
Потому как юзерагенты хотя и генерируются, но они одинаковые, а вот ip адреса могуть у особо буйных пациентов быть достаточно разнами если у них большая база прокси.
Добавлено: 04.12.2022 21:13:02

Вот вы должны понимать что имея на одном Хосте 100 серверов, эти сто Хостов могут "атаковаться" школотронами, поисковиками и т.д. одновременно.
А так как сервер 1 то канал могут зафлудить подключениями... и у Вас не то что хостинг, а DNS сервер вытянуть не сможет.
К примеру DNS хостинга на котором данный форум работает количество подключений вытягивает, но вот сам форум может приуныть на некоторое время из-за того что нагрузка на сам форум многократно вырастает. И тут на помощь приходит фильтрация. Мозг + чуточку фантазии творят чудеса. Пробуйте результат сообщите.

05.12.2022 12:52 · отредактировано #438612
alt6kdesktop написал:
Так сильно достало, что такую "портянку" накатал? Еле осилил. :) Прежде чем заморачиваться этим вопросом хотелось бы сначала увидеть конфиг mysql. Сервер-то физический или виртуальный?

Apache бекэнд, Nginx прокси.

Конфиг MySQL из того, что настраивал я, остальное по умолчанию:

text

skip-name-resolve
performance_schema = off

innodb_flush_method = O_DIRECT innodb_buffer_pool_size = 15G innodb_buffer_pool_instances = 15 innodb_log_file_size = 1G innodb_flush_log_at_trx_commit = 2 innodb_additional_mem_pool_size = 20M secure_file_priv = "" log_slow_queries = /var/log/mysql/mysql_slow.log long_query_time = 5 log_error = /var/log/mysql/mysql_error.log log_warnings = 1 max_connections = 2000 wait_timeout = 90 interactive_timeout = 90 innodb_stats_on_metadata = 0 innodb_log_buffer_size = 8M table_definition_cache = 4096 innodb_read_io_threads = 8 innodb_write_io_threads = 8 innodb_thread_concurrency = 24

Медленных запросов почти нет, кроме LOAD DATA INFILE, так как в районе 100 миллионов записей обновляются ежедневно – это больший прайс-листы. Есть еще INSERT медленный в некоторых местах, выясняю, но их не так много. Однострочные вставки в большом объеме от разных пользователей (например, запись посещения).
Добавлено: 05.12.2022 12:52:16

MozgFx написал:

Что имеем в сухом остатке... Куча текстов много буков... Их надо осилить...
Кто держит на одном сервере 100 хостов?

Это единая платформа для создания интернет-магазинов в определенной сфере (типа тильлды), поэтому так.

MozgFx написал:

Ну да ладно если держим то следует учитывать что сайты посещают как пользователи, так и поисковые роботы, рекламные роботы...
А далее школота... дос атаки...
Что с поисковыми роботами делать - уменьшить частоту сканирования можно...
Со школотой фильтры по IP и HTTP_USER_AGENT.
Обычно если сервер приуныл всем прикрывается доступ, открывается только себе и анализируется лог.
Нам нужен USER AGENT и IP хостов.
А далее дело техники.

Вывод... Фильтровать по юзерагенту проще чем по Ip.
Потому как юзерагенты хотя и генерируются, но они одинаковые, а вот ip адреса могуть у особо буйных пациентов быть достаточно разнами если у них большая база прокси.

В итоге так и было сделано, только задачу эту переложилли на fail2ban, который автоматически access-логи сканит, прописал для него правила блокировки в iptables по User-agent, реально LA снизился до 8-10 в 95% времени (на 12 ядрах). В час-пик может быть 14-17, и то не факт. Ночью LA 3-4.

В целом выяснил уже, что fail2ban никак не влияет на мою проблему, он работает как надо. Медленные SQL-запросы практически все пофикшены (более 3 секунд).

Таким образом, от флуда ненужного избавились в целом, можно еще подокручивать со временем, но уже результат успешный.

Также некоторые более популярные в интернете хосты повесили на cloudflare, чтобы школьники их не дедосили своими парсерами.

MozgFx написал:

Вот вы должны понимать что имея на одном Хосте 100 серверов, эти сто Хостов могут "атаковаться" школотронами, поисковиками и т.д. одновременно.
А так как сервер 1 то канал могут зафлудить подключениями... и у Вас не то что хостинг, а DNS сервер вытянуть не сможет.
К примеру DNS хостинга на котором данный форум работает количество подключений вытягивает, но вот сам форум может приуныть на некоторое время из-за того что нагрузка на сам форум многократно вырастает. И тут на помощь приходит фильтрация. Мозг + чуточку фантазии творят чудеса. Пробуйте результат сообщите.

С этим и боролись, а когда начались зависания 30-секундные раз в 2-3 минуты (основная проблема), решили, что виноват fail2ban, потому что начало этих зависаний совпало с установкой и настойкой fail2ban. Уже выяснили, что просто совпало.

Зависаний стало чуть меньше, видимо, благодаря снижению нагрузки, но они остались. Причем иногда их нет почти в течение суток даже при LA 17. А иногда за час я их ловлю аж 20-30 при работе с любым из сайтов при LA 3-4. То есть с нагрузкой справился, но она на зависания и не влияет.

Как определить, вывозит ли DNS? Думал насчет пропускной способности интернета, но у нас в пиках пакетов до 100 Мбит/с приходит, а поддержка сообщила, что канал до 1000 Мбит/с. Увеличение MaxChildren (или как правильно, не помню) в Apache изменений не дает. Как выяснить, подходят ли к пределам эти значения на apache, nginx – не нашел. Но, опять-таки, ситуация ночью может быть хуже, чем в час-пик (но не обязательно), поэтому тут явно не с лимитами соединений связано.

СЕВЕР ВИРТУАЛЬНЫЙ

Команда ifconfig у меня выводит следующее:

text
eth0      Link encap:Ethernet  HWaddr de:6e:5e:e5:27:4d                                                                                                                
          inet addr:91.201.41.156  Bcast:91.201.41.255  Mask:255.255.255.0                                                                                             
          inet6 addr: fe80::dc6e:5eff:fee5:274d/64 Scope:Link                                                                                                          
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                                                                                                           
          RX packets:850571396 errors:39598410 dropped:7858 overruns:0 frame:39598410                                                                                  
          TX packets:694180233 errors:0 dropped:0 overruns:0 carrier:0                                                                                                 
          collisions:0 txqueuelen:1000                                                                                                                                 
          RX bytes:672208880716 (626.0 GiB)  TX bytes:314846610539 (293.2 GiB)                                                                                         
                                                                                                                                                                       
eth0:0    Link encap:Ethernet  HWaddr de:6e:5e:e5:27:4d                                                                                                                
          inet addr:91.201.43.57  Bcast:91.201.43.57  Mask:255.255.255.255                                                                                             
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1                                                                                                           
                                                                                                                                                                       
lo        Link encap:Local Loopback                                                                                                                                    
          inet addr:127.0.0.1  Mask:255.0.0.0                                                                                                                          
          inet6 addr: ::1/128 Scope:Host                                                                                                                               
          UP LOOPBACK RUNNING  MTU:16436  Metric:1                                                                                                                     
          RX packets:4408653450 errors:0 dropped:0 overruns:0 frame:0                                                                                                  
          TX packets:4408653450 errors:0 dropped:0 overruns:0 carrier:0                                                                                                
          collisions:0 txqueuelen:0                                                                                                                                    
          RX bytes:1871977400448 (1.7 TiB)  TX bytes:1871977400448 (1.7 TiB)

В районе 5-6% входящих пакетов с ошибками. Вывод этой команды за неделю аптайма для понимания, то есть за неделю 40 млн входящих пакетов с ошибками. Предположил, что проблема кроется здесь.

Сообщил в техподдержку дата-центра информацию, мне ответили так:

Никаких проблем нет. Игнорируйте этот счетчик. rx_short_length_errors означает, что ядро вашего сервера отбросило слишком короткий пакет (скорее всего широковещательный пакет и он не предназначался для Вашего сервера). на профильных форумах рекомендуют сменить драйвер виртуальной машины, мы уже пробовали это делать и не на всех операционных системах это помогает. Но можем попробовать для Вашего vds

вот данные с корневой машины, никаких проблем с железом нет. На Вашем сервере виртуальный драйвер сетевой карты - там нет никаких проводов, физических носителей и сетевых адаптеров.

И привели такие результаты команд

text
root@kx04:~# ifconfig eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 00:25:90:7b:e4:f8 txqueuelen 1000 (Ethernet)
RX packets 72068117885 bytes 52768707848440 (47.9 TiB)
RX errors 0 dropped 571203 overruns 571203 frame 0
TX packets 66682068826 bytes 52740049650882 (47.9 TiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
text
root@client:~# ethtool -S eth0 | grep error
rx_errors: 0
tx_errors: 0
rx_length_errors: 42035675
rx_over_errors: 0
rx_crc_errors: 0
rx_frame_errors: 0
rx_missed_errors: 0
tx_aborted_errors: 0
tx_carrier_errors: 0
tx_fifo_errors: 0
tx_heartbeat_errors: 0
tx_window_errors: 0
rx_long_length_errors: 0
rx_short_length_errors: 42035675
rx_align_errors: 0
rx_csum_offload_errors: 0

На что я предположил, что так как сервер виртуальный, значит, ресурсы я делю с другими виртуальными серверами, в которых и может крыться проблема. Они там могут SSD драконить или процессор, и у меня начинаются проблемы. Может ли быть такое?

Также они, как видно из цитаты, предложили сменить какой-то драйвер – пока не просили ничего менять. Есть ли смысл?

Войдите или зарегистрируйтесь, чтобы ответить.