เว็บเซิร์ฟเวอร์ Apache vs Nginx

หลังๆ มานี้เว็บเซิร์ฟเวอร์ Nginx เริ่มได้รับความนิยมมากขึ้นเรื่อยๆ (และเห็นบทความ Apache vs Nginx ออกมาเรื่อยๆ) เนื่องมาจากความเร็วและการที่มันสามารถรับการเชื่อมต่อจำนวนมหาศาลได้เป็นอย่างดี  ดังนั้นในบางสถานการณ์เราคงเริ่มตั้งคำถามกันแล้วว่าจะเลือกใช้ Apache หรือ Nginx ในการทำเว็บไซต์ดี?

Apache vs Nginx

Apache นั้นครองตลาดมาก่อน  โดยเริ่มพัฒนาตั้งแต่ในปี 1995 ทำให้มีเอกสารและชุมชนขนาดใหญ่มากที่คอยช่วยเหลือเวลาเกิดปัญหา  รวมทั้งเว็บไซต์และ CMS จำนวนมากออกแบบมาโดยอิงกับ Apache เป็นหลัก

ในปี 2002 นั้น Nginx ได้ถือกำเนิดขึ้นมา  โดยมีเป้าหมายในการแก้ไขปัญหาการเชื่อมต่อพร้อมกันจำนวนมากๆ (หลักหมื่นคอนเคอร์เรนท์) ซึ่งเริ่มมีปัญหาขึ้นเนื่องจากการเติบโตของอินเตอร์เน็ต

การจัดการการเชื่อมต่อของ Apache และ Nginx

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

Apache บน Linux จะมีวิธีจัดการการเชื่อมต่ออยู่ 3 แบบด้วยกัน โดยปกติ Apache จะเลือกขึ้นมาโดยอัตโนมัติ  ขึ้นอยู่กับว่าเซิร์ฟเวอร์รองรับหรือไม่

  1. mpm_prefork จะเป็นการสร้างโพรเซสแบบ 1 Thread ต่อ 1 Process ขึ้นมาเพื่อรองรับการเชื่อมต่อ  วิธีนี้ทำให้ Apache สามารถทำงานได้เร็วมากถ้าหากว่ามีการเชื่อมต่อจำนวนน้อย  แต่จะเริ่มมีปัญหาขึ้นมาทันทีถ้าหากว่าต้องรับกับการเชื่อมต่อจำนวนมาก  เช่นการสูบแรมจำนวนมากจากการสร้างโพรเซสย่อยขึ้นมา  หรือการที่การเชื่อมต่อจะต้องรอโพรเซสที่ว่าง  จึงจะทำงานได้อย่างไรก็ตาม mpm_prefork ยังมีข้อดีบางอย่างของมันอยู่  เช่นเมื่อถ้าทำงานร่วมกับส่วนเสริมอื่นที่ไม่ได้ออกแบบมาเป็น thread safe (เช่น mod_php) ซึ่งคือหากส่วนเสริมนั้นเกิดค้างหรือแครชลงไป  มันจะดับไปแค่โพรเซสนั้นๆ เพียงโพรเซสเดียว  ไม่ไปกวนการทำงานกับโพรเซสอื่น
  2. mpm_worker จะเป็นการสร้างโพรเซสแบบหลาย Threads ต่อ 1 Process ขึ้นมา  โดยแต่ละ Thread จะจัดการกับ 1 การเชื่อมต่อ  ทำให้การเชื่อมต่อสามารถโดดเข้ามาทำงานใน Thread ที่ว่างได้ทันที  โดยไม่ต้องรอให้โพรเซสว่างก่อน
  3. mpm_event การทำงานของมันจะเหมือนกับ mpm_worker ทุกประการ  แต่จะต่างกันในส่วนการจัดการการเชื่อมต่อแบบ keep-alive ที่โดยปกติถ้าใช้ mpm_worker ถ้าหากการเชื่อมต่อเข้ามาเป็นแบบ keep-alive การเชื่อมต่อนั้นจะจอง Thread ทิ้งไว้จนกว่าการเชื่อมต่อจะปิดลงmpm_event เข้ามาแก้ไขปัญหาตรงนี้  โดยการสร้าง Thread เฉพาะสำหรับจัดการกับการเชื่อมต่อแบบ keep-alive ขึ้นมา  และโยนการเชื่อมต่อแบบ keep-alive มาไว้ที่ Thread นี้ (mpm_event เพิ่ง stable ใน Apache 2.4)

สำหรับบน Nginx นั้นการทำงานจะคล้ายกับ mpm_event ใน Apache โดย Nginx จะสร้าง Thread ย่อยขึ้นมาเพื่อรับการเชื่อมต่อจำนวนมากๆ โดย Nginx จะกองการเชื่อมต่อต่างๆ เอาไว้ในที่เดียว  และทำงานแบบ non-blocking (คล้ายๆ กับเวลาเราเขียน Node.js) คือเมื่อมันจัดการงานหนึ่งแล้ว  มันจะโดดไปทำงานต่อไปทันทีโดยไม่รอให้งานก่อนหน้านี้ประมวลผลเสร็จก่อน  แล้วค่อยกลับมาทำต่ออีกครั้งเมื่อประมวลผลเสร็จแล้ว

การทำงานแบบนี้ทำให้ Nginx สามารถใช้ทรัพยากรได้คุ้มค่ามากกว่า  และจะเห็นผลชัดมากหากอยู่บนเซิร์ฟเวอร์ที่มีทรัพยากรค่อนข้างจำกัดจำเขี่ย

โมดูลเสริม

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

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

การทำงานร่วมกับเนื้อหาแบบ Dynamic

ในกรณีนี้จะขอยกตัวอย่างเป็น PHP นะครับ  ซึ่งโดยปกติแล้วทั้ง Apache และ Nginx โดยตัวของมันมีหน้าที่สำหรับส่งเนื้อหามายังไคลเอ็นท์เท่านั้น  ตัวมันเองไม่สามารถประมวลผลโค๊ดภาษาต่างๆ (เช่น PHP) ได้เลย

ทางฝั่ง Apache นั้นใช้ประโยชน์จากระบบโหลดโมดูลแบบไดนามิคในการโหลดโมดูล PHP เข้ามาทำงานใน Apache ได้ในทันที  ในขณะที่ Nginx นั้น PHP จะทำงานผ่านโมดูล FastCGI อีกทีหนึ่ง  ซึ่งจะได้ Performance ที่ช้ากว่า mod_php ของ Apache ที่ทำงานแบบ Native

จริงๆ แล้วถ้าเราถึกพอ  ผมว่าเราน่าจะสามารถเขียนโมดูล PHP ให้ Nginx ได้เช่นกัน  แต่ว่าทุกครั้งที่เราจะอัพเดท PHP เราจะต้องคอมไพล์ Nginx ใหม่ทุกครั้ง  เทียบกับ Apache ที่เราสามารถอัพเดท PHP แยกได้ทันที

การตั้งค่าการทำงาน

รูปแบบการตั้งค่าการทำงานของ Apache และ Nginx ถือเป็นอีกปัจจัยหนึ่งที่ทำให้เว็บเซิร์ฟเวอร์ทั้งสองตัวมีความเร็วต่างกันอย่างเห็นได้ชัด

ใน Apache เราคงคุ้นเคยกันดีกับไฟล์ .htaccess ที่สามารถเอาไปโยนแปะในไดเรคทอรี่ต่างๆ ที่ต้องการ  ซึ่งการที่ Apache รองรับไฟล์ .htaccess แบบนี้  ทำให้มันจะต้องสแกนไดเรคทอรี่ทั้งหมดเพื่อหาไฟล์ .htaccess และประมวลผลการตั้งค่าต่างๆ ก่อนที่จะเริ่มทำงานของมันจริงๆ  ทำให้ Apache นั้นต้องทำงานหนักขึ้นและกินทรัพยากรมากขึ้นนั่นเอง

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

อย่างไรก็ตามใน Apache สามารถปิดการทำงานของ .htaccess ได้เช่นกัน  โดยการสั่ง AllowOverride None ในไฟล์ vhost (ผมก็ใช้วิธีนี้  ปิด AllowOverride และไปตั้ง Rewrite Rule ลงในไฟล์ vhost โดยตรง)

ทางออกยอดนิยม: ใช้ทั้งคู่ผสมกัน

ทั้ง Apache และ Nginx นั้นมีข้อดีและข้อเสียต่างกันไป  ดังนั้นทางออกยอดนิยมที่หลายคนมักจะเลือกกันก็คือนำทั้งตัวมาใช้งานร่วมกันเสียเลย  โดยใช้ข้อดีของ Nginx คือรับการเชื่อมต่อจำนวนมากได้ดี  มาทำหน้าที่เป็น Reverse Proxy คอยรับการเชื่อมต่อทั้งหมดจาก Client โดยเมื่อพบว่า Client เรียกหา Static Content ก็จะจัดการส่งเนื้อหานั้นๆ ไปให้ Client โดยตรง  หรือหากเป็นการเรียกหา Dynamic Content (เช่น PHP) ก็จะส่งต่อไปให้ Apache ประมวลผล (เพราะ Apache สามารถประมวลผล PHP ได้เร็วกว่าผ่าน mod_php) และส่งผลลัพธ์กลับมา Nginx ก่อนจะส่งกลับ Client ต่อไป

สรุปส่งท้าย

ทั้ง Apache และ Nginx ล้วนเป็นเว็บเซิร์ฟเวอร์ที่มีความสามารถสูงทั้งคู่  คำถามว่า Apache vs Nginx นั้นใช้อะไรดีกว่ากันก็คงยังหาคำตอบที่แน่นอนไม่ได้ต่อไป  ดังนั้นแล้วการจะเลือกเว็บเซิร์ฟเวอร์สักตัว  เราควรจะเลือกจากว่างานของเรานั้นต้องการความสามารถแบบไหน  จะเอามาใช้ตัวใดตัวหนึ่ง  หรือนำมันมาใช้ร่วมกัน

เรียบเรียงจาก https://www.digitalocean.com/community/tutorials/apache-vs-nginx-practical-considerations

Posted by Jirayu

WordPress Developer ที่พอมีประสบการณ์อยู่บ้าง วันไหนไม่ทำงานอยู่บ้านว่างๆ ก็นั่งเลี้ยงแมว

Comments