2012-03-07 6 views
3

CodeIgniterのCLIを使用してSystem_Daemonパッケージを使用してデーモンを作成しようとしています。これは私のための新しい領域であり、私は苦労しています。System_Daemonパッケージを使用するCodeigniterデーモン

は、ここで私が持っているものです:(。CIにAWS SDKを統合する方法についての優れた指示を提供するために、[URL = http://codeigniter.com/forums/member/196201/]coccodrillo[/url]のおかげでここを参照してください:Integrating AWS SDK as a library in Codeigniter)をAWS SQSキューにメッセージを注入 CIコントローラ。

キュー内のメッセージを受信して​​ログファイルに書き出し、キュー内のメッセージを削除するCIコントローラ。

私はこのキューを聞いて、そこにメッセージを受け取り、そのメッセージに役立つ何かをして、そしてメッセージを削除するCIデーモンを持っていたいと思います。だから私はSystem_Daemonのドキュメントの例から始め、CIコードを受信プログラムから追加しました。以下のコードを参照

これは正しいことですか?あなたは私にこのことを "正しい方法"に導くことができますか?私は様々な知識豊富なフォーラムを回ってきたし、短くなりました....私を助けてください!

MMIZ

#!/usr/bin/php -q 
<?php 

// Make it possible to test in source directory 
// This is for PEAR developers only 
ini_set('include_path', ini_get('include_path').':..'); 

// Include Class 
error_reporting(E_ALL); 
require_once "System/Daemon.php"; 

// Bare minimum setup 
System_Daemon::setOption("appName", "receiveaws"); 
System_Daemon::setOption("logLocation","/tmp/log/receiveaws.log"); 
System_Daemon::setOption("appPidLocation","/tmp/log/receiveaws/receiveaws.pid"); 
System_Daemon::log(System_Daemon::LOG_INFO, "Daemon not yet started so this will be written on-screen"); 

// Spawn Deamon! 
System_Daemon::start(); 
System_Daemon::log(System_Daemon::LOG_INFO, "Daemon: '". 
    System_Daemon::getOption("appName"). 
     "' spawned! This will be written to ". 
      System_Daemon::getOption("logLocation")); 

System_Daemon::log(System_Daemon::LOG_WARNING, 'My php code starting'); 
class Receiveaws extends CI_Controller { 

    public function index(){ 
    if ($this->input->is_cli_request()) { 
     //Load the aws library 
     $this->load->library('awslib'); 
     $sqs = new AmazonSQS(); 

     //Get the queue to look at 
     $res=$sqs->get_queue_url('example-queue'); 

     //Get the queue's url 
     $qurl=($res->body->GetQueueUrlResult->QueueUrl); 
     System_Daemon::log(System_Daemon::LOG_INFO,$qurl); 

     //Get a message from the queue 
     $response = $sqs->receive_message($qurl); 

     //If there was a message received, then do something 
      if ($res->isOK()) { 
      System_Daemon::log(System_Daemon::LOG_INFO,"Receive message successful"); 
          //Now delete message from queue 
      $res=$sqs->delete_message($qurl,$rcpt_hand); 
      if ($res->isOK()) { 
       System_Daemon::log(System_Daemon::LOG_INFO,"Delete message successful"); 
      } 
     } else { 
      //go back to check for messages 
      //How do you do that? 
     } 
    } else { 
     //Access from URL - so bail out? 
     //how do you not bail out of the daemon from here? 
    } 
    } 
} 
System_Daemon::stop(); 
?> 

答えて

0

デーモンは、バックグラウンドで '永遠に' 実行中のプロセスです。 ここでは、キュー内の1つの新しいメッセージを確認して終了します。 基本的には、実行する必要があるすべてのコードを取るループを追加する必要があります。あなたのデーモンが利用可能なすべてのリソースを占めないようにするには、ループの中でsleepを実行する必要があります。

とにかく、スクリプトの終わりまでメモリが解放されないので、phpはデーモンがうまくいかない。あなたのスクリプトが(デーモンのように)決して終わらなければ、(phpの設定に従って)利用可能なすべてのメモリを使い果たし、エラーで死んでしまいます。このようなメモリリークを避けるには、スクリプトを非常に慎重にコーディングする必要があります。

また、sqsライブラリに何か質問するたびに、Amazonサーバーにhttp要求を送信することに注意してください。あまりにも頻繁に行うのは非常にコストがかかることがあります。

補正するには、毎分実行して新しい作業を確認するcronジョブを使用することをお勧めします。こうすることで、メモリリーク(PHPプロセスが実行間でダウンする)とネットワークの使用量が多すぎる(要求が分単位で行われる)ことを回避できます。

多くのタスクを計画していない場合(すなわち、デーモンは99%の時間を費やさない)、代わりにプッシュキューを使用することを検討してください。プッシュキューでは、これ以上キューをポーリングするスクリプトではありませんが、キューはスクリプトに通知します(つまり、標準のhttp要求でスクリプトを呼び出す)。これにより、不要なスクリプトの実行を回避できます。

amazonがプッシュキューを提供しているかどうかわかりませんが、ironmq(別の「無料」キューサービス)がそれらを提供できるかどうかはわかりません。 詳細情報:http://dev.iron.io/mq/reference/push_queues/

+0

お寄せいただきありがとうございます!私もcronの仕事が行く方法であるという結論に達しました。 push_queuesポインタもありがとう。とても有難い。 – user1072910

関連する問題