หลักการรีสตาร์ทแบบราบรื่น
อะไรคือการรีสตาร์ทแบบราบรื่น?
การรีสตาร์ทแบบราบรื่นแตกต่างจากการรีสตาร์ททั่วไป โดยการรีสตาร์ทแบบราบรื่นสามารถทำได้โดยไม่กระทบต่อผู้ใช้ เพื่อที่จะโหลดโปรแกรม PHP ใหม่ทำการอัปเดตโค้ดธุรกิจ
การรีสตาร์ทแบบราบรื่นมักจะถูกใช้ในกระบวนการอัปเดตธุรกิจหรือการเผยแพร่เวอร์ชัน ซึ่งสามารถหลีกเลี่ยงผลกระทบที่เกิดจากการรีสตาร์ทบริการเนื่องจากการเผยแพร่โค้ดที่ทำให้บริการไม่สามารถใช้ได้ชั่วคราว
หมายเหตุ
ระบบ Windows ไม่สนับสนุนการโหลดใหม่ (reload)หมายเหตุ
สำหรับธุรกิจเช่น long connection (เช่น websocket) การรีสตาร์ทแบบราบรื่นจะทำให้การเชื่อมต่อถูกตัดขาด ทางแก้ไขคือการใช้สถาปัตยกรรมที่คล้ายกับ gatewayWorker โดยมีการประมวลผลกลุ่มหนึ่งที่รับผิดชอบการเก็บรักษาการเชื่อมต่อและตั้งค่าคุณสมบัติ reloadable ของกลุ่มนี้เป็น false ในขณะที่โลจิกธุรกิจเริ่มทำงานด้วย worker processes นอกจากนี้ gateway และ worker processes จะสื่อสารกันผ่าน tcp หากธุรกิจต้องการเปลี่ยนแปลง เพียงแค่รีสตาร์ท worker processes เท่านั้น
ข้อจำกัด
หมายเหตุ: เฉพาะไฟล์ที่ถูกโหลดใน callback on{...} เท่านั้นที่จะอัปเดตอัตโนมัติหลังจากการรีสตาร์ทแบบราบรื่น ไฟล์ที่ถูกโหลดตรงๆ ในสคริปต์เริ่มต้นหรือโค้ดที่เขียนตายแล้ว จะไม่อัปเดตอัตโนมัติหากทำการโหลดใหม่
โค้ดต่อไปนี้จะไม่อัปเดตหลังจาก reload
$worker = new Worker('http://0.0.0.0:1234');
$worker->onMessage = function($connection, $request) {
$connection->send('hi'); // โค้ดที่เขียนตายแล้วไม่สนับสนุนการอัปเดตแบบร้อน
};
$worker = new Worker('http://0.0.0.0:1234');
require_once __DIR__ . '/your/path/MessageHandler.php'; // ไฟล์ที่โหลดตรงจากสคริปต์เริ่มต้นไม่สนับสนุนการอัปเดตแบบร้อน
$messageHandler = new MessageHandler();
$worker->onMessage = [$messageHandler, 'onMessage']; // สมมุติว่าในคลาส MessageHandler มีเมธอด onMessage
โค้ดต่อไปนี้จะอัปเดตอัตโนมัติหลังจาก reload
$worker = new Worker('http://0.0.0.0:1234');
$worker->onWorkerStart = function($worker) { // onWorkerStart คือ callback ที่ถูกกระตุ้นหลังจากกระบวนการเริ่มต้น
require_once __DIR__ . '/your/path/MessageHandler.php'; // ไฟล์ที่โหลดหลังจากกระบวนการเริ่มต้นสนับสนุนการอัปเดตแบบร้อน
$messageHandler = new MessageHandler();
$worker->onMessage = [$messageHandler, 'onMessage'];
};
หลังจากที่มีการเปลี่ยนแปลงใน MessageHandler.php ให้ทำการ php start.php reload เพื่อให้ MessageHandler.php ถูกโหลดใหม่ในหน่วยความจำเพื่อให้บรรลุการอัปเดตโลจิกธุรกิจ
คำแนะนำ
โค้ดข้างต้นเพื่อ方便การสาธิตใช้คำสั่งrequire_onceหากโปรเจ็กต์ของคุณสนับสนุนการโหลดอัตโนมัติ PSR-4 แล้ว ไม่มีความจำเป็นต้องเรียกใช้คำสั่งrequire_once
หลักการรีสตาร์ทแบบราบรื่น
Workerman แบ่งออกเป็นกระบวนการหลักและกระบวนการย่อย กระบวนการหลักจะรับผิดชอบในการตรวจสอบการทำงานของกระบวนการย่อย และกระบวนการย่อยจะรับผิดชอบในการรับการเชื่อมต่อจากลูกค้าและข้อมูลคำขอที่ส่งมา การทำงานที่เกี่ยวข้องและส่งคืนข้อมูลให้กับลูกค้า เมื่อมีการอัปเดตโค้ดธุรกิจ จริงๆ แล้วเราต้องอัปเดตกระบวนการย่อยเพื่อบรรลุวัตถุประสงค์ในการอัปเดตโค้ด
เมื่อกระบวนการหลักของ Workerman ได้รับสัญญาณการรีสตาร์ทแบบราบรื่น กระบวนการหลักจะส่งสัญญาณให้กระบวนการย่อยหนึ่งทำการออกอย่างปลอดภัย (ให้กระบวนการที่เกี่ยวข้องจัดการคำขอปัจจุบันจนเสร็จสิ้นก่อนที่จะออก) หลังจากที่กระบวนการนี้ออก กระบวนการหลักจะสร้างกระบวนการย่อยใหม่ (กระบวนการนี้โหลดโค้ด PHP ใหม่) จากนั้นกระบวนการหลักจะส่งคำสั่งหยุดไปยังอีกกระบวนการเก่า ทำให้กระบวนการถูกรีสตาร์ททีละหนึ่งและต่อเนื่องจนกว่ากระบวนการเก่าทั้งหมดจะถูกแทนที่
เราจะเห็นว่าการรีสตาร์ทแบบราบรื่นจริงๆ แล้วทำให้กระบวนการธุรกิจเก่าถูกละทิ้งทีละตัว และสร้างกระบวนการใหม่ทีละตัว ด้วยเหตุนี้ ในการรีสตาร์ทแบบราบรื่นจำเป็นต้องไม่เก็บข้อมูลสถานะที่เกี่ยวข้องกับผู้ใช้ในกระบวนการ ซึ่งกระบวนการธุรกิจควรเป็น stateless เพื่อหลีกเลี่ยงการสูญหายของข้อมูลเนื่องจากการออกจากกระบวนการ