Escolha intermediário
O Celery precisa de um serviço separado para receber e enviar mensagens, esse serviço é chamado de 'middleware de mensagens'.
Supondo que redis seja usado como middleware,
task.py:
from celery import Celery
app = Celery('task', broker='redis://localhost//')
@app.task
def add(x, y):
return x + y
O código acima instancia uma instância do Celery. Para usar essa instância como um ponto de entrada para criar tarefas assíncronas e gerenciar executores de tarefas em outros módulos, essa instância deve ser referenciada de tempos em tempos.
O primeiro parâmetro é o nome do módulo onde a instância do Celery está localizada.Este parâmetro é necessário e usado para gerar o nome automaticamente quando o módulo __main__ cria uma tarefa.
Uma tarefa chamada add também é definida aqui.
Execute o servidor de execução de tarefas Celery
celery -A tasks worker --loglevel=info
Chamar tarefa assíncrona
Abra outro terminal
>>> from task import add
>>> add.delay(4, 4)
A tarefa atual é executada pelo executor da tarefa que acabou de ser executado. Verifique o terminal anterior para ver o processo em execução.
Usar o método de atraso para chamar uma função retornará uma instância do tipo AsyncResult, que pode ser usada para verificar o status da tarefa, aguardar o resultado da execução da tarefa ou obter o resultado de retorno da tarefa. Se a tarefa falhar, a exceção e o rastreamento da exceção também podem ser obtidos por meio dessa instância.
O resultado da tarefa não está disponível por padrão, você pode configurar o parâmetro de back-end para chamar ou rastrear remotamente a tarefa:
app = Celery('task', backend='redis://', broker='redis://')
Você pode usar o método get para obter o resultado da tarefa e usar o parâmetro de tempo limite para especificar o tempo de espera:
res.get(timeout=10)
O método get lançará a exceção lançada pela tarefa. Ao especificar o parâmetro de propagação como False, a exceção pode ser evitada.
Você também pode usar o atributo traceback para obter o
resultado de rastreamento anormal . O plano de fundo irá ocupar recursos para armazenar ou transmitir os resultados. Você deve chamar o método get () ou forget () em cada instância AsyncResult para liberar os recursos.
Configuração
Você pode definir diretamente a configuração do aplicativo:
app.conf.task_serializer = 'json'
ou
app.conf.update(
task_serializer='json',
accept_content=['json'], # Ignore other content
result_serializer='json',
timezone='Europe/Oslo',
enable_utc=True,
)
Você também pode usar um arquivo de configuração especial:
app.config_from_object('celeryconfig')
O arquivo de configuração é aproximadamente o seguinte
broker_url = 'pyamqp://'
result_backend = 'rpc://'
task_serializer = 'json'
result_serializer = 'json'
accept_content = ['json']
timezone = 'Europe/Oslo'
enable_utc = True
Use aipo no projeto
Estrutura do projeto:
proj/__init__.py
/celery.py
/tasks.py
proj / celery.py
from __future__ import absolute_import, unicode_literals
from celery import Celery
app = Celery('proj',
broker='redis://',
backend='redis://',
include=['proj.tasks'])
# Optional configuration, see the application user guide.
app.conf.update(
result_expires=3600,
)
if __name__ == '__main__':
app.start()
O módulo celery.py cria uma instância de Celery, que pode ser usada para criar tarefas assíncronas no projeto.
- O parâmetro include especifica os módulos a serem importados quando o executor da tarefa é iniciado. Após a introdução, o executor da tarefa pode encontrar a tarefa.
proj / tasks.py
from __future__ import absolute_import, unicode_literals
from .celery import app
@app.task
def add(x, y):
return x + y
@app.task
def mul(x, y):
return x * y
@app.task
def xsum(numbers):
return sum(numbers)
Use o programa de aipo no diretório superior do proj para iniciar o executor da tarefa:
$ celery -A proj worker -l info
--------------- [email protected] v4.0 (latentcall)
--- ***** -----
-- ******* ---- [Configuration]
- *** --- * --- . broker: amqp://guest@localhost:5672//
- ** ---------- . app: __main__:0x1012d8590
- ** ---------- . concurrency: 8 (processes)
- ** ---------- . events: OFF (enable -E to monitor this worker)
- ** ----------
- *** --- * --- [Queues]
-- ******* ---- . celery: exchange:celery(direct) binding:celery
--- ***** -----
O padrão do aipo é iniciar o número de processos de executores de tarefas com o número de CPUs. Você pode especificar o número de executores de tarefas por meio do trabalhador de aipo -c. Se a tarefa for principalmente operações de E / S, considere aumentar o número de trabalhadores. Caso contrário, a eficiência de execução não pode ser significativamente melhorada e o desempenho pode até ser reduzido.
O aipo também oferece suporte a multi-threading .
O parâmetro –app especifica a instância do aipo e o formato do valor module.path:attribute
Para –app = proj, o aipo irá procurar instâncias relacionadas na seguinte ordem:
- Parâmetro denominado proj.app
- Parâmetro denominado proj.celery
- O valor no módulo proj é o parâmetro do aplicativo Celety
- Um parâmetro denominado proj.celety.app
- Parâmetro denominado proj.celery.celery
- O valor do módulo proj.celery é o parâmetro usado pelo Celery
Chamar tarefa
O método delay () é na verdade abreviação de apply_async (). apply_async () permite que você especifique o tempo de execução da tarefa (contagem regressiva) e a fila de chamadas da tarefa (fila), etc .:
res = add.apply_async((2, 2), queue='lopri', countdown=10)
# 检查任务状态
res.state # 'FAILURE'
# 获取任务id
res.id # 'd6b3aea2-fb9b-4ebc-8da4-848818db9114'
# 获取AsyncResult实例
from proj.celery import app
res = app.AsyncResult('d6b3aea2-fb9b-4ebc-8da4-848818db9114')
Status de tarefa comum:
PENDING -> STARTED ->
status SUCCESS PENDING é na verdade o status padrão de tarefas desconhecidas.
Somente se o task_track_started
parâmetro for configurado ou especificado na decoração @task(track_started=True)
ele terá o estado INICIADO.
Chamada de streaming
Quando você deseja passar a assinatura da tarefa para outro processo ou como um parâmetro de outra função, você pode usar assinaturas.
sa = add.signature((2, 2), countdown=10)
# 调用
res = sa.delay()
res.get()
grupos
grupos chamam um grupo de tarefas ao mesmo tempo e retornam os resultados em grupos
from celery import group
from proj.tasks import add
group(add.s(i, i) for i in range(10)),get() # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
g = group(add.s(i) for i in range(10))
g(10).get() # [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
correntes
As tarefas também podem ser conectadas e chamadas sequencialmente
from celery import chain
from proj.tasks import add, mul
chain(add.s(4, 4) | mul.s(8))().get()
acordes
chrods é um grupo com função de retorno de chamada
from celery import chord
from proj.tasks import add, xsum
chord((add.s(i, i) for i in range(10)), xsum.s())().get()
Quando um grupo e outra tarefa formam uma cadeia, ela será automaticamente convertida em acorde
(group(add.s(i, i) for i in range(10)) | xsum.s())().get()
Roteamento de tarefas
O Celery suporta a atribuição de tarefas a filas de tarefas especificadas por nome
app.conf.update(
task_routes = {
'proj.tasks.add': {'queue': 'hipri'},
},
)
Você também pode especificar a fila de tarefas, especificando o parâmetro apply_async ao executar a tarefa
from proj.tasks import add
add.apply_async((2, 2), queue='hipri')
Em seguida, especifique o executor da tarefa para executar as tarefas na fila por meio do parâmetro de linha de comando -Q
celery -A proj worker -Q hipri
Use vírgulas para selecionar várias filas
celery -A proj worker -Q hipri,celery