Bagaimana cara debug timeout apache?

13

Saya menjalankan aplikasi web PHP di server Apache 2.2 (Ubuntu Server 10.04, 8x2GHz, 12Gb RAM) menggunakan prefork. Setiap hari Apache mendapat sekitar 100rb-200rb permintaan, dari sekitar 100-200 ini mencapai batas batas waktu (jadi sekitar satu dari setiap seribu), hampir semua permintaan lainnya dilayani jauh di bawah batas waktu.

Apa yang bisa saya lakukan untuk mencari tahu mengapa ini terjadi? Atau apakah normal jika sebagian kecil dari semua permintaan habis?

Inilah yang telah saya lakukan sejauh ini:

Meminta waktu respons

Seperti dapat dilihat, ada sangat sedikit permintaan yang berada di antara batas waktu habis dan permintaan yang lebih masuk akal. Saat ini batas batas waktu diatur ke 50 detik, sebelumnya ditetapkan ke 300 dan itu masih situasi yang sama dengan beberapa batas waktu dan kemudian kesenjangan besar ke permintaan lainnya.

Semua permintaan yang keluar adalah AJAXpermintaan, tetapi sebagian besar dari mereka adalah, jadi mungkin itu lebih merupakan kebetulan. Kode pengembalian Apache adalah 200, tetapi batas waktu habis jelas tercapai. Mereka berasal dari berbagai IP yang berbeda.

Saya telah melihat permintaan yang keluar dan tidak ada yang istimewa tentang mereka, jika saya melakukan permintaan yang sama dengan yang mereka lakukan dalam waktu kurang dari sedetik.

Saya sudah mencoba melihat sumber yang berbeda untuk melihat apakah saya dapat menemukan penyebabnya tetapi tidak berhasil. Selalu ada banyak memori bebas (minimum adalah sekitar 3GB gratis), kadang-kadang memuat setinggi 1,4 dan pemanfaatan CPU hingga 40%, tetapi banyak dari timeout terjadi ketika beban dan pemanfaatan CPU rendah. Disk write / read cukup konstan sepanjang hari. Tidak ada entri dalam log permintaan lambat MySQL (setel untuk mencatat apa pun di atas 1 detik), permintaan tidak menggunakan yang banyak ditulis / dibaca oleh database.

Minta waktu respons dengan beban sistem / cpu

Biru adalah pemanfaatan CPU, yang memuncak pada 40%, merah marun adalah beban dengan puncak pada 1,4. Jadi kita bisa melihat kita mendapatkan timeout bahkan dengan utilisasi / beban CPU yang rendah (sepuluh detik lonjakan sesuai dengan utilisasi CPU, tapi itu masalah lain, saya memiliki harapan yang lebih tinggi untuk mencari tahu apa yang menyebabkannya).

Tidak ada kesalahan dalam log kesalahan Apache dan saya belum melihatnya mencapai lebih dari 200 proses Apache aktif.

Pengaturan Server:

Timeout 50 
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 2

<IfModule mpm_prefork_module>
    ServerLimit     350
    StartServers        20
    MinSpareServers     75
    MaxSpareServers     150
    MaxClients          320
    MaxRequestsPerChild 5000
</IfModule>

Memperbarui:

Saya memperbarui ke Ubuntu 12.04.1, untuk berjaga-jaga, tidak ada perubahan. Saya menambahkan mod_reqtimeout dengan pengaturan:

RequestReadTimeout header=20-40,minrate=500
RequestReadTimeout body=10,minrate=500

Sekarang hampir semua timeout terjadi pada 10 detik, satu atau dua pada 20 detik. Saya menganggap itu berarti bahwa sebagian besar waktu itu mendapatkan tubuh permintaan yang bermasalah untuk menerima? Badan permintaan tidak boleh lebih besar dari beberapa ratus byte. Saya telah memonitor lalu lintas jaringan setiap 1 detik dan tidak pernah lebih tinggi dari 1Mbit / s dan saya tidak melihat rxerrs atau rxdorps, mengingat server berada pada jalur 1Gbit / s tidak terdengar seperti HopelessN00b memposting tentang. Mungkinkah itu hanya kasus beberapa koneksi pengguna yang buruk?

Untuk lonjakan setiap jam (mereka tampaknya sedikit melayang, dalam grafik di atas mereka berada di 33 menit melewati jam, sekarang mereka di 12 menit terakhir), saya sudah mencoba untuk melihat apakah ada sesuatu yang berjalan secara berkala ( crons dll) tetapi tidak menemukan apa pun. Pengumpulan sampah PHP berjalan dua kali setiap jam, tetapi tidak pada saat paku, masih saya sudah mencoba menonaktifkannya tetapi tidak ada bedanya.

Saya telah menggunakan dstat dengan --top-cpu dan top untuk melihat proses pada saat lonjakan dan semua yang muncul adalah apache yang bekerja keras selama beberapa detik tetapi tidak ada proses lain yang menggunakan cpu yang signifikan.

Saya telah membuat grafik yang diperbesar dari paku: Waktu respons permintaan yang diperbesar

Bagi saya sepertinya apache berhenti selama beberapa detik dan kemudian bekerja keras untuk memproses permintaan yang masuk selama penghentian. Apa yang dapat menyebabkan penghentian seperti itu, atau saya salah menafsirkannya?

Leon
sumber
1
Saya ingin memposting dengan beberapa grafik di atas permintaan, tetapi perwakilan saya terlalu rendah.
Leon

Jawaban:

4

Hal pertama yang saya perhatikan, melihat grafik pertama Anda, tampaknya ada perlambatan per jam (terjadi sekitar 40 menit melewati jam) yang mungkin berkontribusi terhadap masalah. Anda harus melihat penjadwal tugas pada OS / database.

Berdasarkan data yang Anda berikan, langkah saya berikutnya adalah melihat frekuensi waktu respons (jumlah respons pada sumbu Y vs durasi pada X) tetapi hanya menyertakan URL yang menunjukkan batas waktu (atau lebih disukai satu URL pada suatu waktu ). Pada sistem tipikal ini harus mengikuti distribusi normal atau poisson - permintaan yang waktunya habis mungkin hanya menjadi bagian dari ekor - dalam hal ini Anda perlu memfokuskan upaya Anda pada penyetelan umum. OTOH jika distribusinya adalah bi-modal maka Anda perlu mencari pertengkaran di suatu tempat dalam kode Anda.

symcbean
sumber
Terimakasih atas tanggapan Anda. Saya mencari tahu apa yang mungkin menyebabkan perlambatan per jam. Sementara itu saya membuat plot frekuensi dari data yang sudah saya miliki. Ini hanya salah satu URL yang memiliki masalah batas waktu (tetapi yang lain terlihat sangat mirip): leela.kikora.no/apache_hist_show.png Jumlah batas waktu sangat kecil dibandingkan dengan yang membutuhkan waktu kurang dari 10 detik, tetapi tampaknya seperti itu mungkin bukan bagian dari ekor. Tapi di sisi lain bisa jadi itu karena mereka mewakili apa pun yang membutuhkan waktu 50 + detik, itu seharusnya terlihat seperti ini.
Leon
3

Saya punya pemikiran lain tentang ini, berdasarkan pada kenyataan bahwa Anda mendapatkan sejumlah besar permintaan per hari, dan tampaknya memiliki batas waktu hanya selama jam sibuk (dari gambar yang Anda posting).

Ada posting di blog Server Fault,Per Second Measurements Don't Cut It ... mungkinkah beberapa permintaan ini mengalami masalah yang sama dengan yang dialami oleh tim ServerFault?

Kami menemukan bahwa kami sering membuang paket pada antarmuka 1 Gbit / s dengan kecepatan hanya 10-30 MBit / s yang mengganggu kinerja kami. Ini karena laju 10-30 MBit / s sebenarnya jumlah bit yang ditransfer per 5 menit yang dikonversi menjadi laju satu detik. Ketika kami menggali lebih dekat dengan Wireshark dan menggunakan grafik IO satu milidetik, kami melihat bahwa kami sering meledakkan tingkat 1 Mbit per milidetik dari apa yang disebut antarmuka 1 Gbit / s.

HopelessN00b
sumber
Menarik, saya akan melihatnya. Saya telah mengaktifkan mod_reqtimeout dan mengaturnya ke header RequestReadTimeout = 20-40, minrate = 500 dan tubuh RequestReadTimeout = 10, minrate = 500 dan hampir semua timeout terjadi pada 10 detik sekarang. Saya menganggap itu berarti bahwa tubuh permintaan membutuhkan waktu terlalu lama (tubuh tidak boleh lebih dari beberapa ratus byte paling banyak) sehingga beberapa pengguna saya memiliki koneksi yang buruk atau seperti yang Anda katakan ada beberapa kemacetan di sisi server saya.
Leon