2017-02-16 58 views
1

我有一個下面的問題: 我在codeigniter框架的php中有一個後端,我將從一個外部C#應用程序發送的計量機中獲取體重數據(不能修改該C#應用程序)。我會在每次稱重器更新數值時獲得重量數據,例如它將從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這快,$重量將保持重量值(忽略$ evType,這是一些縮放比例)。隨着新的價值觀的到來,這將不得不保持並快速插入數據。現在我將有一個條件:if($ weight> 100)當這是TRUE時我轉到上面列出的另一個函數,這是做一個相機打印屏幕並將該圖像保存到我的服務器上選擇文件夾並將其與在mysql上插入的weight值的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打印屏幕(這意味着當有人將規模的東西,我需要做一個打印屏幕,當條件觸發,然後等待下一個加權事件,稱重機不會產生不間斷的數據,但是當它產生時,我必須快速獲得它)。

我在想什麼是使請求API並行處理,以便重量事件的流程不受影響,當API請求完成時,再次開始檢查,如果將變爲真,等等。 ,我還想如果我可以控制那個並行進程來使用一些睡眠或其他東西。

我讀了一些關於php工作者和線程的內容,我看到redis,german,heroku,但說實話他們似乎有點難以理解,而且文檔很薄弱,我也認爲他們也是如此很多爲我的問題。

問題是否有什麼是輕量級和平易近人的PHP是不是先進的?

非常感謝你的時間!

回答

1

是的,你可以自己做一個簡單的任務隊列。

每次您需要請求API時,您都將創建一個任務,並將其存儲在數據庫中的某個定製表中,其中只存儲任務。因爲我們只是將任務保存到數據庫而不是在這裏發出api請求,所以速度很快。

現在我們有一個需要完成任務的隊列(數據庫中的一個表),所以現在我們需要一些php工作者從隊列中獲取一個任務並執行它。

創建一個簡單的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

嗯,這是有趣的,感謝您的回覆,我的問題是,由於實際的打印屏幕,我做的是從現場攝像機,我想以最快的速度處理我的數據庫中的任務(因爲我想讓相機圖片的打印屏幕儘可能接近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

相關問題