Codeigniter Daemon с использованием пакета System_Daemon - PullRequest
4 голосов
/ 08 марта 2012

Я пытаюсь создать демон, используя пакет System_Daemon с CLI CodeIgniter. Это новая область для меня, и я изо всех сил.

Вот что у меня есть: Контроллер CI, который внедряет сообщения в очередь AWS SQS (спасибо [url = http://codeigniter.com/forums/member/196201/]coccodrillo[/url] за прекрасные инструкции по интеграции AWS SDK в CI. См. Здесь: Интеграция AWS SDK в качестве библиотеки в Codeigniter ).

Контроллер 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();
?>

1 Ответ

1 голос
/ 14 августа 2013

Демон - это процесс, выполняющийся в фоновом режиме. Здесь все, что вам нужно сделать, это проверить одно новое сообщение в очереди, а затем выйти. По сути, вы должны добавить цикл, который принимает весь код, который должен быть выполнен. Вам нужно выполнить спящий цикл, чтобы ваш демон не занимал все доступные ресурсы.

В любом случае, php плохо работает с демоном, потому что некоторая память никогда не освобождается до конца скрипта. Если ваш скрипт никогда не завершится (как демон), он съест всю доступную память (в соответствии с конфигурацией php), а затем умрет с ошибкой. Чтобы избежать утечек памяти, вам придется очень тщательно кодировать свой скрипт.

Также обратите внимание, что каждый раз, когда вы спрашиваете библиотеку sqs, она отправляет http-запрос на серверы Amazon. Это может быть очень дорого делать слишком часто.

Для компенсации я рекомендую вам использовать cronjob, который запускается каждую минуту, чтобы проверять новое задание. Таким образом вы избежите утечек памяти (процесс php останавливается между выполнениями) и слишком большого использования сети (запрос выполняется за одну минуту).

В последнем замечании, если вы не планируете выполнять много задач (это означает, что ваш демон ничего не делает в 99% случаев), рассмотрите возможность использования очереди push. С помощью push-очереди больше не ваш сценарий опрашивает очередь, но очередь уведомляет ваш сценарий (то есть: вызывает вас сценарий со стандартным http-запросом) каждый раз, когда необходимо выполнить какую-либо задачу. Это позволит избежать запуска скрипта без необходимости.

Я не знаю, предоставляет ли amazon очереди push, но ironmq (еще один «бесплатный» сервис очереди) может их предоставить. Дополнительная информация: http://dev.iron.io/mq/reference/push_queues/

...