วิธีการดำเนินงานแบบไม่สะดุด

คำถาม:

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

ตอบ:

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

กระบวนการงานบริการดิบ

use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// งานคนงานภาระ | ใช้โพรโตคอล Text
$task_worker = new Worker('Text://0.0.0.0:12345');
// จำนวนของการทำงานงานสามารถเปิดให้มากขึ้นตามความต้องการ
$task_worker->count = 100;
$task_worker->name = 'TaskWorker';
$task_worker->onMessage = function(TcpConnection $connection, $task_data)
{
     // สมมติว่าข้อมูลที่ส่งมาเป็นJSON
     $task_data = json_decode($task_data, true);
     // ดำเนินการคำแนนตามข้อมูลงาน.... รับผลลัพธ์นี้และละเว้นส่วนนี้....
     $task_result = ......
     // ส่งผลลัพธ์
     $connection->send(json_encode($task_result));
};
Worker::runAll();

การเรียกใช้งานใน workerman

use Workerman\Worker;
use \Workerman\Connection\AsyncTcpConnection;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

// บริการผู้ใช้작เวบ
$worker = new Worker('websocket://0.0.0.0:8080');

$worker->onMessage = function(TcpConnection $ws_connection, $message)
{
    // เชื่อมต่อกับบริการงานคนงานภาระบนเครื่องไกล ที่ IP ของบริการงานคนงานภาระของเครื่องไกล ถ้าเป็นบนเครื่องของตนเองคือ 127.0.0.1 ถ้าเป็นกลุ่มอื่นๆ จะเป็น IP ของ LVS
    $task_connection = new AsyncTcpConnection('Text://127.0.0.1:12345');
    // งานและข้อมูลพาราเมตเตอร์
    $task_data = array(
        'function' => 'send_mail',
        'args'       => array('from'=>'xxx', 'to'=>'xxx', 'contents'=>'xxx'),
    );
    // ส่งข้อมูล
    $task_connection->send(json_encode($task_data));
    // รับผลลัพธ์แบบไม่สะดุด
    $task_connection->onMessage = function(AsyncTcpConnection $task_connection, $task_result)use($ws_connection)
    {
         // ผลลัพธ์
         var_dump($task_result);
         // หลังจากได้รับผลลัพธ์ อย่าลืมปิดการเชื่อมต่อแบบไม่สะดุด
         $task_connection->close();
         // แจ้งเตือนผู้ใช้ websocket ที่เกี่ยวข้องว่าการทำงานเสร็จสมบูรณ์
         $ws_connection->send('task complete');
    };
    // ดำเนินการเชื่อมต่อแบบไม่สะดุด
    $task_connection->connect();
};

Worker::runAll();

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