Skip to main content

เนื้อหาภาษาไทย / Thai content

System guide Content reviewed

การใช้ Queues และ Workers ใน PHP

บทความนี้แนะนำแนวคิดของ Queues และ Workers ใน PHP ซึ่งเป็นเครื่องมือที่มีประสิทธิภาพในการจัดการ Background Tasks เช่น การส่งอีเมลจำนวนมาก เพื่อลดผลกระทบต่อ Resp...

การใช้ Queues และ Workers ใน PHP: จัดการ Background Tasks อย่างมืออาชีพ

ในโลกของการพัฒนาเว็บแอปพลิเคชัน การจัดการงานที่ใช้เวลานาน (Long-Running Tasks) เป็นสิ่งสำคัญอย่างยิ่ง ไม่ว่าจะเป็นการส่งอีเมลจำนวนมาก, การประมวลผลรูปภาพ, หรือการดึงข้อมูลจาก API ภายนอก หากเราประมวลผลงานเหล่านี้โดยตรงใน Request/Response Cycle หลักของเว็บแอปพลิเคชัน จะทำให้ผู้ใช้งานต้องรอคอยนาน และอาจส่งผลกระทบต่อประสิทธิภาพโดยรวมของแอปพลิเคชัน

บทความนี้จะแนะนำแนวคิดของ Queues และ Workers ซึ่งเป็นเครื่องมือที่มีประสิทธิภาพในการจัดการ Background Tasks เหล่านี้ใน PHP พร้อมทั้งยกตัวอย่างการใช้งานและแนะนำ Library ที่ได้รับความนิยม

What are Queues and Workers?

Queue (คิว) คือโครงสร้างข้อมูลที่ใช้ในการเก็บรวบรวมงาน (Jobs) ที่ต้องประมวลผล โดยงานจะถูกเพิ่มเข้าไปในคิว (enqueue) และรอการประมวลผลตามลำดับ (First-In, First-Out - FIFO) เปรียบเสมือนแถวคอยในร้านอาหาร ที่ลูกค้าที่มาก่อนจะได้รับการบริการก่อน

Worker (คนงาน) คือโปรแกรมที่ทำหน้าที่ดึงงานจากคิว (dequeue) และประมวลผลงานนั้นๆ Worker จะทำงานอย่างต่อเนื่องใน Background โดยไม่รบกวนการทำงานหลักของเว็บแอปพลิเคชัน

ทำไมต้องใช้ Queues และ Workers?

  • ปรับปรุง Response Time: ลดเวลาที่ผู้ใช้งานต้องรอคอย โดยย้ายงานที่ใช้เวลานานไปประมวลผลใน Background
  • เพิ่ม Scalability: สามารถเพิ่มจำนวน Workers เพื่อรองรับปริมาณงานที่มากขึ้นได้
  • เพิ่ม Reliability: หาก Worker ล้มเหลว งานที่อยู่ในคิวยังคงอยู่ และสามารถประมวลผลใหม่ได้เมื่อ Worker กลับมาทำงาน
  • ลดภาระของ Web Server: ป้องกันไม่ให้ Web Server ต้องรับภาระในการประมวลผลงานที่ใช้เวลานาน

Implementation Examples

เพื่อให้เห็นภาพการทำงานของ Queues และ Workers เราจะยกตัวอย่างการส่งอีเมลจำนวนมาก โดยใช้ Queue ในการจัดการงานส่งอีเมล

1. สร้าง Queue:

ใน PHP เราสามารถใช้ Library ต่างๆ เพื่อสร้างและจัดการ Queue ได้ ในตัวอย่างนี้ เราจะสมมติว่าเราใช้ Library ที่มีฟังก์ชัน enqueue() ในการเพิ่มงานเข้าไปใน Queue

// สมมติว่าเรามี Library ที่จัดการ Queue
use MyQueueLibrary\Queue;

// สร้าง Queue
$emailQueue = new Queue('email_queue');

// ข้อมูลอีเมลที่จะส่ง
$emailData = [
  'to' => 'user@example.com',
  'subject' => 'Welcome to our website!',
  'body' => 'Thank you for signing up!'
];

// เพิ่มงานส่งอีเมลเข้าไปใน Queue
$emailQueue->enqueue($emailData);

echo "Email job added to the queue!\n";

2. สร้าง Worker:

Worker จะทำหน้าที่ดึงงานจาก Queue และประมวลผลงานนั้นๆ ในตัวอย่างนี้ Worker จะดึงข้อมูลอีเมลจาก Queue และส่งอีเมลจริง

// สมมติว่าเรามี Library ที่จัดการ Queue
use MyQueueLibrary\Queue;

// สร้าง Queue
$emailQueue = new Queue('email_queue');

// ฟังก์ชันสำหรับส่งอีเมล (สมมติ)
function sendEmail($emailData) {
  // โค้ดสำหรับส่งอีเมลจริง (อาจใช้ PHPMailer หรือ Library อื่นๆ)
  echo "Sending email to: " . $emailData['to'] . "\n";
  echo "Subject: " . $emailData['subject'] . "\n";
  echo "Body: " . $emailData['body'] . "\n";
  // ... โค้ดส่งอีเมล ...
  sleep(1); // จำลองการทำงานที่ใช้เวลา
  echo "Email sent!\n";
}

// Worker Loop
while (true) {
  // ดึงงานจาก Queue
  $emailData = $emailQueue->dequeue();

  // ตรวจสอบว่ามีงานใน Queue หรือไม่
  if ($emailData) {
    // ประมวลผลงาน (ส่งอีเมล)
    sendEmail($emailData);
  } else {
    // ไม่มีงานใน Queue, รอสักครู่
    echo "No email jobs in the queue. Waiting...\n";
    sleep(5); // รอ 5 วินาที
  }
}

คำอธิบาย Code:

  • $emailQueue->enqueue($emailData);: เพิ่มข้อมูลอีเมลเข้าไปใน Queue ชื่อ email_queue
  • $emailQueue->dequeue();: ดึงข้อมูลอีเมลจาก Queue
  • sendEmail($emailData);: ฟังก์ชันสำหรับส่งอีเมลจริง โดยรับข้อมูลอีเมลเป็น Argument
  • while (true): Worker Loop ที่ทำงานอย่างต่อเนื่อง
  • sleep(5);: หากไม่มีงานใน Queue Worker จะรอ 5 วินาที ก่อนที่จะตรวจสอบ Queue อีกครั้ง

3. การรัน Worker:

Worker จะต้องถูกรันใน Background โดยอาจใช้ Command Line หรือ Process Manager เช่น Supervisor

php worker.php &  # รัน Worker ใน Background

Trade-offs และแนวปฏิบัติที่ดี:

  • Serialization: ข้อมูลที่จะถูกเพิ่มเข้าไปใน Queue จะต้องสามารถ Serialize ได้ (เช่น ข้อมูลแบบ Array หรือ Object)
  • Idempotency: ออกแบบให้ Worker สามารถประมวลผลงานเดิมซ้ำได้โดยไม่ทำให้เกิดผลข้างเคียงที่ไม่พึงประสงค์ (Idempotent) ในกรณีที่ Worker ล้มเหลวระหว่างการประมวลผล
  • Error Handling: จัดการ Error ที่อาจเกิดขึ้นระหว่างการประมวลผลงานอย่างเหมาะสม เช่น การ Logging หรือการ Retry
  • Monitoring: ตรวจสอบสถานะของ Queue และ Workers อย่างสม่ำเสมอ เพื่อให้มั่นใจว่าระบบทำงานได้อย่างถูกต้อง

Popular Queue Libraries

ใน PHP มี Library หลายตัวที่ช่วยให้การใช้งาน Queues และ Workers เป็นเรื่องง่ายขึ้น ตัวอย่างเช่น:

  • Laravel Queue: เป็นส่วนหนึ่งของ Laravel Framework แต่สามารถใช้งาน Standalone ได้ รองรับ Drivers หลายรูปแบบ เช่น Redis, Database, Beanstalkd
  • Symfony Messenger: เป็น Component ของ Symfony Framework ที่ใช้ในการจัดการ Messages และ Tasks รองรับ Transports หลายรูปแบบ เช่น Doctrine, AMQP, Redis
  • Pheanstalkd: เป็น Queue Server ที่มีประสิทธิภาพสูง เหมาะสำหรับงานที่ต้องการความเร็วและความน่าเชื่อถือ
  • Redis: Redis ไม่ได้เป็น Queue Server โดยตรง แต่สามารถใช้เป็น Queue ได้โดยใช้ List Data Structure

การเลือก Library:

การเลือก Library ที่เหมาะสมขึ้นอยู่กับความต้องการของโปรเจกต์ เช่น:

  • ความคุ้นเคย: หากคุณใช้ Laravel หรือ Symfony อยู่แล้ว การใช้ Laravel Queue หรือ Symfony Messenger อาจเป็นตัวเลือกที่ดี
  • ประสิทธิภาพ: หากต้องการประสิทธิภาพสูง Pheanstalkd อาจเป็นตัวเลือกที่ดี
  • ความง่ายในการใช้งาน: หากต้องการ Library ที่ใช้งานง่าย Redis อาจเป็นตัวเลือกที่ดี

สรุป:

Queues และ Workers เป็นเครื่องมือที่สำคัญในการจัดการ Background Tasks ใน PHP ช่วยให้เว็บแอปพลิเคชันทำงานได้อย่างมีประสิทธิภาพและมีความน่าเชื่อถือมากขึ้น การเลือกใช้ Library ที่เหมาะสมและการออกแบบระบบให้รองรับการทำงานแบบ Asynchronous จะช่วยให้คุณสามารถสร้างแอปพลิเคชันที่สามารถรับมือกับปริมาณงานที่มากขึ้นได้อย่างง่ายดาย

Office.in.th Custom Service

Want to build or adapt a system from this structure?

Office.in.th designs and develops enterprise web applications, API integrations, and public- and private-sector management systems, with long-term support.

See our software development service