ประสิทธิภาพการปรับเซิร์ฟเวอร์ Apache โหลดสูง


12

ฉันต้องการทำความเข้าใจกับปัญหาประสิทธิภาพการทำงานของเซิร์ฟเวอร์ที่ฉันเห็นด้วย (สำหรับเรา) เว็บเซิร์ฟเวอร์ที่โหลดหนัก สภาพแวดล้อมมีดังนี้:

  • Debian Lenny (แพ็คเกจที่มีเสถียรภาพทั้งหมด + ได้รับการปรับปรุงเพื่อความปลอดภัยแล้ว)
  • Apache 2.2.9
  • PHP 5.2.6
  • Amazon EC2 อินสแตนซ์ขนาดใหญ่

พฤติกรรมที่เราเห็นคือโดยทั่วไปแล้วเว็บจะรู้สึกตอบสนอง แต่มีความล่าช้าเล็กน้อยในการเริ่มจัดการคำขอ - บางครั้งเสี้ยววินาที, บางครั้ง 2-3 วินาทีในเวลาที่เราใช้งานมากที่สุด โหลดจริงบนเซิร์ฟเวอร์จะถูกรายงานว่าสูงมาก - มัก 10.xx หรือ 20.xx topตามการรายงานของ นอกจากนี้การเรียกใช้สิ่งอื่น ๆ บนเซิร์ฟเวอร์ในช่วงเวลานี้ (แม้vi) จะช้ามากดังนั้นการโหลดจึงอยู่ที่นั่น Apache ก็ผิดปกติพอที่จะตอบสนองได้ดีนอกเหนือจากความล่าช้าครั้งแรก

เรามีการกำหนดค่า Apache ดังนี้ใช้ prefork:

StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0

และ KeepAlive เป็น:

KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 5

ดูที่หน้าสถานะเซิร์ฟเวอร์แม้ในช่วงเวลาที่มีการโหลดจำนวนมากเราไม่ค่อยได้กดปุ่มไคลเอนต์ซึ่งมักจะให้บริการระหว่างคำขอ 80-100 รายการและหลายรายการที่อยู่ในสถานะ keepalive ที่บอกให้ฉันออกกฎคำขอเริ่มต้นช้าเป็น "รอจัดการ" แต่ฉันอาจจะผิด

การตรวจสอบ CloudWatch ของ Amazon บอกฉันว่าแม้ระบบปฏิบัติการของเราจะรายงานการโหลด> 15 แต่การใช้งาน CPU ของอินสแตนซ์ของเราอยู่ระหว่าง 75-80%

ตัวอย่างผลลัพธ์จากtop:

top - 15:47:06 up 31 days,  1:38,  8 users,  load average: 11.46, 7.10, 6.56
Tasks: 221 total,  28 running, 193 sleeping,   0 stopped,   0 zombie
Cpu(s): 66.9%us, 22.1%sy,  0.0%ni,  2.6%id,  3.1%wa,  0.0%hi,  0.7%si,  4.5%st
Mem:   7871900k total,  7850624k used,    21276k free,    68728k buffers
Swap:        0k total,        0k used,        0k free,  3750664k cached

กระบวนการส่วนใหญ่มีลักษณะดังนี้:

24720 www-data  15   0  202m  26m 4412 S    9  0.3   0:02.97 apache2                                                                       
24530 www-data  15   0  212m  35m 4544 S    7  0.5   0:03.05 apache2                                                                       
24846 www-data  15   0  209m  33m 4420 S    7  0.4   0:01.03 apache2                                                                       
24083 www-data  15   0  211m  35m 4484 S    7  0.5   0:07.14 apache2                                                                       
24615 www-data  15   0  212m  35m 4404 S    7  0.5   0:02.89 apache2            

ตัวอย่างเอาต์พุตจากvmstatในเวลาเดียวกันกับด้านบน:

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 8  0      0 215084  68908 3774864    0    0   154   228    5    7 32 12 42  9
 6 21      0 198948  68936 3775740    0    0   676  2363 4022 1047 56 16  9 15
23  0      0 169460  68936 3776356    0    0   432  1372 3762  835 76 21  0  0
23  1      0 140412  68936 3776648    0    0   280     0 3157  827 70 25  0  0
20  1      0 115892  68936 3776792    0    0   188     8 2802  532 68 24  0  0
 6  1      0 133368  68936 3777780    0    0   752    71 3501  878 67 29  0  1
 0  1      0 146656  68944 3778064    0    0   308  2052 3312  850 38 17 19 24
 2  0      0 202104  68952 3778140    0    0    28    90 2617  700 44 13 33  5
 9  0      0 188960  68956 3778200    0    0     8     0 2226  475 59 17  6  2
 3  0      0 166364  68956 3778252    0    0     0    21 2288  386 65 19  1  0

และสุดท้ายผลลัพธ์จาก Apache server-status:

Server uptime: 31 days 2 hours 18 minutes 31 seconds
Total accesses: 60102946 - Total Traffic: 974.5 GB
CPU Usage: u209.62 s75.19 cu0 cs0 - .0106% CPU load
22.4 requests/sec - 380.3 kB/second - 17.0 kB/request
107 requests currently being processed, 6 idle workers

C.KKKW..KWWKKWKW.KKKCKK..KKK.KKKK.KK._WK.K.K.KKKKK.K.R.KK..C.C.K
K.C.K..WK_K..KKW_CK.WK..W.KKKWKCKCKW.W_KKKKK.KKWKKKW._KKK.CKK...
KK_KWKKKWKCKCWKK.KKKCK..........................................
................................................................

จากประสบการณ์ที่ จำกัด ของฉันฉันได้ข้อสรุป / คำถามต่อไปนี้:

  • เราอาจอนุญาตKeepAliveคำขอมากเกินไป

  • ฉันเห็นเวลาที่ใช้ในการรอ IO ใน vmstat แม้ว่าจะไม่สม่ำเสมอและไม่มาก (ฉันคิดว่าใช่ไหม) ดังนั้นฉันไม่แน่ใจว่านี่เป็นปัญหาใหญ่หรือไม่ฉันมีประสบการณ์น้อยกว่ากับ vmstat

  • นอกจากนี้ใน vmstat ฉันเห็นการทำซ้ำจำนวนหนึ่งซึ่งรอกระบวนการที่จะให้บริการซึ่งเป็นสิ่งที่ฉันอ้างถึงความล่าช้าในการโหลดหน้าเริ่มต้นบนเว็บเซิร์ฟเวอร์ของเราที่อาจผิดพลาด

  • เราให้บริการเนื้อหาแบบสแตติก (75% หรือสูงกว่า) และเนื้อหาของสคริปต์และเนื้อหาของสคริปต์มักจะมีตัวประมวลผลค่อนข้างเข้มข้นดังนั้นการค้นหาความสมดุลที่เหมาะสมระหว่างสองสิ่งนี้เป็นสิ่งสำคัญ ในระยะยาวเราต้องการย้ายสถิติที่อื่นเพื่อเพิ่มประสิทธิภาพเซิร์ฟเวอร์ทั้งสอง แต่ซอฟต์แวร์ของเรายังไม่พร้อมสำหรับวันนี้

ผมมีความสุขที่จะให้ข้อมูลเพิ่มเติมถ้าใครมีความคิดใด ๆ ที่ทราบอื่น ๆ คือที่นี้คือการติดตั้งการผลิตว่างสูงดังนั้นผมระวังในการทำบิดหลังจากที่ปรับแต่งและเป็นเหตุผลว่าทำไมผมไม่ได้เล่นกับสิ่งที่ต้องการKeepAliveค่าตัวเอง ยัง


+1 คำถามที่ยอดเยี่ยมเกี่ยวกับกระหายเลือด หวังว่าคุณจะได้รับคำตอบที่สมควร!
Dave Rix

คำตอบ:


7

ฉันจะเริ่มต้นด้วยการยอมรับว่าฉันไม่ได้เกี่ยวกับการใช้งานสิ่งต่างๆในระบบคลาวด์ - แต่จากประสบการณ์ของฉันที่อื่นฉันจะบอกว่าการกำหนดค่าเว็บเซิร์ฟเวอร์นี้สะท้อนปริมาณการเข้าชมค่อนข้างต่ำ ที่ runqueue มีขนาดใหญ่มากแสดงให้เห็นว่ามีเพียง CPU ไม่เพียงพอที่จะจัดการกับมัน มีอะไรอีกบ้างใน Runqueue?

เราอาจอนุญาตคำขอ KeepAlive มากเกินไป

ไม่ - keeplive ยังคงปรับปรุงประสิทธิภาพเบราว์เซอร์ที่ทันสมัยเป็นอย่างมากเกี่ยวกับการรู้ว่าเมื่อใดที่จะไปป์ไลน์และเมื่อใดที่จะเรียกใช้คำขอในแบบคู่ขนานแม้ว่าการหมดเวลา 5 วินาทียังค่อนข้างสูงและคุณมีเซิร์ฟเวอร์จำนวนมากรอ ฉันมีปัญหาเวลาในการตอบสนองมากฉันขอแนะนำให้ลดขนาดลงเหลือ 2-3 สิ่งนี้ควรทำให้รูนิกสั้นลงเล็กน้อย

หากคุณยังไม่ได้ติดตั้ง mod_deflate ในเว็บเซิร์ฟเวอร์ - ฉันขอแนะนำให้คุณทำ - และเพิ่ม ob_gzhandler () ลงในสคริปต์ PHP ของคุณ คุณสามารถทำสิ่งนี้เป็นการเติมอัตโนมัติ:

if(!ob_start("ob_gzhandler")) ob_start();

(ใช่การใช้งานร่วมใช้ CPU มากขึ้น - แต่คุณควรบันทึก CPU โดยรวมโดยทำให้เซิร์ฟเวอร์ออกจาก runqueue เร็วขึ้น / จัดการแพ็คเก็ต TCP น้อยลง - และเป็นโบนัสไซต์ของคุณก็เร็วขึ้นด้วย)

ฉันขอแนะนำให้ตั้งค่าขีด จำกัด สูงสุดบน MaxRequestsPerChild - พูดบางอย่างเช่น 500 สิ่งนี้อนุญาตให้มีการหมุนเวียนในกระบวนการในกรณีที่คุณมีหน่วยความจำรั่ว กระบวนการ httpd ของคุณดูเหมือนจะใหญ่มาก - ตรวจสอบให้แน่ใจว่าคุณได้ลบโมดูล apache ใด ๆ ที่คุณไม่ต้องการแล้วและตรวจสอบให้แน่ใจว่าคุณกำลังแสดงเนื้อหาแบบสแตติกพร้อมกับข้อมูลแคชที่ดี

หากคุณยังคงพบปัญหาแสดงว่าอาจเกิดจากรหัส PHP (หากคุณเปลี่ยนไปใช้ fastCGI คุณจะเห็นได้อย่างชัดเจนโดยไม่มีการลงโทษด้านประสิทธิภาพที่สำคัญ)

ปรับปรุง

หากเนื้อหาสแตติกไม่ได้แตกต่างกันมากในแต่ละหน้าอาจเป็นสิ่งที่ควรค่าแก่การทดลอง

if (count($_COOKIE)) {
    header('Connection: close');
}

ในสคริปต์ PHP ด้วย


ในบรรดาคำตอบที่ดีฉันกำลังทำเครื่องหมายนี้ว่าเป็นคำตอบที่ยอมรับได้เนื่องจากคุณระบุอย่างชัดเจนว่านี่เป็นปัญหาเกี่ยวกับ CPU (ส่วนใหญ่เกิดจากแอปพลิเคชั่นที่เราใช้งานไม่ดี) และนั่นเป็นกรณีที่แน่นอน ฉันปรับใช้ทุกอย่างกับอินสแตนซ์ 2x2 ของ EC2x2 (สูงจากใหญ่) และปัญหาส่วนใหญ่ก็หายไปแม้ว่าคุณสมบัติด้านประสิทธิภาพอื่น ๆ จะยังคงอยู่ที่นั่น เรามีแอปเดียวที่ทำงานบนเซิร์ฟเวอร์เหล่านี้และมันก็น่าเกลียด
อนาคต

4

คุณควรพิจารณาติดตั้ง reverse proxy แบบอะซิงโครนัสเนื่องจากกระบวนการจำนวนมากในสถานะ W นั้นค่อนข้างสูงเช่นกัน กระบวนการ Apache ของคุณดูเหมือนจะใช้เวลามากในการส่งเนื้อหาเพื่อชะลอลูกค้าผ่านเครือข่ายที่ถูกบล็อก Nginx หรือ lighttpd เป็นส่วนหน้าไปยังเซิร์ฟเวอร์ Apache ของคุณสามารถลดจำนวนกระบวนการในสถานะ W อย่างมาก และใช่คุณควร จำกัด จำนวนคำขอที่รักษาไว้ อาจเป็นสิ่งที่ควรค่าแก่การลองปิดใช้งาน

BTW, 107 กระบวนการ Apache สูงเกินไปสำหรับ 22 rps ฉันสามารถให้บริการ 100-120 rps โดยใช้กระบวนการ Apache เพียง 5 กระบวนการ อาจเป็นขั้นตอนต่อไปคือโพรไฟล์แอปของคุณ


ใช่เห็นด้วยอย่างแน่นอนว่าแอปพลิเคชันเป็นปัญหาส่วนใหญ่ มันได้รับการเอาต์ซอร์ซและได้รับการแก้ไขเป็นจำนวนมากและสิ่งที่ไม่ได้ทำให้แย่ลงและความพยายามในการออกแบบใหม่กำลังดำเนินอยู่ ฉันคืนนี้ลองปิด KeepAlive ไปโดยไม่มีผลกระทบจริงและขั้นตอนต่อไปของฉันคือลองใช้ reverse proxy นั่นน่าจะเป็น nginx โดยอ้างอิงจากทั้งหมดที่ฉันอ่านมา
อนาคต

ในการติดตามฉันเริ่มทดลองใช้ reverse proxy และอาจจะปรับใช้ในการผลิตในอนาคตอันใกล้ ขอบคุณ (และคนอื่น ๆ ที่แนะนำ) สำหรับแนวคิดนี้ไม่ใช่สิ่งที่ฉันเคยแก้ไขมาก่อน แต่ฉันคิดว่ามันจะส่งผลกระทบจนกว่าเราจะสามารถออกแบบใหม่ได้อย่างสมบูรณ์
อนาคต

1

คุณมีสองแถวใน vmstat ของคุณที่แสดงเวลารอคอย CPU ของคุณค่อนข้างสูงและรอบ ๆ นั้นคุณเขียนจำนวนที่ค่อนข้างยุติธรรม (io - bo) และการสลับบริบท ฉันจะดูสิ่งที่เขียนบล็อกและวิธีการกำจัดที่รอ ฉันคิดว่าการปรับปรุงส่วนใหญ่สามารถพบได้ในการปรับปรุงดิสก์ IO ของคุณ ตรวจสอบ syslog - ตั้งค่าให้เขียน async ตรวจสอบให้แน่ใจว่าแคชการเขียนของคอนโทรลเลอร์ใช้งานได้ (ตรวจสอบ - คุณอาจมีแบตเตอรี่ไม่ดี)

Keepalive ไม่ได้เป็นสาเหตุของปัญหา perf มันช่วยให้คุณประหยัดเวลาในการตั้งค่าการเชื่อมต่อหากคุณไม่ได้ใช้แคชอยู่ข้างหน้า คุณอาจชน MaxSpareServers นิดหน่อยเพื่อว่าในสถานการณ์ที่คุณไม่ได้รอส้อมทั้งหมด


ฉันไม่คุ้นเคยกับ syslog พอที่จะรู้วิธีตั้งค่าสำหรับการเขียนแบบอะซิงโครนัสภายใต้ Apache แม้ว่าฉันจะค้นหาและค้นหาสิ่งนั้นอย่างแน่นอน ฉันได้ทำการเปลี่ยนแปลงบางอย่างในคืนนี้ที่เกี่ยวข้องกับ KeepAlive และ MaxSpareServers ไม่มีผลจริงฉันเห็นด้วยที่จะทิ้งอะไหล่ไว้มากขึ้นฉันพลาดไป คุณภาพของแอปพลิเคชั่นของเรา (แย่) คือมันเขียนอย่างหนักไปยังไฟล์เซสชันผู้ใช้ (ใช่ไฟล์) ซึ่งเป็นจุดที่ฉันเริ่มคิดว่าเรากำลังทุกข์ทรมาน ฉันมีตัวเลือกในการย้ายการจัดการเซสชั่นไปยังฐานข้อมูลซึ่งฉันน่าจะลองต่อไป
อนาคต

ใช่ฉันยอมรับว่าการเขียนเซสชันของคุณเป็นสาเหตุของปัญหาคุณอาจสูญเสียการเขียนดิสก์เซสชันหากคุณใช้เซสชัน PHP - ติดตั้ง memcache และตั้งค่า session.save_handler ของ PHP เป็น memcache และ session.save_path เป็น tcp : //127.0.0.1: 11211 (หรือที่ใดก็ตามที่คุณตั้งค่า memcache) โดยค่าเริ่มต้นการบันทึกของ Apache เป็นแบบอะซิงโครนัส แต่บางครั้งเว็บแอปสามารถใช้ syslog หรือ syslog อาจเป็นช่างพูดและทำการซิงค์ทุกบรรทัด ดูเหมือนว่ามันจะไม่เป็นปัญหาสำหรับคุณ คุณสามารถใส่คำนำหน้าบรรทัดรายการไฟล์ด้วย '-' ใน syslog.conf เพื่อละเว้นการซิงค์
ถั่ว

0

คุณควรลองปิด keepalive เป็นการลองครั้งแรก ...

เมื่อประมวลผลคำขอ 107 ครั้งฉันจะรักษา MaxSpareServers ให้สูงกว่าที่คุณตั้งไว้ ...

IMHO ใน nginx ระยะยาวในฐานะ reverse proxy สำหรับเนื้อหาคงที่ควรพิจารณาด้วย


0

ข้อเสนอแนะแรก: ปิดการใช้งาน keepalives ฉันต้องการเพียงเมื่อฉันสามารถระบุสถานการณ์เฉพาะที่ประสิทธิภาพเพิ่มขึ้น แต่โดยทั่วไปคำขอ / วินาทีลดลงเมื่อเปิดใช้งาน Keepalive

ข้อเสนอแนะที่สอง: ตั้งค่า MaxRequestsPerChild ฉันก้อง symcbean ที่นี่มันจะช่วยในกระบวนการโรลโอเวอร์ในกรณีที่หน่วยความจำรั่ว 500 เป็นจุดเริ่มต้นที่ดี

คำแนะนำที่สาม: เพิ่ม MaxClients การคำนวณ ballpark สำหรับสิ่งนี้คือ (หน่วยความจำกายภาพ - หน่วยความจำที่ใช้โดยกระบวนการที่ไม่ใช่ httpd) / ขนาดของแต่ละกระบวนการ httpd ขึ้นอยู่กับวิธีรวบรวม httpd จำนวนนี้สูงสุดที่ 255 ฉันใช้ 250 สำหรับเซิร์ฟเวอร์สาธารณะของฉันเพื่อจัดการกับ google / yahoo / MS การรวบรวมข้อมูลระบบ

คำแนะนำมา: เพิ่ม MaxSpareServers: สิ่งที่ชอบ 4-5x MinSpareServers

การถอดข้อเสนอแนะเหล่านั้นล้มเหลวฉันจะดูการโหลดบาลานซ์ด้วย reverse-proxy หรือ memcache สำหรับ DB

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.