2017-02-16 1 views
1

나는 fallowing 문제가있다 : 나는 외부 C# 응용 프로그램에서 보내는 무게 기계에서 무게 데이터를 얻을 수있는 codeigniter 프레임 워크에서 PHP 백엔드를 가지고있다. 그 C# 애플 리케이션). weigher가 값을 업데이트 할 때마다 가중치 데이터를 얻습니다. 예를 들어 0, 100, 300, 400, 1000, 1500, 600, 400, 300, 100에서 다시 0으로 시작합니다 이 제품은) 규모 떨어져 있으며,이 모든 값은 두 번째에 하나 개의 항목을 생성, 그래서 나는 그들을 빨리, 그리고이 함수 내 MySQL 데이터베이스에 그를 삽입 할 때 :PHP에서 병렬 처리 작업 방법

public function balance() { 
    $evType = $this->input->post('eventType'); 
    $weight = $this->input->post('balanceWeight'); 

    if ($evType !== false && $weight !== false) { 
     $evType = intval($evType); 
     $weight = intval($weight); 


     switch($this->balance_events->insert($evType, $weight)) { 
      case OpResult::Ok; 
       $this->_issue_success(); 
        if($weight>100){ 
        $insert_id = $this->db->insert_id(); 
        $this->Curlsynologyapi->CURLsaveimage($insert_id); 
        }    
       break; 
      case OpResult::InvalidParameters; 
       $this->_issue_respond_with_reason("Not all parameters were supplied.", HttpResponse::BadRequest); 
       break; 
      case OpResult::Failed: 
       $this->_issue_respond_with_reason("Internal server error occured while inserting the balance entry. Please try again ...", HttpResponse::InternalServerError); 
       break; 
      default: 
       break; 
     } 
    } 
} 

그래서이 exaplain하기 빠르면 $ weight가 가중치를 유지합니다 ($ evType을 무시합니다. 새로운 가치가 올 것으로 예상되면 데이터를 보류하고 삽입해야합니다. 이제 조건이 생깁니다 : if ($ weight> 100) TRUE 일 때 위의 목록에서 다른 기능으로 이동합니다. 카메라 인쇄 화면을 만들고 해당 이미지를 선택한 폴더에 저장하고 mysql에 삽입 된 가중치의 ID로 이름을 지정한다. 이것은 내가 나의 문에 해당하는 경우 이후에 있음을 부르는 :

public function CURLsaveimage($insert_id) { 
    $datasidget = $this->curl->simple_get('blablabla this is my api login url'); 
    $datasid = json_decode($datasidget,true); 
    $data_sid = $datasid['data']['sid']; 

    $reqUrl = "blabla this is my print screen from a live camera api url"; 
    $imageencode = $this->curl->simple_get($reqUrl); 
    $path = "./images/$insert_id"; 
    write_file($path, $imageencode, $mode = 'wb'); 

} 

내 마지막 함수의 API 요청의 실행은 30 ~ 40 초처럼 걸릴 것입니다 그리고 내가 무게를 얻을 것이다 속도에 비해 훨씬이다 값 (1 항목/초). 그리고 if가 트리거하고 api 요청을 시작하면 요청이 완료 될 때까지 모든 체중 데이터를 놓칩니다. 그게 제가 규모의 세션 당 1 인쇄 화면을 얻을 여유가 있다는 것입니다 (즉, 누군가가 저울에 무언가를 집어 넣을 때, 조건이 실행될 때 1 개의 인쇄 화면을해야하고 다음 가중치 이벤트, 무게 기계에 대기해야 함을 의미합니다 비 연속 데이터를 생성 할 수는 없지만 생성시 신속하게 가져와야 함).

내가 생각했던 것은 가중치 이벤트의 흐름이 영향을받지 않도록 api 프로세스에 병렬로 요청하는 것이고 api 요청이 완료되면 언제 다시 시작되는지를 확인하기 위해 다시 시작합니다. , 나는 또한 그와 비슷한 수면을 사용하기 위해 그 평행 과정을 어느 정도 통제 할 수 있으면 좋겠다.

PHP 작업자와 스레드에 대해 약간 읽었지만, 나는 redis, german, heroku를 보았습니다.하지만 솔직히 말하면 이해하기가 약간 어려워 보이며 문서화도 꽤 얇은 것 같아요. 내 문제에 많이.

질문 가볍고 주위에 PHP에서 고급 아닌 사람을 위해 친숙한 질문이 있습니까?

감사합니다.

답변

1

예, 간단한 작업 대기열을 직접 만들 수 있습니다.

API를 요청할 필요가있을 때마다 작업을 만들고 데이터베이스에 작업 만 저장되는 사용자 정의 테이블에 저장합니다. 우리는 데이터베이스에 작업 만 저장하고 여기에 API 요청을하지 않기 때문에 빠릅니다.

이제는 완료 할 작업이있는 대기열 (데이터베이스에있는 테이블)이 있습니다. 그래서 우리는 대기열에서 하나의 작업을 가져와 실행하기 위해 PHP 작업자가 필요합니다.

데이터베이스에서 하나의 작업 (예 : "select * from tasks limit 1")을 생성하고 실행 한 다음 완료시 데이터베이스에서이 작업을 삭제합니다 (또는 작업 상태를 변경할 수 있음).

이제 우리는이 스크립트를 누가 언제 실행할 것입니까? 이 경우 cron을 사용할 수 있습니다. 예를 들어 매분마다 스크립트를 실행하도록 예약 할 수 있습니다.

PHP 스크립트는 매분 (예 : cron) 실행할 수 있습니다.

그리고 당신의 코드는 다음과 같이보고한다 :

 switch($this->balance_events->insert($evType, $weight)) { 
      case OpResult::Ok; 
       $this->_issue_success(); 
        if($weight>100){ 
         $insert_id = $this->db->insert_id(); 
         $saveCameraImageTask = new SaveCameraImageTask($insert_id); 
         $saveCameraImageTask->save()//save it to database, we are just saving it to our database, no api request, so it is fast. 
        }    
       break; 
      case OpResult::InvalidParameters; 
       $this->_issue_respond_with_reason("Not all parameters were supplied.", HttpResponse::BadRequest); 
       break; 
      case OpResult::Failed: 
       $this->_issue_respond_with_reason("Internal server error occured while inserting the balance entry. Please try again ...", HttpResponse::InternalServerError); 
       break; 
      default: 
       break; 
     } 
+0

음을, 즉 흥미, 답장을 보내 주셔서 감사합니다, 내 문제는 내가 실제 인쇄 화면부터 라이브 카메라에서하고 내가 원하는 것입니다 작업이 내 DB에 도착할 때까지 빨리 처리 할 수 ​​있습니다. 왜냐하면 카메라의 화면을 if 트리거처럼 시간에 가깝게 만들고 싶고, 어떤 제품이 저울에 있는지 확인하고 싶기 때문입니다. 예를 들어, 거기에 작업을 삽입하자마자 내 데이터베이스에서 작업을 시작할 수 있습니까? – Bogdan

+0

글쎄요. 당신이 방아쇠에 대한 작업을 실행하려면, 새로운 행이 삽입되었을 때, 내가 아는 한 쉬운 해결책이 없습니다. 비슷한 질문이 여기에 있었다 http://stackoverflow.com/questions/21019886/how-to-check-in-real-time-if-new-row-was-added-to-mysql-table 그러나 만약 당신이 확인하고 싶다면 새로운 행을 1 분 이상 자주 실행하면됩니다. – Clickbeetle

+0

곧 실행할 의사가있는 작업이있을 때 내 솔루션이 더 적합하지만 동시에는 적합하지 않습니다. 즉각적인 동시 실행이 필요한 경우 기어맨, 토끼 등이 필요합니다. – Clickbeetle