비동기 작업 구현하기
질문:
번거로운 비즈니스를 비동기적으로 처리하고, 주 비즈니스가 장시간 차단되는 것을 피하려면 어떻게 해야 합니까? 예를 들어 1000명의 사용자에게 이메일을 보내야 하는데 이 과정은 매우 느리고 몇 초 동안 차단될 수 있으며, 이 과정에서 주요 프로세스가 차단될 경우 후속 요청에 영향을 미칠 수 있습니다. 이러한 번거로운 작업을 다른 프로세스에게 비동기적으로 처리하려면 어떻게 해야 합니까?
답변:
지역 또는 다른 서버 심지어 서버 클러스터에 미리 번거로운 비즈니스를 처리할 몇 가지 작업 프로세스를 설정할 수 있습니다. 작업 프로세스 수를 CPU의 10배 정도 추가로 열 수 있으며, 그런 다음 호출자는 AsyncTcpConnection을 사용하여 데이터를 이러한 작업 프로세스에 비동기적으로 보내고 비동기적으로 처리 결과를 얻을 수 있습니다.
작업 프로세스 서버 측
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_data에 따라 작업 로직을 처리하여 결과를 얻음... 여기서는 생략됨....
$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는 원격 작업 서비스의 IP이며, 로컬이면 127.0.0.1, 클러스터라면 LVS의 IP입니다.
$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();
// 해당 웹소켓 클라이언트에 작업 완료 알림
$ws_connection->send('작업 완료');
};
// 비동기 연결 실행
$task_connection->connect();
};
Worker::runAll();
이렇게 하면 번거로운 작업을 로컬 또는 다른 서버의 프로세스에 맡기게 되며, 작업이 완료되면 비동기적으로 결과를 받을 수 있어서 비즈니스 프로세스가 차단되지 않습니다.