현재 웹 프론트 엔드의 병렬 작업/요청을 처리하는 기어 맨을 테스트 중입니다. 기어맨 클린트는 Ajax를 통해 게시 매개 변수로 요청을 수신 한 다음 작업을 생성하고 gearman worker에게 보냅니다. 동시에 여러 클라이언트의 다중 요청을 처리하기 위해 21 개의 작업자 프로세스 인스턴스가 실행됩니다. 한 번에 하나의 클라이언트 요청으로 모든 것이 잘 작동하지만, 동시에 여러 클라이언트가 요청할 경우 클라이언트는 요청한 정보에 대해 잘못된 결과를 얻습니다. 예를 들어 클라이언트 A가 customer_id 123에 대한 정보를 요청하고 클라이언트 B가 customer_id 456에 대한 정보를 요청하고 동시에 두 요청이 모두 실행되면 클라이언트 A는 클라이언트 B의 결과를 얻고 클라이언트 B는 클라이언트 A의 결과를 얻습니다. 다른 근로자의 기능을 분리하지만 동일한 문제가 존재합니다. 내 코드에서 문제를 찾을 수 있도록 도와주세요.기어맨 PHP 병렬 작업이 잘못된 요청에 응답했습니다.
나는 문제가없는 CURL-multi를 사용했으나 (최근에 기어를 시험해보고 더 많은 성능을 얻을 수 있는지 알아보기로 결정했습니다. 여기
는 클라이언트와 노동자에 대한 내 코드입니다 :클라이언트 코드 :
<?php
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header("Cache-Control: no-store, no-cache, must-revalidate"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
$order_id = $_POST['order_id'];
$customer_id = $_POST['customer_id'];
//some validation code here
class DataCollector extends GearmanClient{
private $data = array();
private $tmpArr = array();
function addData($content){
if($content){
$this->tmpArr = json_decode($content, true);
$this->data = array_merge($this->tmpArr, $this->data);
//$this->data[] = json_decode($content, true);
}
}
function getData(){
return $this->data;
}
function outputData(){
echo json_encode($this->getData());
}
function taskCompleted($task){
$this->addData($task->data());
}
}
$collector = new DataCollector();
$collector->addServer();
# set a function to be called when the work is complete
$collector->setCompleteCallback(array($collector, "taskCompleted"));
//params to pass to worker
$queryStr = array(
"order_id" => $order_id,
"customer_id" => $customer_id
);
$postData = serialize($queryStr);
# add tasks to be executed in parallel in Gearman server
$collector->addTask("getdata_orderDetails", $postData, null, "1");
$collector->addTask("getdata_customerDetails", $postData, null, "2");
# run the tasks in parallel
$collector->runTasks();
# output the data
$collector->outputData();
?>
작업자 코드 :
<?php
class Worker{
private $worker;
static $conn;
public function __construct(){
try{
self::$conn = oci_connect($user, $pass, $db); // create db connection
}
catch (Exception $e) {
echo "ERROR: " . $e->getMessage();
}
$this->worker = new GearmanWorker();
$this->worker->addServer();
# Register functions
$this->worker->addFunction("getdata_orderDetails", array($this, "getdata_orderDetails_fn"));
$this->worker->addFunction("getdata_customerDetails", array($this, "getdata_customerDetails_fn"));
}
public function run(){
while (1) {
//print "Waiting for job...\n";
$this->worker->work();
if ($this->worker->returnCode() != GEARMAN_SUCCESS) {
echo "return_code: " . $this->worker->returnCode() . "\n";
break;
}
}
}
static function getdata_orderDetails_fn($job){
if(!self::$conn){
$responseArr = array(
'response_status' => -1, //failed
'response_message' => 'Database connection lost',
'response_id' => 'DatabaseConnectionErr'
);
return json_encode($responseArr);
}
$postData = unserialize($job->workload());
$order_id = $postData['order_id'];
$customer_id = $postData['customer_id'];
$sql = "select order_id, order_status, create_date from customer_order where order_id= :order_id";
$stmt = oci_parse(self::$conn, $sql);
oci_bind_by_name($stmt, ":order_id", $order_id, -1);
oci_execute($stmt);
oci_fetch($stmt);
$order_id = oci_result($stmt, 'ORDER_ID');
$order_status = oci_result($stmt, 'ORDER_STATUS');
$create_date = oci_result($stmt, 'CREATE_DATE');
oci_free_statement($stmt);
$responseArr = array(
'response_status' => 1,
'response_message' => 'success',
'response_id' => 'order_details',
'order_id' => $order_id,
'order_status' => $order_status,
'create_date' => $create_date
);
// send result
return json_encode($responseArr);
}
static function getdata_customerDetails_fn($job){
if(!self::$conn){
$responseArr = array(
'response_status' => -1, //failed
'response_message' => 'Database connection lost',
'response_id' => 'DatabaseConnectionErr'
);
return json_encode($responseArr);
}
$postData = unserialize($job->workload());
$order_id = $postData['order_id'];
$customer_id = $postData['customer_id'];
$sql = "select customer_id, customer_fname, customer_lname, customer_address, customer_contact where customer_id= :customer_id";
$stmt = oci_parse(self::$conn, $sql);
oci_bind_by_name($stmt, ":customer_id", $customer_id, -1);
oci_execute($stmt);
oci_fetch($stmt);
$customer_id = oci_result($stmt, 'CUSTOMER_ID');
$customer_fname = oci_result($stmt, 'CUSTOMER_FNAME');
$customer_lname = oci_result($stmt, 'CUSTOMER_LNAME');
$customer_address = oci_result($stmt, 'CUSTOMER_ADDRESS');
$customer_contact = oci_result($stmt, 'CUSTOMER_CONTACT');
oci_free_statement($stmt);
$responseArr = array(
'response_id' => 'customer_details',
'response_status' => 1,
'response_message' => 'success',
'customer_id' => $customer_id,
'customer_fname' => $customer_fname,
'customer_lname' => $customer_lname,
'customer_address' => $customer_address,
'customer_contact' => $customer_contact
);
// send result
return json_encode($responseArr);
}
}//class
//start worker
$worker = new Worker();
$worker->run();
?>
감사합니다. 당신은 라이트입니다. https://groups.google.com/forum/m/#!topic/gearman/q3EV7mvHKDs –
답변도 정확하지만 제 시나리오의 경우 $를 기준으로 작업 고유 ID를 생성하는 것이 더 좋습니다. postData, 아래 내 대답을 참조하십시오. –