กรณีแปลก ๆ ของ Mr. Time To First Byte


14

ฉันมีเว็บเซิร์ฟเวอร์โดยใช้ Linode 1024 VPS

  • Ubuntu 11.10
  • Nginx 1.0.5
  • PHP 5.3.6 (ด้วย PHP-FPM, APC)
  • วานิช 3.0.2

และมีบล็อกอีกสองสามตัวที่ใช้ WordPress 3.3.1 หนึ่งในนั้นคือบล็อกธรรมดาที่มีการกำหนดค่าเริ่มต้นชุดรูปแบบและเพียงโพสต์ "Hello World" เพื่อทดสอบเซิร์ฟเวอร์ อีกบล็อกหนึ่งถูกบล็อกจากเซิร์ฟเวอร์อื่นที่มีโพสต์เกือบ 10k และมีความคิดเห็นมากกว่า 10k บล็อกนี้มีเนื้อหาที่ไม่ซ้ำกัน 5 พันรายการต่อวัน

เซิร์ฟเวอร์ให้ตัวเลขที่ดีในการทดสอบ ab สำหรับบล็อกทดสอบแต่การทดสอบเดียวกันกับบล็อกที่ทำโคลนนั้นเป็นไปไม่ได้: การทดสอบ ab โหลดเซิร์ฟเวอร์มากเกินไปและฉันต้องหยุดกระบวนการซึ่งทำให้ ab แสดงต่อไปผลลัพธ์ที่แย่มาก

ฮ็อพแสดงให้เห็นถึงการโหลด "ปกติ" เมื่ออยู่ในการทำงานปกติแต่โหลดใหญ่ผิดปกติในระหว่างการทดสอบ ab

มีสิ่งแปลกใหม่เกิดขึ้น (สำคัญที่สุดสำหรับฉัน): Time To First Byte สูงมากแต่หลังจากนั้นเว็บไซต์ก็โหลดเร็วมาก สามารถทดสอบได้อย่างง่ายดายด้วยบริการต่าง ๆ เช่น tools.pingdom.com ซึ่งให้ผลลัพธ์นี้ โปรดใส่ใจกับภูมิภาคสีเหลืองที่หมายถึง "รอเวลา"

ทำไมสิ่งนี้จึงเกิดขึ้น ความคิดที่เป็นไปได้:

  • การกำหนดค่า PHP-FPM ไม่ถูกต้อง
  • เวลาตอบสนองของ Linode DNS แย่มาก Nonsense - บล็อกทดสอบแก้ไข DNS ได้ดี TTFB นั้นยอดเยี่ยม
  • การกำหนดค่า Nginx ไม่ถูกต้อง

ในกรณีที่มีคนต้องการข้อมูลเพิ่มเติม

  • ที่นี่คุณมีไฟล์กำหนดค่าบล็อกnginxบล็อกโคลนปัจจุบัน ( /etc/nginx/sites-available/muycomputerpro.com )
  • ที่นี่คุณมีmy.cnf config ปัจจุบัน ( /etc/mysql/my.cnf ) (ฉันรู้ว่าสำหรับช่วงเวลาที่ไม่ได้แคชก็ไม่ได้สร้างความแตกต่างให้กับ TTFB ในอดีต)
  • ที่นี่คุณมีการกำหนดค่าPHP-FPM ปัจจุบัน ( /etc/php5/fpm/pool.d/www.conf )

ฉันคิดว่านี่อาจเกี่ยวข้องกับif -fคำสั่งที่คุณใช้ในlocationคอนเทนเนอร์ในการกำหนดค่า nginx จากสิ่งที่ฉันอ่านที่นี่wiki.nginx.org/Pitfallsฉันรู้สึกว่าการ-fค้นหาไฟล์ที่ไม่มีประสิทธิภาพซึ่งอาจทำให้เกิดปัญหาเกี่ยวกับไบต์ต่อครั้งแรกโดยเฉพาะอย่างยิ่งหากคุณมีไดเรกทอรีที่มีจำนวนมาก ไฟล์
d34dh0r53

1
ความคิดเล็กน้อย: ก) อะไรคือความแตกต่างจากเซิร์ฟเวอร์ดั้งเดิมที่บล็อกถูกโคลนจาก (เช่นเรียกใช้สแต็กเดียวกัน?) b) ถ้าคุณทำได้ให้รัน ab โดยตรงจากเซิร์ฟเวอร์โดยใช้ localhost และพอร์ต ลองเข้าถึงผ่านวานิชแล้วเข้าถึง nginx โดยตรง) c) เปิดใช้งานบันทึกที่ช้าของ MySQL และ PHP-FPM d) เรียกใช้ mysqltuner.pl และดูว่าคุณสามารถปรับปรุงประสิทธิภาพ MySQL ของคุณ (ซึ่งจะเป็นความแตกต่างที่ชัดเจนที่สุดระหว่างบล็อก - หรือปลั๊กอิน) e) การกำหนดค่า PHP-FPM ที่คุณโพสต์ดูเหมือนจะไม่ถูกใช้โดย nginx (/var/run/php5-fpm-tpnet.sock! = /var/run/php5-fpm-www-data.sock)
cyberx86

1
แน่นอนปัญหา PHP Wordpress ช้าจริงๆ คุณจะต้องการปลั๊กอินสำหรับแคชเพื่อรับเวลาในการโหลดที่ดีเมื่อคุณมีเนื้อหามากมาย
Martin Fjordvald

2
คุณบอกว่าคุณ 'สามารถเรียกใช้ ab บน localhost และรับ 4k req / s' - localhost ใด (ก่อนหน้า / ปัจจุบัน) ที่คุณอ้างถึง? ถ้าค่านั้นมาจากเซิร์ฟเวอร์ปัจจุบันของคุณ - ที่มี TTFB สูง - ปัญหาของคุณน่าสนใจมากขึ้น - เนื่องจากคุณกำจัด PHP, MySQL และเว็บเซิร์ฟเวอร์ของคุณได้อย่างมีประสิทธิภาพ TTFB รวมถึง DNS, เวลาในการเดินทางและเวลาในการดำเนินการ TTFB ที่ยาวมักเกิดจากการประมวลผล (เช่น PHP / MySQL) จุดที่ใช้ ab โดยตรงกับ nginx คือการกำจัดส่วนประกอบอื่น ๆ นอกจากนี้วานิชถ้าตั้งค่าถูกต้องควรข้ามแบ็กเอนด์โดยให้ค่าการตอบสนองที่สูงมาก
cyberx86

1
ดูเหมือนว่าการทดสอบในพื้นที่ของคุณไม่ถูกต้องคุณไม่ได้เรียกคืนบล็อกของคุณ สังเกตเห็นความแตกต่างในขนาดหน้า: 7500bytes เมื่อเข้าถึงจากโดเมน 151 ไบต์จาก localhost เนื่องจากคุณอาจมี virtualhost หลายตัวคุณต้องผ่านส่วนหัวของโฮสต์ไปยัง ab ab -n 1000 -c 100 -H 'Host: mysite.com' http://127.0.0.1/ที่กล่าว - ความแตกต่างในแคช (วานิช) กับผลลัพธ์ที่ไม่ได้รับการตรวจพบเพียงพอที่จะตรวจสอบตำแหน่งที่ปัญหาไม่เกี่ยวข้องกับเครือข่าย, DNS, ฯลฯ และอยู่ในการประมวลผลตามที่คาดไว้
cyberx86

คำตอบ:


24

ประการแรกนี่ไม่ใช่คำตอบมากเท่ากับวิธีการวินิจฉัย

สิ่งนี้ไม่ได้ครอบคลุมอย่างสมบูรณ์ - หรือแม้แต่สิ่งใดก็ตามที่ใกล้เคียงมันเป็นเพียงจุดเริ่มต้น

เวลาที่ไบต์แรก

เวลาเป็นไบต์แรก (TTFB) มีจำนวนคอมโพเนนต์:

  • การค้นหา DNS: ค้นหาที่อยู่ IP ของโดเมน (การปรับปรุงที่เป็นไปได้: เซิร์ฟเวอร์ DNS จำนวนมาก / กระจาย / ตอบสนองมากขึ้น)
  • เวลาในการเชื่อมต่อ: เปิดซ็อกเก็ตไปยังเซิร์ฟเวอร์เจรจาการเชื่อมต่อ (ค่าปกติควรจะประมาณเวลา 'ping' - โดยทั่วไปจำเป็นต้องไปกลับ - keepalive ควรช่วยสำหรับคำขอที่ตามมา)
  • กำลังรอ: การประมวลผลเริ่มต้นที่จำเป็นก่อนที่จะสามารถส่งไบต์แรก (ซึ่งเป็นที่ที่คุณควรปรับปรุง - มันจะมีความสำคัญที่สุดสำหรับเนื้อหาแบบไดนามิก

เมื่อคุณดูที่เอาต์พุต ApacheBench คุณจะเห็น:

  • กำลังประมวลผล: นี่คือผลรวมของการรอ + การถ่ายโอนเนื้อหาที่สมบูรณ์ (หากเวลาถ่ายโอนมีความยาวมากกว่าที่คาดว่าจะดาวน์โหลดปริมาณข้อมูลที่ได้รับการประมวลผลเพิ่มเติม (หลังจากรับไบต์แรก) เกิดขึ้น (เช่นหน้าคือ ล้างเนื้อหาตามที่มีอยู่)

การเปรียบเทียบเพื่อกำจัดองค์ประกอบ

ด้วยข้อยกเว้นเล็กน้อยปัญหาของคุณจะอยู่ในการประมวลผลส่วนหลังซึ่งมักจะเกิดขึ้นกับรหัสที่ซับซ้อน / ไม่มีประสิทธิภาพมากเกินไปหรือกำหนดค่า MySQL ไม่ดี

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

  1. ไซต์ที่เหมือนกัน (โคลน) ที่ทำงานบนเซิร์ฟเวอร์เก่าและเซิร์ฟเวอร์ใหม่:
    • ความแตกต่าง: เซิร์ฟเวอร์
    • ผลลัพธ์: เซิร์ฟเวอร์เก่าเร็ว เซิร์ฟเวอร์ใหม่ช้า
    • หมายเหตุ: สิ่งที่คุณต้องการในที่นี้คือการหาปริมาณความแตกต่างระหว่างเซิร์ฟเวอร์เหล่านี้ - ทั้งในแง่ของสแต็กที่ใช้ (Nginx, ฯลฯ ) และฮาร์ดแวร์ (เซิร์ฟเวอร์เก่าเร็วกว่าเพราะเป็นเครื่องที่ทรงพลังมากกว่าหรือไม่)
    • สรุป: รหัสอาจจะสามารถทำงานได้อย่างรวดเร็วในการตั้งค่าที่เหมาะสม
  2. ทดสอบไซต์ vs ไซต์แบบเต็มบนเซิร์ฟเวอร์ใหม่
    • ความแตกต่าง: เนื้อหาธีมปลั๊กอิน ฯลฯ
    • ผลลัพธ์: ไซต์ทดสอบเร็วไซต์เต็มช้า
    • หมายเหตุ: ตามทฤษฎีแล้วการทดสอบนี้จะช่วยให้คุณกำจัดแง่มุมต่าง ๆ ของการตั้งค่าของคุณ - DNS, เครือข่าย, แม้กระทั่งการติดตั้ง nginx / php / mysql ของคุณ - อย่างไรก็ตามมันไม่ยุติธรรมเลย
    • สรุป: เนื้อหาเพิ่มเติมกำลังส่งผลกระทบอย่างมีนัยสำคัญต่อประสิทธิภาพ

การทดสอบในอุดมคติจะให้คุณทำซ้ำไซต์แบบเต็มของคุณ แต่จากนั้นลบเนื้อหาทั้งหมดยกเว้นหนึ่งบทความและความคิดเห็นที่เกี่ยวข้อง จุดประสงค์ของการทดสอบนี้คือการพิจารณาว่าเนื้อหาจำนวนมากเป็นปัญหาหรือเกิดปัญหาด้านอื่น ๆ ของการตั้งค่าของคุณ (ปลั๊กอิน WordPress, ธีม ฯลฯ ) เป็นสาเหตุหรือไม่ คุณจะเปรียบเทียบประสิทธิภาพของเว็บไซต์ที่เหมือนกันบนเซิร์ฟเวอร์ (ใหม่) เดียวกัน - โหลดหน้าเดียวกัน (ความยาวเท่ากัน ฯลฯ ) - โดยมีความแตกต่างเพียงอย่างเดียวกับเนื้อหาเว็บไซต์ทั้งหมด (เช่นมีโอกาสดีที่ปลั๊กอินบางตัวไม่ ขยายขนาดด้วยเนื้อหาที่เพิ่มขึ้น)

มีการเปรียบเทียบอื่น ๆ ที่คุณสามารถทำได้:

  • ทดสอบจากสถานที่ห่างไกลกับท้องถิ่น - สิ่งนี้จะช่วยระบุว่าเครือข่าย, เวลาในการตอบสนอง, DNS, ฯลฯ เป็นสาเหตุหรือไม่
    • คุณได้ทำสิ่งนี้ไปแล้วและส่วนใหญ่สรุปว่าคุณไม่มีปัญหาเครือข่าย
  • ทดสอบผ่านการเคลือบเงา (เช่นพอร์ต 80) กับ nginx โดยตรง (พอร์ต 8080) - พยายามอย่าเปลี่ยนการกำหนดค่าระหว่างการทดสอบ - เพียงแค่ใช้พอร์ตที่ถูกต้อง สิ่งนี้จะแสดงให้คุณเห็นถึงผลกระทบของสารเคลือบเงา เนื่องจากวานิชนั้นเป็นเลเยอร์แคชดังนั้นจึงควรให้บริการคำขอทั้งหมดหลังจากคำขอแรกอย่างรวดเร็ว - โดยพื้นฐานแล้วควรข้ามแบ็กเอนด์และการประมวลผลที่จำเป็นในการสร้างเพจแบบไดนามิกและให้บริการแคชสำเนาอย่างรวดเร็ว
    • คุณได้ทำสิ่งนี้ (แม้ว่าไม่ใช่เฉพาะในพื้นที่) และแสดงให้เห็นว่าวานิชมีผลกระทบเชิงบวกอย่างมากต่อประสิทธิภาพการทำงานของคุณ

ปรับแบ็กเอนด์ของคุณ

ณ จุดนี้คุณควรพบปัญหาหรือสรุปว่ามันอยู่ในแบ็กเอนด์ของคุณ นั่นทำให้คุณ Nginx, PHP หรือ MySQL

(ฉันควรจะพูดถึงที่นี่ว่ามันก็มักจะมีประโยชน์ในการทราบว่าคอขวดของคุณเป็น CPU, RAM หรือ I / O - ระหว่างsar, top, iostat, vmstat, free. ฯลฯ คุณควรจะสามารถที่จะมาถึงข้อสรุปบางอย่างเกี่ยวกับเรื่องนี้)

Nginx

Nginx กำลังรับคำร้องขอและให้บริการเนื้อหาแบบคงที่หรือเปลี่ยนคำร้องขอเป็น PHP-FPM โดยปกติแล้ว Nginx จะไม่ได้รับการปรับให้เหมาะสมมากนัก

  • ตั้งคนงาน = # แกน CPU
  • เปิดใช้งาน keepalive (ค่า 10-15 ดี)
  • ปิดใช้งานการบันทึกที่ไม่จำเป็น
  • เพิ่มขนาดบัฟเฟอร์หากจำเป็น
  • หลีกเลี่ยงถ้าข้อความ (ใช้ชื่อคงที่แทนที่จะเป็น regexes ที่เป็นไปได้กำจัดส่วนขยายที่ไม่จำเป็น)

ในอุดมคติแล้วบล็อกทดสอบและบล็อกโคลนของคุณมีการกำหนดค่าเหมือนกันซึ่งในกรณีนี้คุณได้กำจัด Nginx อย่างมีประสิทธิภาพ

ใบสมัคร

ในกรณีที่คุณพยายามระบุปัญหาในรหัสของคุณ (เช่นปลั๊กอินช้าเป็นต้น) บันทึกช้าเป็นจุดเริ่มต้น

  • เปิดใช้งานการบันทึก MySQL แบบช้าและการบันทึกแบบช้าของ PHP-FPM เรียกใช้การวัดประสิทธิภาพของคุณและดูว่าอะไรจะเกิดขึ้นช้า

MySQL

  • เพิ่มแคชของคุณและเรียกใช้mysqltuner.plเพื่อรับจุดเริ่มต้นที่ดี

PHP

  • ปิดใช้งานส่วนขยายที่ไม่จำเป็น
  • ปิดการใช้งาน register_globals, magic_quotes_ *, expose_php, register_argc_argv, always_populate_raw_post_data
  • เพิ่ม memory_limit
  • open_basedir และ safe_mode มีนัยสำคัญเกี่ยวกับประสิทธิภาพ แต่ยังสามารถเพิ่มระดับการป้องกันเพิ่มเติม ทดสอบด้วยและไม่มีพวกเขาเพื่อตรวจสอบว่าผลกระทบที่มีต่อประสิทธิภาพนั้นดีหรือไม่

PHP-FPM

  • ปรับค่า pm. * - เพิ่มเพื่อจัดการกับโหลดสูง

เป็นที่น่าสังเกตว่าผลลัพธ์ htop ของคุณแสดง php-fpm ว่ากินซีพียูจำนวนมาก - และปัญหาของคุณดูเหมือนจะเกี่ยวข้องโดยตรงกับสิ่งนี้

เก็บเอาไว้

เมื่อคุณเพิ่มประสิทธิภาพคอขวดแต่ละอันแล้วให้เริ่มแคช

  • คุณมีแคช opCode (APC) อยู่แล้ว - ให้แน่ใจว่าทำงานได้ (มาพร้อมกับไฟล์ทดสอบ) - ตรวจสอบอัตราการเข้าชมแคชของคุณและถ้าเป็นไปได้ให้แคช APC ไปยังหน่วยความจำแทนไปยังดิสก์
  • ตั้งค่ารหัสของคุณเป็นแคช (เช่นใช้ปลั๊กอินสำหรับ Wordpress เช่น W3TC)
  • ด้วย nginx คุณสามารถตั้งค่าการแคช FastCGI - แต่เนื่องจากคุณมีสารเคลือบเงาสิ่งนี้จึงหลีกเลี่ยงได้ดีที่สุด
  • ตั้งค่าเลเยอร์แคชเช่น Varnish (ซึ่งคุณได้ทำไปแล้ว) - และตรวจสอบให้แน่ใจว่ามันใช้งานได้ (เช่นใช้ varnishstat อ่านเพื่อให้ได้ Hitrate ที่สูง )
  • เพิ่มการแคชเพิ่มเติมสำหรับส่วนประกอบของเว็บไซต์ของคุณ - เช่น MemCached หากทำได้

บางครั้งด้วยข้อ จำกัด ของแอปพลิเคชันและฮาร์ดแวร์ของคุณคุณอาจไม่สามารถปรับปรุงประสิทธิภาพของแบ็กเอนด์ที่มาก - อย่างไรก็ตามนั่นคือจุดของแคช - เพื่อลดการใช้แบ็กเอนด์

อ่านเพิ่มเติม


2
นั่นเป็นบทสรุปที่ยอดเยี่ยมสำหรับการวิเคราะห์ ขอบคุณมากสำหรับความคิดเห็นฉันจะพยายามทำการทดสอบอย่างหนักพร้อมกับข้อเสนอแนะทั้งหมดนี้ - บางส่วนของพวกเขาอย่างที่คุณพูดแล้วชัดเจน - และดูว่าฉันสามารถตรวจจับปัญหาได้หรือไม่ ขอแสดงความนับถือ cyberx86
javipas

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