Saya menjalankan situs dengan lalu lintas yang relatif rendah yang mengalami lonjakan besar pengunjung seminggu sekali setelah pembaruan situs. Selama lonjakan ini, kinerja situs sangat buruk dibandingkan dengan sisa minggu ini. Beban yang sebenarnya di server tetap sangat rendah, andal di bawah 10% CPU dan di bawah 30% RAM (perangkat keras harus benar-benar berlebihan untuk apa yang sebenarnya kita lakukan), tetapi untuk beberapa alasan Apache tampaknya tidak dapat mengatasi kuantitasnya. permintaan. Kami menjalankan apache 2.2.3 pada RHEL 5.7, kernel 2.6.18-274.7.1.el5, x86_64.
Mencoba mereproduksi perilaku ini selama jam kerja dengan ab, saya menemukan penurunan kinerja yang besar ketika melebihi sekitar 256 pengguna. Menjalankan tes dengan kasus penggunaan sekecil mungkin yang dapat saya buat dengan (file teks statis sedang diambil, total 223 byte) kinerja secara konsisten normal dengan 245 permintaan simultan:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 15 25 5.8 24 37
Processing: 15 65 22.9 76 96
Waiting: 15 64 23.0 76 96
Total: 30 90 27.4 100 125
Percentage of the requests served within a certain time (ms)
50% 100
66% 108
75% 111
80% 113
90% 118
95% 120
98% 122
99% 123
100% 125 (longest request)
Tetapi segera setelah saya ratchet hingga 265 permintaan secara bersamaan, sebagian dari mereka mulai mengambil jumlah waktu yang absurd untuk menyelesaikan:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 13 195 692.6 26 3028
Processing: 15 65 21.3 72 100
Waiting: 15 65 21.3 71 99
Total: 32 260 681.7 101 3058
Percentage of the requests served within a certain time (ms)
50% 101
66% 108
75% 112
80% 116
90% 121
95% 3028
98% 3040
99% 3044
100% 3058 (longest request)
Hasil-hasil ini sangat konsisten di berbagai proses. Karena ada lalu lintas lain menuju kotak itu, saya tidak yakin persis di mana cutoff kerasnya akan, jika ada, tetapi tampaknya mendekati 256.
Secara alami, saya berasumsi bahwa ini disebabkan oleh batas utas pada prefork, jadi saya melanjutkan dan menyesuaikan konfigurasi untuk menggandakan jumlah utas yang tersedia dan untuk mencegah kumpulan benang tumbuh dan menyusut secara tidak perlu:
<IfModule prefork.c>
StartServers 512
MinSpareServers 512
MaxSpareServers 512
ServerLimit 512
MaxClients 512
MaxRequestsPerChild 5000
</IfModule>
mod_status mengonfirmasi bahwa saya sekarang menjalankan dengan 512 utas yang tersedia
8 requests currently being processed, 504 idle workers
Namun, mencoba 265 permintaan simultan masih menghasilkan hasil yang hampir sama dengan sebelumnya
Connection Times (ms)
min mean[+/-sd] median max
Connect: 25 211 714.7 31 3034
Processing: 17 94 28.6 103 138
Waiting: 17 93 28.5 103 138
Total: 57 306 700.8 138 3071
Percentage of the requests served within a certain time (ms)
50% 138
66% 145
75% 150
80% 161
90% 167
95% 3066
98% 3068
99% 3068
100% 3071 (longest request)
Setelah menjelajahi dokumentasi (dan Stack Exchange) saya bingung untuk pengaturan konfigurasi lebih lanjut untuk mencoba mengatasi kemacetan ini. Apakah ada sesuatu yang saya lewatkan? Haruskah saya mulai mencari jawaban di luar apache? Adakah orang lain yang melihat perilaku ini? Bantuan apa pun akan sangat dihargai.
EDIT:
Sesuai saran Ladadadada, saya berlari melawan apache. Saya mencoba dengan -tt dan -T beberapa kali dan tidak dapat menemukan sesuatu yang luar biasa. Saya kemudian mencoba menjalankan strace -c terhadap semua proses apache yang sedang berjalan, dan mendapatkan ini:
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
22.09 0.317836 5 62128 4833 open
19.91 0.286388 4 65374 1896 lstat
13.06 0.187854 0 407433 pread
10.70 0.153862 6 27076 semop
7.88 0.113343 3 38598 poll
6.86 0.098694 1 100954 14380 read
(... disingkat)
Jika saya membaca ini dengan benar (dan tahan dengan saya, karena saya tidak sering menggunakan strace) tidak ada panggilan sistem yang dapat menjelaskan jumlah waktu yang dibutuhkan oleh permintaan ini. Sepertinya kemacetan terjadi sebelum permintaan bahkan sampai ke thread pekerja.
EDIT 2:
Seperti yang disarankan beberapa orang, saya menjalankan tes lagi di server web itu sendiri (sebelumnya tes dijalankan dari lokasi internet netral). Hasilnya mengejutkan:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 11 6.6 12 21
Processing: 5 247 971.0 10 4204
Waiting: 3 245 971.3 7 4204
Total: 16 259 973.3 21 4225
Percentage of the requests served within a certain time (ms)
50% 21
66% 23
75% 24
80% 24
90% 26
95% 4225
98% 4225
99% 4225
100% 4225 (longest request)
Waktu bottom-line mirip dengan tes berbasis internet, tetapi tampaknya secara konsisten menjadi sedikit lebih buruk ketika dijalankan secara lokal. Lebih menarik lagi, profilnya telah berubah secara dramatis. Padahal sebelum sebagian besar waktu permintaan berjalan lama dihabiskan di "terhubung" sekarang hambatan tampaknya dalam pemrosesan atau menunggu. Saya curiga bahwa ini mungkin sebenarnya merupakan masalah terpisah yang sebelumnya ditutupi oleh keterbatasan jaringan.
Menjalankan tes lagi dari komputer lain di jaringan lokal yang sama dengan host Apache, saya melihat hasil yang jauh lebih masuk akal:
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 2 0.8 2 4
Processing: 13 118 99.8 205 222
Waiting: 13 118 99.7 204 222
Total: 15 121 99.7 207 225
Percentage of the requests served within a certain time (ms)
50% 207
66% 219
75% 220
80% 221
90% 222
95% 224
98% 224
99% 225
100% 225 (longest request)
Kedua tes ini bersama-sama menimbulkan sejumlah pertanyaan, tetapi secara terpisah dari itu, sekarang ada kasus menarik yang harus dibuat untuk beberapa jenis kemacetan jaringan parah yang terjadi di bawah jumlah beban tertentu. Saya pikir langkah selanjutnya akan menyelidiki lapisan jaringan secara terpisah.