Pengaturan:
Fedora 8
Apache 2.2.8
Tomcat 5.5.8
Apache meneruskan permintaan menggunakan AJP.
Masalah:
Setelah periode waktu tertentu (tidak ada konstanta sama sekali, bisa antara satu atau dua jam, atau satu hari atau lebih) Tomcat akan turun. Entah itu berhenti merespons, atau memasang generik 'Layanan Sementara Tidak Tersedia'.
Diagnosis:
Ada dua server dengan pengaturan yang sama. Satu rumah situs web lalu lintas yang lebih tinggi (beberapa permintaan per detik), yang lain situs lalu lintas rendah (beberapa permintaan setiap beberapa menit). Kedua situs web ini adalah basis kode yang sama sekali berbeda, tetapi keduanya menunjukkan masalah yang serupa.
Di server pertama, ketika masalah terjadi, semua utas perlahan mulai terangkat hingga mencapai batas (MaxThreads 200). Pada saat itu server tidak lagi merespons (dan muncul halaman layanan yang tidak tersedia setelah jangka waktu yang lama).
Pada server kedua, ketika masalah terjadi permintaan membutuhkan waktu yang lama dan ketika mereka selesai semua yang Anda lihat adalah halaman layanan tidak tersedia.
Selain menyebutkan masalah MaxThreads, log Tomcat tidak menunjukkan masalah khusus apa pun yang dapat menyebabkan hal ini.
Namun, dalam log Apache kita melihat pesan acak yang merujuk pada AJP. Berikut contoh pesan acak yang kami lihat (tanpa urutan tertentu):
[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)
Hal aneh lain yang kami perhatikan pada server traffic yang lebih tinggi adalah bahwa tepat sebelum masalah mulai terjadi, permintaan basis data lebih lama dari sebelumnya (2000-5000 ms dibandingkan biasanya 5-50ms). Ini hanya berlangsung selama 2-4 detik sebelum pesan MaxThreads muncul. Saya berasumsi ini adalah hasil dari server yang tiba-tiba berurusan dengan terlalu banyak data / traffic / utas.
Informasi Latar Belakang:
Kedua server ini telah berjalan tanpa masalah selama beberapa waktu. Sistem sebenarnya mengatur masing-masing menggunakan dua NIC selama waktu itu. Mereka memisahkan lalu lintas internal dan eksternal. Setelah peningkatan jaringan, kami memindahkan server-server ini ke NIC tunggal (ini direkomendasikan kepada kami karena alasan keamanan / kesederhanaan). Setelah perubahan itu, server mulai mengalami masalah ini.
Resolusi:
Solusi yang jelas adalah kembali ke pengaturan dua NIC. Masalah dengan itu adalah bahwa hal itu akan menyebabkan beberapa komplikasi dengan pengaturan jaringan, dan sepertinya mengabaikan masalah. Kami lebih suka mencoba dan menjalankannya pada satu pengaturan NIC.
Menelusuri berbagai pesan kesalahan tidak memberikan apa pun yang berguna (baik solusi lama atau tidak terkait dengan masalah kami).
Kami telah mencoba menyesuaikan berbagai batas waktu tetapi itu hanya membuat server berjalan sedikit lebih lama sebelum mati.
Kami tidak yakin ke mana harus mencari untuk mendiagnosis masalah lebih lanjut. Kami masih memahami apa masalahnya:
1) Pengaturan dengan AJP dan Tomcat salah, atau ketinggalan jaman (mis. Bug yang dikenal?)
2) Pengaturan jaringan (dua NIC versus satu NIC) menyebabkan masalah kebingungan atau throughput.
3) Situs web itu sendiri (tidak ada kode umum, tidak ada platform yang digunakan, hanya kode Java dasar dengan servlets dan JSP)
Pembaruan 1:
Mengikuti saran David Pashley yang membantu, saya melakukan stack trace / thread dump selama masalah ini. Apa yang saya temukan adalah bahwa semua 200 utas berada di salah satu dari keadaan berikut:
"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]
Anehnya, hanya satu utas dari semua 200 utas yang ada di negara ini:
"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]
Mungkin saja driver Oracle di utas ini memaksa semua utas lainnya untuk menunggu sampai selesai. Untuk beberapa alasan ia harus macet dalam keadaan membaca ini (server tidak pernah pulih sendiri, itu membutuhkan restart).
Ini menunjukkan bahwa itu harus terkait dengan jaringan antara server dan database, atau database itu sendiri. Kami sedang melanjutkan upaya diagnosis, tetapi kiat apa pun akan membantu.