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.
sumber
Jawaban:
Ternyata versi ini (kelas 12 - cukup tua) dari driver Oracle memiliki berbagai bug di dalamnya yang menyebabkan jalan buntu (seperti yang terlihat di negara TP-Processor2 yang dikutip di atas). Itu tidak menjadi aktif sampai kami beralih ke lingkungan baru. Memutakhirkan ke versi terbaru (ojdbc14) telah menyelesaikan masalah pada server utama.
sumber
Dari uraian, saya sarankan masalahnya mungkin karena permintaan database terlalu lama. Jika permintaan lebih lama, permintaan akan lebih lama dan karena itu Anda akan menjalankan lebih banyak permintaan sekaligus. Seperti yang Anda lihat, Anda kehabisan utas kucing jantan. Ketika Anda memecahkan masalah dengan database Anda harus baik-baik saja.
sumber
Tambahkan connectionTimeout dan keepAliveTimeout ke konektor AJP Anda yang ditemukan di /etc/tomcat7/server.xml.
Info tentang konektor AJP di https://tomcat.apache.org/tomcat-7.0-doc/config/ajp.html
connectionTimeout = Jumlah milidetik Konektor ini akan menunggu, setelah menerima koneksi, agar garis URI permintaan ditampilkan. Nilai default untuk konektor protokol AJP adalah -1 (yaitu tidak terbatas).
keepAliveTimeout = Jumlah milidetik Konektor ini akan menunggu permintaan AJP lain sebelum menutup koneksi. Nilai default adalah menggunakan nilai yang telah ditetapkan untuk atribut connectionTimeout.
Jika nilai connectionTimeout dan keepAliveTimeout tidak ditentukan, maka koneksi AJP akan tetap hidup selama tak terbatas. Menyebabkan banyak utas, utas maksimum bawaan adalah 200.
Saya merekomendasikan menginstal psi-probe - manajer canggih dan monitor untuk Tomcat Apache, bercabang dari Lambda Probe. https://code.google.com/p/psi-probe/
sumber
Karena cara kerja AJP, koneksi persisten antara apache (menggunakan mod_proxy_ajp atau mod_jk) hanya dapat ditutup dengan aman oleh klien . Dalam hal ini, klien adalah pekerja apache yang membuka, dan kemudian memegang koneksi ke kucing jantan untuk kehidupan selama proses pekerja .
Karena perilaku ini, Anda tidak dapat memiliki lebih banyak pekerja apache daripada utas pekerja kucing jantan. Melakukannya akan menyebabkan pekerja http tambahan gagal terhubung ke kucing jantan (karena antrian terima penuh) dan akan menandai backend Anda sebagai BAWAH!
sumber
Saya mendapatkan hasil yang lebih baik dengan mod_proxy daripada mod_ajp dalam hal stabilitas, jadi cobalah solusi itu. Ini non-invasif - paling-paling itu akan menyelesaikan masalah dan paling buruk itu akan menyingkirkan mod_ajp.
Selain itu, sepertinya Tomcats Anda berhenti merespons dan semua utas permintaan diikat. Mintalah tim dev Anda melihat apa yang sedang terjadi - mengambil tempat pembuangan benang dan mengirimkannya kepada mereka akan bermanfaat.
sumber
Hal pertama yang saya pikirkan ketika saya mendengar bahwa server berjalan untuk sementara waktu, tiba-tiba melambat dan kemudian mulai mengalami kegagalan layanan adalah kehabisan RAM dan meronta-ronta swap. Saya tidak jelas apakah kegagalan AJP yang Anda lihat dapat menjadi konsekuensi dari timeout, tetapi tampaknya tidak sepenuhnya tidak masuk akal; tidak melihat cara yang jelas itu akan terhubung ke NIC. Bagaimanapun, saya sarankan Anda mendapatkan gambaran tentang apa yang terjadi dengan penggunaan memori Anda ketika peristiwa ini terjadi.
Jika Anda kehabisan RAM, Anda mungkin perlu mematikan Apache
MaxClients
dan menambahListenBacklog
.Ngomong-ngomong, terima kasih telah membuat pertanyaan Anda begitu terorganisir dan lengkap.
sumber
Saya memiliki kesalahan log yang serupa di lingkungan Redhat dengan proxy_ajp dan Tomcat. Diselesaikan dengan memperbarui paket httpd:
dari:
untuk:
Kemudian restart apache, diikuti oleh restart Tomcat.
Itu memperbaikinya bagi saya!
sumber