quinta-feira, 12 de janeiro de 2012

Zend Job Queue

Aplicações Web geralmente seguem um modelo de comunicação síncrona. No entanto, as tarefas não-interativas e de longa duração (como a geração de relatórios) são mais adequadas para a execução assíncrona. Uma maneira de off-load tarefas para serem executadas em um momento posterior, ou mesmo em um servidor diferente, é usar o módulo Job Queue disponíveis como parte do Zend Server 5 (embora não como parte do Community Edition).

Fila de trabalho permite agendamento de tarefas com base no tempo, prioridade e até mesmo dependências. Jobs pode ser adiada ou executados periodicamente e - a melhor parte - em paralelo! Em cima disso, Zend Server em si oferece uma interface gráfica de gerenciamento para acompanhar a execução dos trabalhos, incluindo o seu estado, o tempo de execução e de saída.
A principal vantagem do módulo Job Queue é a sua capacidade para executar tarefas em paralelo. Ao contrário de trabalhos do cron, Job Queue permite:
Execução de tarefas agora sem esperar por eles para terminar (execução assíncrona)
Executar tarefas de uma vez, mas não agora (empregos diferidos)
Execução de tarefas periodicamente (trabalhos recorrentes como o cron, mas com total controle sobre eles através da API de PHP - iniciar, parar, suspender, reiniciar)
Capacidade de status do trabalho de consulta, lidar com falhas, e re-fila através da API, bem como acompanhar os trabalhos passados, atuais e pendentes da GUI.
Alguns exemplos de tarefas assíncronas, onde Job Queue pode ser útil são:
Preparação de dados para o próximo pedido (pré-cálculo)
Pré-caching de dados
Geração de relatórios periódicos
Enviar e-mails
Limpeza de dados ou arquivos temporários
Comunicação com sistemas externos
Sincronização em segundo plano de dados com dispositivos móveis
Uso da fila de trabalho
API Fila trabalho é disponibilizado através do ZendJobQueue classe. Para executar a maioria das tarefas que você irá se conectar a um servidor de filas de impressão por instanciar um ZendJobQueue objeto e criar um trabalho usando a createHttpJob () método.

<? Php
$ Fila = nova ZendJobQueue ();
$ Fila -> createHttpJob ( " http://example.com/jobs/somejob.php " );

Passando um caminho para createHttpJob () em vez de uma URL completa vai criar um trabalho com o valor de $ _SERVER ["HTTP_HOST"] como o nome do host. Cuidado com os casos em que $ _SERVER ["HTTP_HOST"] não está disponível, como quando o trabalho está programado a partir de um script cron.

<? Php
/ / Ambas as chamadas são equivalentes
$ Fila -> createHttpJob ( "/ jobs / somejob.php" );
$ Fila -> createHttpJob ( " http:// " . $ _SERVER [ "HTTP_HOST" ]. "/ jobs / somejob.php" );

Parâmetros de trabalho pode ser passado tanto como uma parte da seqüência de consulta ou em uma matriz como o segundo argumento do createHttpJob () . Se os parâmetros são passados ​​como segundo argumento, a matriz deve ser compatível com JSON.
Para acessar os parâmetros, o getCurrentJobParams () método estático pode ser usado dentro do código de trabalho.
1
<? Php
$ Params = ZendJobQueue:: getCurrentJobParams ();

Opções de trabalho adicionais estão disponíveis através de um terceiro argumento para createHttpJob () . É uma matriz associativa com as seguintes chaves:
nome - um nome de trabalho opcional
prioridade - a prioridade da tarefa, tal como definido pelas constantes correspondentes PRIORITY_LOW , PRIORITY_NORMAL , PRIORITY_HIGH e PRIORITY_URGENT
persistente - um valor booleano se quer manter o trabalho na história para sempre
predecessor - uma ID trabalho inteiro predecessor
http_headers - HTTP cabeçalhos adicionais
cronograma - cron-como comando de programação
schedule_time - momento em que o trabalho deve ser executado (mas pode rodar após esse tempo, dependendo da carga fila de Jó)
Por exemplo, criar um trabalho diferido ou recorrente seria parecido com os exemplos abaixo:
01
<? Php
02
$ Params = matriz ( "p1" => 10, "p2" => "algumvalor" );
03

04
/ / Processa em uma hora
05
$ Options = matriz ( "schedule_time" => data ( "Ymd H: i: s" , strtotime ( "uma hora" )));
06
$ Fila -> createHttpJob ( " http://example.com/jobs/somejob.php " , $ params , $ options );
07

08
/ / Processa todos os dias às 1:05 am
09
$ Options = matriz ( "schedule" => "5 1 / * 2 * *" );
10
$ Fila -> createHttpJob ( " http://example.com/jobs/somejob.php " , $ params , $ options );
Falhas (e sucessos) podem ser tratadas da seguinte maneira:
1
<? Php
2
try {
3
    doSomething ();
4
    ZendJobQueue:: setCurrentJobStatus (ZendJobQueue:: OK);
5
}
6
catch (Exception $ e ) {
7
    ZendJobQueue:: setCurrentJobStatus (ZendJobQueue:: STATUS_LOGICALLY_FAILED, e $ -> getMessage ());
8
}
Um exemplo Extended
Vamos dizer que sua aplicação web tem que gerar e e-mail um conjunto de relatórios a pedido de um usuário.
Tipicamente, dado o fato de que o PHP não suporta multiprocessamento e modelo de comunicação síncrona é usado, o usuário terá que esperar até que todos os relatórios solicitados são gerados um por um e por e-mail.
Usando fila de tarefas, neste caso, não só irá permitir ao usuário realizar outras ações com a aplicação (desde que o trabalho será feito de forma assíncrona) mas também a aplicação pode processar vários relatórios ao mesmo tempo (uma vez que os trabalhos podem ser executadas em paralelo) - assim a maioria dos relatórios (se não todos) vai terminar mais ou menos no mesmo tempo.

<? Php
função scheduleReport ( $ reportList , $ recipient ) {

    / / Lista de tarefas agendadas
    Lista de trabalhos $ = matriz ();

    $ Fila = nova ZendJobQueue ();

    / / Verificar se fila de tarefas está em execução
    se ( $ fila -> isJobQueueDaemonRunning () & & count ( $ reportList )> 0) {
    foreach ( $ reportList como $ relatório ) {
        $ Params = matriz ( "tipo" => $ relatório [ "type" ],
                        "Start" => $ relatório [ "start" ],
                        "Comprimento" => $ relatório [ "tamanho" ],
                        "Destinatário" => $ recipient );
        $ Options = matriz ( "prioridade" => $ relatório [ "prioridade" ]);
        / / Execute o trabalho em dois minutos a menos que a prioridade é urgente
        se ( $ relatório [ "prioridade" ] = ZendJobQueue:: PRIORITY_URGENT) {
            $ Options [ "schedule_time" ] = data ( "Ymd H: i: s" , strtotime ( "dois minutos" ));
        }

        JobID $ = $ fila -> createHttpJob ( " http://example.com/jobs/report.php " , $ params , $ options );

        / / Adiciona ID trabalho para a lista de trabalhos agendada com êxito
        se ( $ jobID ! == false) {
           Lista de trabalhos $ [] = $ jobID ;
       }
    }
    retorno $ Lista de trabalhos ;
}

O scheduleReport () função retorna a lista de identificadores de trabalho associados a cada relatório programado. Dentro desta função, o isJobQueueDaemonRunning () método de ZendJobQueue classe verifica se o serviço adequado está sendo executado e os trabalhos podem ser agendadas.
Dependendo da prioridade do relatório, o trabalho pode ser programado para ser executado imediatamente ou dois minutos mais tarde (em um esforço para reduzir a carga sobre o servidor se muitos relatórios são solicitados ao mesmo tempo). Uma vez que um trabalho é agendada, seu ID é guardado na lista de todos os empregos criados com sucesso. É importante saber ID um trabalho, a fim de ser capaz de monitorar o trabalho ou mesmo cancelá-la.
Há o que a chamada para scheduleReport () função é semelhante a:

<? Php
/ Pedido setup / para um relatório de vendas diário e relatório financeiro mensal
$ ReportList = matriz (
    série ( "tipo" => "vendas" ,
          "Start" => "2011/12/09 00:00:00" ,
          "Comprimento" => 1,
          "Prioridade" => ZendJobQueue:: PRIORITY_URGENT),
    série ( "tipo" => "financiamento" ,
          "Start" => "2011/11/01 00:00:00" ,
          "Comprimento" => 30,
          "Prioridade" => ZendJobQueue:: PRIORITY_NORMAL));
/ / Programar relatórios
Lista de trabalhos $ = scheduleReport ( $ reportList , "user@example.com" );

/ / Verificar se os relatórios foram agendadas
se ( vazia ( $ Lista de trabalhos )) {
    Mensagem de erro / / show
}
Como mencionado anteriormente, também é possível cancelar um trabalho agendado. Quando o trabalho está em andamento que será terminado. Assim, se a prioridade do pedido não é urgente, o usuário tem dois minutos para cancelar a entrega do relatório agendado.

<? Php
função cancelReport ( $ jobID ) {
    $ Fila = nova ZendJobQueue ();
    retorno $ fila -> removeJob ( $ jobID );
}

se ( $ jobID ! == false & & cancelReport ( $ jobID )) {
    / / O trabalho foi removido com sucesso a partir da fila
}

O cancelReport () função simplesmente remove o trabalho da fila de relatórios programados que ainda não começou a correr.
O script trabalho, então fica assim:

<? Php
função runReport () {
    $ Params = ZendJobQueue:: GetParamList ();

    try {
        $ Relatório prepareReport = ( $ params [ "type" ], $ params [ "start" ], $ params [ "tamanho" ]);
        sendReport ( $ params [ "destinatário" ], $ relatório );
        ZendJobQueue:: setCurrentJobStatus (ZendJobQueue:: OK);
    }
    catch (Exception $ e ) {
        ZendJobQueue:: setCurrentJobStatus (ZendJobQueue:: STATUS_LOGICALLY_FAILED, e $ -> getMessage ());
    }
}

O runReport () função, finalmente, prepara e envia o relatório com base nos parâmetros fornecidos. Após a conclusão, o status do trabalho é definida como bem-sucedida (ou logicamente não se houve um erro).

Nenhum comentário :

Postar um comentário

Total de visualizações de página