Apache + Tomcat iletişim kurmakta zorlanıyor. Net olmayan hata mesajları. Tomcat’te barındırılan web sitelerini aşağı getirmek


22

Kurulum:
Fedora 8
Apache 2.2.8
Tomcat 5.5.8
Apache, AJP kullanarak istekleri iletiyor.

Sorun:
Belli bir süre sonra (hiç bir şekilde sabit değil, bir veya iki saat arasında olabilir veya bir veya daha fazla gün) Tomcat iner. Ya yanıt vermeyi durdurur ya da 'Hizmet Geçici Olarak Kullanılamıyor' servisini başlatır.

Teşhis:
Aynı kurulumu yapan iki sunucu var. Biri daha yüksek trafikli bir web sitesine (saniyede birkaç istek), diğeri düşük trafikten (birkaç dakikada bir birkaç istek) ev sahipliği yapıyor. Her iki web sitesi tamamen farklı kod tabanlarıdır, ancak benzer sorunları da göstermektedirler.

İlk sunucuda, sorun oluştuğunda, tüm iş parçacıkları yavaşça sınıra ulaşana kadar alınmaya başlar (MaxThreads 200). Bu noktada, sunucu artık yanıt vermiyor (ve uzun süre sonra hizmet kullanılamayan bir sayfayla çıkıyor).

İkinci sunucuda, sorun gerçekleştiğinde istekler uzun zaman alır ve tek yaptıkları hizmet kullanılamayan sayfadır.

MaxThreads sorununun belirtilmesi dışında, Tomcat günlükleri buna neden olabilecek herhangi bir özel sorunu belirtmemektedir.

Ancak, Apache günlüklerinde AJP'ye gönderme yapan rastgele mesajlar görüyoruz. İşte gördüğümüz rastgele bir mesaj örneği (belirli bir düzende değil):

[error] (70007)The timeout specified has expired: ajp_ilink_receive() can't receive header
[error] (104)Connection reset by peer: ajp_ilink_receive() can't receive header
[error] proxy: AJP: disabled connection for (localhost)
[error] ajp_read_header: ajp_ilink_receive failed
[error] (120006)APR does not understand this error code: proxy: read response failed from 127.0.0.1:8009 (localhost)
[error] ap_proxy_connect_backend disabling worker for (localhost)

Daha yüksek trafik sunucusunda fark ettiğimiz diğer tuhaf olan şey, sorun oluşmadan hemen önce, veritabanı sorgularının öncekinden çok daha uzun sürdüğüdür (2000-5000 ms ve normal olarak 5-50ms). Bu, MaxThreads mesajı gelmeden önce sadece 2-4 saniye sürer. Bunun birdenbire çok fazla veri / trafik / iş parçacığıyla ilgili sunucunun bir sonucu olduğunu farz ediyorum.

Arka Plan Bilgileri:
Bu iki sunucu bir süredir sorunsuz çalışıyordu. Sistemler aslında her biri iki NIC kullanarak bu süre zarfında kuruldu. İç ve dış trafiği ayırdılar. Bir ağ yükseltmesinden sonra, bu sunucuları tek NIC’lere taşıdık (güvenlik / basitlik nedeniyle bize önerildi). Bu değişiklikten sonra sunucular bu problemlerle karşılaşmaya başladı.

Çözüm:
Açık bir çözüm, iki NIC kurulumuna geri dönmek olacaktır. Bununla ilgili problemler, ağ kurulumunda bazı komplikasyonlara neden olacağı ve problemi görmezden geldiği gibi görünüyor. Tek bir NIC kurulumunda çalıştırmayı denemeyi tercih ederiz.

Çeşitli hata mesajlarına göz atmak yararlı bir şey sağlamadı (eski çözümler ya da sorunumuzla ilgisi yok).

Çeşitli zaman aşımlarını ayarlamayı denedik ancak bu, sunucuyu ölmeden önce biraz daha uzun çalıştırmaya başladı.

Sorunu daha yakından tanımak için nereye bakacağımızdan emin değiliz. Sorunun ne olabileceğine dair hala pipet tutuyoruz:

1) AJP ve Tomcat ile yapılan kurulum yanlış veya modası geçmiş (yani bilinen hatalar?)
2) Ağ kurulumu (bir NIC'e karşı iki NIC) karışıklığa veya çıkış sorunlarına neden oluyor.
3) Web sitelerinin kendileri (ortak kod yoktur, platform kullanılmaz, sunucu sunucuları ve JSP içeren basit Java kodu kullanılır)

Güncelleme 1:
David Pashley'nin yararlı tavsiyesinin ardından, sorun sırasında bir yığın izi / iş parçacığı dökümü yaptım. Bulduğum şey, 200 ipliğin hepsinin aşağıdaki durumlardan biri olduğuydu:

"TP-Processor200" daemon prio=1 tid=0x73a4dbf0 nid=0x70dd waiting for monitor entry [0x6d3ef000..0x6d3efeb0]
at  oracle.jdbc.pool.OracleConnectionCacheImpl.getActiveSize(OracleConnectionCacheImpl.java:988)
- waiting to lock <0x7e3455a0> (a oracle.jdbc.pool.OracleConnectionCacheImpl)
[further stack trace removed for brevity]

"TP-Processor3" daemon prio=1 tid=0x08f142a8 nid=0x652a waiting for monitor entry [0x75c7d000..0x75c7ddb0]
at oracle.jdbc.pool.OracleConnectionCacheImpl.getConnection(OracleConnectionCacheImpl.java:268)
- waiting to lock <0x7e3455a0> (a oracle.jdbc.pool.OracleConnectionCacheImpl)
[further stack trace removed for brevity]

Tuhaf bir şekilde, tüm 200 ipliğin sadece bir dişi bu durumdaydı:

"TP-Processor2" daemon prio=1 tid=0x08f135a8 nid=0x6529 runnable [0x75cfe000..0x75cfef30]
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at oracle.net.ns.Packet.receive(Unknown Source)
at oracle.net.ns.DataPacket.receive(Unknown Source)
at oracle.net.ns.NetInputStream.getNextPacket(Unknown Source)
at oracle.net.ns.NetInputStream.read(Unknown Source)
at oracle.net.ns.NetInputStream.read(Unknown Source)
at oracle.net.ns.NetInputStream.read(Unknown Source)
[further stack trace removed for brevity]

Bu konudaki Oracle sürücüsünün, diğer tüm iş parçacıklarının tamamlanmasını beklemesi için zorlaması olabilir. Bazı nedenlerden dolayı bu okuma durumunda sıkışmış olması gerekir (sunucu asla kendi kendine kurtarılmaz, yeniden başlatmayı gerektirir).

Bu, sunucu ile veritabanı arasındaki ağla veya veritabanının kendisiyle ilişkili olması gerektiğini gösterir. Teşhis çabalarına devam ediyoruz, ancak herhangi bir ipucu yardımcı olacaktır.


Öncelikle, bu oldukça yazılı bir soru. Detaylarda fantastik bir iş! İkincisi, Apache ve Tomcat sunucularını bağlamak için proxy_ajp veya mod_jk kullanıyor musunuz?
Ophidian

İkisini bağlamak için proxy_ajp kullanıyorum.
Jordy Boom

Kuşatma, joedog.org/siege-home kullanarak stres testleri yapın .
paalfe

Yanıtlar:


9

Oracle sürücüsünün bu sürümünün (sınıf 12 - oldukça eski), içinde bir kilitlenmeye neden olan ve (yukarıda belirtilen TP İşlemci2 durumunda görüldüğü gibi) çeşitli hatalara sahip olduğu ortaya çıktı. Yeni ortama geçene kadar aktif olmadı. En son sürüme yükseltme (ojdbc14), birincil sunucudaki sorunu çözdü.


Bu beni doğru çözüm yoluma yönlendirdi : Bir DB-satırına kilitlendim ... ve App-Server'da hiç bir istisna
almadım

6

Açıklamadan, problemin çok uzun süren veritabanı sorguları nedeniyle olabileceğini öneriyorum. Sorgular daha uzun sürüyorsa, istek daha uzun sürecektir ve bu nedenle bir kerede daha fazlasını yayınlayacaksınız. Gördüğünüz gibi, tomcat ipliklerinden bitiyorsunuz. Veritabanındaki sorunu çözdüğünüzde sorun değil.

  • Jstack kullanarak veya kill -3 $ process_id kullanarak bir yığın izlemesi alın. İpliklerinizin öldüğünde ne yaptığını görün. Hepsi veritabanında bekliyorlarsa, bu benim teorim için iyi bir işaretçi. Hepsi bir kilit bekliyor olabilir.
  • LambdaProbe'ı yükleyin. Tomcat'in ne yaptığını bulmak çok değerli.
  • Tomcat'inizi yükseltin. 5.5.8 inanılmaz derecede eski. Sanırım şimdi 5.5.27'de.

David, konu dökümü / yığın izleme önerinize dayanan yeni bulgularla soruyu güncelledim (bkz. Güncelleme 1).
Jordy Boom

Veri tabanı bağlantı havuzunuzun tomcat max bağlantı değerinize göre çok küçük olduğunu öneriyorum. Görünüşe göre çoğu konu bir veritabanı bağlantısı almak için bekliyor.
David Pashley

Bunun birçok nedeni, normalde kullanılan iş parçacıklarının soketten okumaya çalışan bir iş parçacığı için bekletilmeleridir. Herhangi bir zamanda kullanılan DB bağlantılarının sayısı 1 ile 3 arasındadır. Asla bu kadar fazlasına ihtiyaç duyulmaz.
Jordy Boom

5

ConnectionTimeout ve keepAliveTimeout'u /etc/tomcat7/server.xml içinde bulunan AJP konektörünüze ekleyin.

<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" 
           connectionTimeout="10000" keepAliveTimeout="10000" />

Https://tomcat.apache.org/tomcat-7.0-doc/config/ajp.html adresindeki AJP konektörü hakkında bilgi

  • connectionTimeout = Bu Bağlayıcının, bir bağlantıyı kabul ettikten sonra, talep edilen URI hattının sunulması için bekleyeceği milisaniye sayısı. AJP protokolü bağlayıcıları için varsayılan değer -1'dir (sonsuzdur).

  • keepAliveTimeout = Bu Bağlayıcının bağlantıyı kapatmadan önce başka bir AJP isteğini bekleyeceği milisaniye sayısı. Varsayılan değer, connectionTimeout özniteliği için ayarlanmış olan değeri kullanmaktır.

ConnectionTimeout ve keepAliveTimeout değerleri tanımlanmazsa, AJP bağlantıları sonsuz olarak canlı tutulur. Birçok konuya bağlı olarak, varsayılan maksimum konu sayısı 200'dür.

Lambda Probundan çatallanan Apache Tomcat için gelişmiş bir yönetici ve monitör olan psi-probe'u kurmanızı öneririm. https://code.google.com/p/psi-probe/


4

AJP'nin çalışma şekli nedeniyle, apache arasındaki kalıcı bağlantılar (mod_proxy_ajp veya mod_jk kullanılarak) yalnızca istemci tarafından güvenli bir şekilde kapatılabilir . Bu durumda, müşteri açılan apache çalışanıdır ve çalışan işlemin ömrü boyunca tomcat'la bir bağlantı kurar .

Bu davranış nedeniyle, tomcat çalışanının iş parçacığından daha fazla apache işçiniz olamaz. Bunu yapmak, ek http çalışanlarının tomcat'e bağlanamamasına neden olur (kabul sırası dolduğu için) ve arka ucunuzu AŞAĞI olarak işaretler!


1
Bunca yıldan bu yana yapılan yorum için üzgünüm, ancak ProxyPass yapılandırmasındaki maksimum bayrağı, sunucu kabının MaxThreads sayısına ayarlayarak bu garanti edilemez mi?
Horst Gutmann

2

Kararlılık anlamında mod_ajp yerine mod_proxy ile daha iyi sonuçlar aldım, o yüzden bu çözümü deneyin. İstilacı değil - en iyi ihtimalle sorunu çözecek ve en kötüsü mod_ajp'ı ekarte edecek.

Bunun dışında, Tomcats'niz gibi sesler yanıt vermiyor ve tüm istek iş parçacıkları bağlı. Geliştirme ekibinize neler olup bittiğini araştırın - bir iş parçacığı dökümü alıp onlara teslim etmek faydalı olacaktır.


Mod_proxy'nin bağlanması daha kolay olmasına rağmen bazı ölçeklenebilirlik sorunları olduğu izlenimindeydim. Apache vakfının mod_jk ( wiki.apache.org/tomcat/FAQ/Connectors#Q2 )
Ophidian

Yapışkan bir tutku sağlamaz, doğru. Ama bunun dışında hiçbir zaman sorun yaşamadım.
Robert Munteanu

1

Bir sunucunun bir süre çalıştığını duyduğumda düşündüğüm ilk şey, aniden yavaşlıyor ve ardından servis arızalarına başlıyor olması, RAM'in tükenmesi ve takas değişimine neden olmasıdır. Gördüğünüz AJP başarısızlıklarının zaman aşımına uğramasına neden olup olmayacağı konusunda net değilim, ancak bu tamamen mantıksız görünmüyor; Yine de, NIC ile bağlantı kuracak açık bir yol görmüyorum. Her halükarda, bu olaylar meydana geldiğinde bellek kullanımınızla ilgili neler olduğuna dair bir resim çekmenizi öneriyorum.

RAM'iniz tükeniyorsa, Apache'nizi düşürmeniz MaxClientsve cihazınızı artırmanız gerekebilir ListenBacklog.

Bu arada, sorunuzu çok iyi organize ve eksiksiz hale getirdiğiniz için teşekkür ederiz.


Bu olurken top top ’engellediğimde, bellek kullanımı oldukça tutarlı kalıyor. En azından çiviler yok. İşlemci kullanımının sadece kısa bir anı var.
Jordy Boom 19

1

Proxy_ajp ve Tomcat ile Redhat ortamında benzer günlük hataları vardı. Httpd paketini güncelleyerek çözüldü:

yum update httpd

dan:

  • httpd-devel-2.2.3-43.el5_5.3.x86_64
  • httpd-2.2.3-43.el5_5.3.x86_64

için:

  • httpd-2.2.3-45.el5_6.3.x86_64
  • httpd-devel-2.2.3-45.el5_6.3.x86_64

Sonra apache'yi yeniden başlattıktan sonra Tomcat'i yeniden başlattık.

Bu benim için sorunumu çözdü!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.