На прошлой неделе я имел дело с агрессивным роботом-обходчиком / атакой. Бот распространяется со случайными IP-адресами и строкой агентов, поэтому их сложно заблокировать, но у меня есть другой поток для этого. Эта проблема заключается в том, что поток HTTP-запросов может привести к смерти Tomcat.
Процесс Tomcat все еще в порядке, и ему не хватает памяти, он просто перестает принимать запросы http или https. Он отключит любой HTTP-запрос, но все равно будет принимать запросы https (если http подвергается атаке, иногда https также умирает).
Ранее я видел ошибку «слишком много открытых файлов», поэтому я изменил ограничение на количество файлов с 10000 на 50000, что, похоже, помогло, по крайней мере, https умирает, но http все еще умирает. В последнее время я не вижу "слишком много открытых файлов".
Похоже, слишком много открытых файлов, зачем Tomcat открывать так много файлов, может ли утечка файлов при высокой нагрузке? Иногда с сервером все в порядке в течение 6 месяцев (так что утечки не может быть в нормальных условиях), но раньше он падал при высокой нагрузке.
Веб-сайт - это большой сайт с> 1 миллионом страниц (динамическое содержание) и> 1 миллионом посещений в день.
Что происходит, когда Tomcat получает поток HTTP-запросов (например,> 100 в секунду в течение длительного времени), я предполагаю, что запросы начнут резервное копирование, если при использовании пула потоков не останется потоков, он будет продолжать объединять запросы, пока что-то ломается, или он начнет отклонять запросы?
Есть ли способ начать отклонять запросы после определенного объема резервного копирования? Кажется, единственный способ предотвратить смерть или аварию при экстремальной нагрузке.
Моя конфигурация http и https отличается, так что, возможно, это связано с тем, почему http умирает. https использует maxThreads, а http - нет (сколько потоков по умолчанию?)
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="443"
URIEncoding="UTF-8" />
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="..." keystorePass="..."
URIEncoding="UTF-8"/>
Использование Tomcat v8.5.47, CentOS 7.6, Oracle Java 1.8
Оба этих соединителя будут использовать реализацию NIO.
Для 8.5.47 значение maxConnections по умолчанию - 10000, а невыполненное - 100.
Что произойдет, так это первые 10000 подключений будут приняты и будут, в свою очередь, выделены потокам в пуле потоков (по умолчанию 200 потоков) для обработки. Сколько времени потребуется на обработку этих подключений, зависит от приложения.
Если текущих подключений 10000, следующие 100 запросов будут отложены в журнале. Пока Java пытается настроить это значение на 100, ОС может проигнорировать этот параметр.
После заполнения журнала последующие подключения будут отключены.
Вы можете (надеюсь) выяснить, почему HTTP не отвечает, взяв три дампа потока на расстоянии ~ 5 секунд, когда вы увидите, что HTTP не отвечает.