Apache Tomcat задихається після 300 з'єднань

Ми маємо веб-сервер Apache перед Tomcat, розміщений на EC2, тип екземпляра дуже великий з пам'яттю в 34 ГБ.

Наше додаток займається великою кількістю зовнішніх веб-сервісів, і у нас дуже поганий зовнішній веб-сервіс, який займає майже 300 секунд, щоб відповідати на запити в години пік.

У пікові години сервер задихається приблизно на 300 процесах httpd. ps -ef | grep httpd | wc -l = 300

Я googled і знайшов численні пропозиції, але нічого не працює .. наступні деякі конфігурації я зробив, які безпосередньо взяті з інтернет-ресурсів.

Я збільшив межі максимального підключення та максимального числа клієнтів як у apache, так і tomcat. ось деталі конфігурації:

// apache

   
    StartServers 100
    MinSpareServers 10
    MaxSpareServers 10
    ServerLimit 50000
    MaxClients 50000
    MaxRequestsPerChild 2000
    

// tomcat

    

//Sysctl.conf

 net.ipv4.tcp_tw_reuse=1
 net.ipv4.tcp_tw_recycle=1
 fs.file-max = 5049800
 vm.min_free_kbytes = 204800
 vm.page-cluster = 20
 vm.swappiness = 90
 net.ipv4.tcp_rfc1337=1
 net.ipv4.tcp_max_orphans = 65536
 net.ipv4.ip_local_port_range = 5000 65000
 net.core.somaxconn = 1024

Я намагався численні пропозиції, але марно .. як це виправити? Я впевнений, що m2xlarge сервер повинен обслуговувати більше запитів, ніж 300, ймовірно, я можу зіпсувати мою конфігурацію

Сервер задихається тільки в години пік і коли існує 300 одночасних запитів, які очікують відповіді на [300 секундну затримку] webservice.

Я просто моніторинг tcp з'єднання з netstat

Я знайшов близько 1000 з'єднань в TIME_WAIT держави, не знаю, що це буде означати, з точки зору продуктивності, я впевнений, що він повинен бути доповнення до проблеми.

Вихід ТОП

 8902  root      25   0 19.6g 3.0g  12m S  3.3  8.8  13:35.77 java
 24907 membase   25   0  753m 634m 2528 S  2.7  1.8 285:18.88 beam.smp
 24999 membase   15   0  266m 121m 3160 S  0.7  0.3  51:30.37 memcached
 27578 apache    15   0  230m 6300 1536 S  0.7  0.0   0:00.03 httpd
 28551 root      15   0 11124 1492  892 R  0.3  0.0   0:00.25 top


 Output of free -m
 total       used       free     shared    buffers    cached
 35007       8470       26536    0          1         61
 8407        26599
 15999       15         15984

 output of iostat
 avg-cpu:  %user   %nice %system %iowait  %steal   %idle
      26.21    0.00    0.48    0.13    0.02   73.15

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda1             14.36         4.77       329.37    9005402  622367592
sdb               0.00         0.00         0.00       1210         48

Також у піковий час існує близько 10-15k tcp підключень до мембранного сервера [local]

Деякі помилки в журналі MODJK LOG, я сподіваюся, що це висвітлить питання.

[Wed Jul 11 14:39:10.853 2012] [8365:46912560456400] [error]         ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:18.627 2012] [8322:46912560456400] [error] ajp_send_request::jk_ajp_common.c (1630): (tom2) connecting to backend failed. Tomcat is probably not started or is listening on the wrong port (errno=110)
[Wed Jul 11 14:39:21.358 2012] [8351:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)
[Wed Jul 11 14:39:22.640 2012] [8348:46912560456400] [error] ajp_get_reply::jk_ajp_common.c (2118): (tom1) Tomcat is down or refused connection. No response has been sent to the client (yet)

~

Worker.properties
workers.tomcat_home=/usr/local/tomcat/
worker.list=loadbalancer
worker.tom1.port=8009
worker.tom1.host=localhost
worker.tom1.type=ajp13
worker.tom1.socket_keepalive=True
worker.tom1.connection_pool_timeout=600
worker.tom2.port=8109
worker.tom2.host=localhost
worker.tom2.type=ajp13
worker.tom2.socket_keepalive=True
worker.tom2.connection_pool_timeout=600
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=tom1,tom2
worker.loadbalancer.sticky_session=True
worker.tom1.lbfactor=1
worker.tom1.socket_timeout=600
worker.tom2.lbfactor=1
worker.tom2.socket_timeout=600

// Розв'язано

thansk все для ваших цінних пропозицій .. Я пропустив налаштування maxThreads для роз'єму AJP 1.3 .. Тепер все здається під контролем.

Я б також почав шукати навіть на основі серверів, таких як nginx.

16
Які ваші налаштування Keepalive?
додано Автор Pablo Venturino, джерело
Як виглядає вихід верхньої у цей час? Як щодо free -m ? І, нарешті, iostat ?
додано Автор sauceboat, джерело
Чи знаєте ви, якщо Tomcat може обробляти 300 з'єднань?
додано Автор Lewis Pulsipher, джерело
З журналів з modjk, здавалося б, у вас апач налаштований на використання modjk для підключення до tomcat, а не modproxy. Так що ж конфігурація tomcat для роз'єму AJP? (Як правило, це порт 8009).
додано Автор polypus74, джерело
Які помилки повертаються клієнтам під час спроби завантажити сторінку?
додано Автор Kar, джерело
Чи неможливо кешувати відповідь з веб-сервісу, який запускається протягом 300 секунд і обслуговує відповіді клієнтам?
додано Автор Matthew Ife, джерело
Можливо, це нерозумно питання, але якщо він змінюється кожні 2 хвилини, але займе 5 хвилин, щоб отримати, чи не зміст вже застарів до того часу, коли ви його отримаєте?
додано Автор Matthew Ife, джерело
Що кажуть журнали Apache? Чи згадується ліміт сервера?
додано Автор poige, джерело
@Wyann Так .. Tomcat може обробляти 300 з'єднань, ми перевірили його протягом не пікових годин
додано Автор JZ11, джерело
@Tom My Keep Alive Settings - KeepAliveTimeout 10 у httpd.conf
додано Автор JZ11, джерело
@golja Як збільшити максимально допустимі описи відкритих файлів для користувача apache/httpd?
додано Автор JZ11, джерело
два примірники tomcat один на порт 8009, а інший на 8109, перевірте відредаговане запитання для worker.properties
додано Автор JZ11, джерело
Користувачі залишаються з завантажувальною сторінкою .. немає відповіді від сервера, також немає помилок, зареєстрованих у будь-якому журналі помилок
додано Автор JZ11, джерело
@Mlfe Є багато запитів, які отримали відповідь через пару секунд, а також .., також ця поведінка спостерігається тільки в години пік ..
додано Автор JZ11, джерело
Неможливо, дані змінюються майже кожні 2 хвилини
додано Автор JZ11, джерело
Залежить від того, який дистрибутив ви використовуєте, але це посилання має бути корисним cyberciti.biz/faq/…
додано Автор golja, джерело
Чи збільшили максимально допустимі описи відкритих файлів для користувача apache/httpd?
додано Автор golja, джерело

9 Відповіді

Чи збільшили ви maxThreads в AJP 1.3 Connector на порту 8009?

13
додано
Так, додайте maxThreads до строфи цього Connector. Типовим значенням є 200.
додано Автор Brian, джерело
@john, Ви говорите, що для кожного роз'єму ви вказали maxThreads = "1500"? Чи можете ви розмістити свою строфу для AJP 1.3 Connector (порт 8009)?
додано Автор Brian, джерело
спасибі за вказуючи це з .. немає maxThreads налаштування для AJP1.3 на всіх .. це може бути причиною?
додано Автор JZ11, джерело
1500 є те, що я на кожен tomcat екземпляр
додано Автор JZ11, джерело

Перед Apache встановіть асинхронний веб-сервер проксі, як nginx або lighttpd . Apache синхронно обслуговує вміст, тому працівники блокуються, поки клієнти не завантажують повністю створений вміст (докладніше тут ). Налаштування асинхронного (без блокування) проксі-сервера зазвичай значно покращує ситуацію (я використовував для зменшення кількості одночасно працюючих працівників Apache з 30 до 3-5, використовуючи nginx як проксі-сервер).

6
додано

Я підозрюю, що ваша проблема в tomcat не apache, з журналів ви показали в будь-якому випадку. Коли ви отримуєте "помилку 110", що намагається з'єднатися назад в tomcat, це вказує на те, що ви маєте чергу з'єднань, що очікують відправлення, що більше не може вписатися в налаштування прослуховування відставання для прослуховуючого сокета в tomcat.

From the listen manpage:
   The  backlog  parameter defines the maximum length the queue of pending 
   connections may grow to.  If a connection request arrives with
   the queue full the client may receive an error with an indication
   of ECONNREFUSED or, if the underlying protocol supports  
   retransmission, the request may be ignored so that retries succeed.

Якщо я повинен був здогадатися, я підозрюю, що переважна більшість HTTP-запитів, коли сервер "задихається", заблокований в очікуванні повернення з Tomcat. Б'юся об заклад, якщо ви спробували отримати деякий статичний вміст, який безпосередньо подається апачем (а не проксі до tomcat), що це буде працювати навіть тоді, коли його зазвичай "задихається".

Я не знайомий з tomcat на жаль, але чи є спосіб маніпулювати налаштування паралелізму цього замість?

Можливо, вам також доведеться розглянути можливість використання зовнішніх мережевих служб, які обмежують кількість з'єднань, які до яких виконують до , до 300, тому немає різниці, скільки маніпуляцій з паралелізмом ви робите на передній стороні, якщо практично кожне з'єднання, яке ви робите, спирається на відповідь зовнішніх веб-служб.

У одному з ваших коментарів згадані дані залишаються незмінними через 2 хвилини. Я пропоную кешувати відповідь, яку ви отримаєте від цієї служби протягом двох хвилин, щоб зменшити кількість одночасних з'єднань, які ви ведете до зовнішньої веб-служби.

5
додано

Першим кроком для виправлення неполадок є можливість mod_status Apache - поки ви це не зробите, насправді ви сліпо ходите. Це не справедливо. ;-)

Друга річ, про яку я маю на увазі (мені не подобається відповідати на питання, які я не запитував, але ...), використовує більш ефективні та спеціальні серверні частини, такі як nginx .

Також ви точно restart apache або просто graceful ly перезавантажено ? :)

2
додано
@johntitus, добре, mod_status - це ваш друг. :)
додано Автор poige, джерело
Apache перезавантажив .. не витончене перезавантаження
додано Автор JZ11, джерело

Для будь-якого розгортання корпоративного рівня, prefork MPM - це лише найгірший вибір, який ви можете зробити: він поглинає ресурси, як ніхто, а перезапуск потоків займає FOREVER порівняно з іншими MPM.

Принаймні перейдіть на worker (MPG) (MPEG (apache 2.2 і вище) або - ще краще - оновіть до поточної стабільної версії 2.4.2 за замовчуванням подія MPM.

Обидва з них легко оброблятимуть тисячі одночасних з'єднань з дуже невеликими накладними витратами.

1
додано
Я не погоджуюся з тим, що це найгірший вибір - це поганий вибір для цього контексту, і ймовірно, що проблеми будуть полегшені за допомогою потокового сервера, але краще було б використовувати сервер на основі подій (nginx або lighttpd). Apache, заснований на подіях, не настільки зрілий, щоб його можна було розглядати з IMHO розгортання підприємства.
додано Автор MagicAndi, джерело
спасибі .. намагався теж .. не пощастило. З’єднання TIME_WAIT продовжують зростати. Сервер перестає відповідати на 350 з'єднань
додано Автор JZ11, джерело

Я знаю, що це стара історія, але у мене є 2 зауваження.

Існує обмежений жорсткий код для директиви ServerLimit . http://httpd.apache.org/docs/2.2/mod/ mpm_common.html # serverlimit ви побачите, що це не більше 20000/200K.

Існує жорсткий ліміт ServerLimit 20000, скомпільований на сервері (для prefork MPM 200000). Це призначене для того, щоб уникнути неприємних наслідків, спричинених помилками.

2-й Очевидно, що nodybo відзначив, що встановлення цих 2 до одного є дуже поганою ідеєю :

net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

це означає, що ви повторно використовуєте час очікування рано, угадайте, що? сервер може розмовляти з неправильним клієнтом під великим навантаженням.

I found a very good article explaining that but - it is french ;-) http://vincent.bernat.im/fr/blog/2014-tcp-time-wait-state-linux.html

1
додано

дуже великий з пам'яттю в 34 Гб.

Велике залізо - це не спосіб масштабування веб-служб, ви просто рухаєте вузькі місця навколо. Але навіть з такою пам'яттю, я підозрюю, що 50000 з'єднань підштовхують те, що система здатна особливо, якщо:

У пікові години сервер задихається приблизно на 300 процесах httpd

Було б корисно, якщо ви пояснили, що ви маєте на увазі під "дроселями сервера".

Також дуже дивно мати таку високу межу для підключень, але дуже низький рівень гістерезису (мін/макс резервних серверів).

Хоча витяг наданих вами помилок не відображає «занадто багато відкритих файлів», я б подивився на кількість відкритих дескрипторів файлів і параметрів ulimit.

0
додано
Я змінив maxClients на 3000 тепер .. до цих пір те ж питання
додано Автор JZ11, джерело
Дроселі сервера, як і в ньому, не реагують навіть на звичайні HTML-файли.
додано Автор JZ11, джерело

Можливо, користувачеві Apache вичерпуються дозволені ручки файлів? Ви взагалі не згадували їх у своїй публікації. Скільки обробок файлів Apache зараз дозволено мати?

0
додано
128192 ручки файлів
додано Автор JZ11, джерело

Це більше схоже на коментар, але як не може, тому що я маю менше репутації. Прийшла через аналогічну проблему, як і у тихону @john.

Щоб вирішити цю проблему, роз'єм AJP MaxThreads був близький до ліміту нитки Apache.

Щоб відстежити це, ми шукали SYN_SENT допомога статусу порту netstat з командою netstat на нашому AJP порту.

netstat -an | grep: 8102 | grep SYN_SENT | wc -l

Це скоротилося до 0, яке завжди було деяким великим числом перед обмеженням MaxThread, встановленим на AJP Connector.

0
додано