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.