Celery에서 작업 상태를 확인하는 방법은 무엇입니까?


92

작업이 celery에서 실행 중인지 어떻게 확인합니까 (특히 celery-django를 사용하고 있습니다)?

설명서를 읽고 봤지만 다음과 같은 전화를 볼 수 없습니다.

my_example_task.state() == RUNNING

내 사용 사례는 트랜스 코딩을위한 외부 (자바) 서비스가 있다는 것입니다. 트랜스 코딩 할 문서를 보낼 때 해당 서비스를 실행하는 작업이 실행 중인지 확인하고 그렇지 않은 경우 (다시) 시작하고 싶습니다.

현재 안정된 버전 인 2.4를 사용하고 있습니다.

답변:


97

task_id (.delay ()에서 제공됨)를 반환하고 나중에 상태에 대해 셀러리 인스턴스에 문의합니다.

x = method.delay(1,2)
print x.task_id

질문 할 때 다음 task_id를 사용하여 새 AsyncResult를 가져옵니다.

from celery.result import AsyncResult
res = AsyncResult("your-task-id")
res.ready()

10
감사합니다. 액세스 권한이 없으면 x어떻게합니까?
Marcin

4
셀러리에 직업을 어디에 넣습니까? 앞으로 작업을 추적하려면 task_id를 반환해야합니다.
Gregor

@Marcin과 달리이 답변은 백엔드 구성을 유용하게 재사용하는 AsyncResult의 팩토리로 정적 메서드 Task.AsyncResult ()를 사용하지 않습니다. 그렇지 않으면 결과를 얻으려고 할 때 오류가 발생합니다.
ArnauOrriols 2015

2
@Chris @gregor 코드에 대한 논란은 async_result. 사용 사례에서 이미 인스턴스가 있으므로 이동하는 것이 좋습니다. 그러나 작업 ID 만 async_result있고 호출 할 수 있도록 인스턴스를 인스턴스화해야하는 경우 async_result.get()어떻게됩니까? 이것은 AsyncResult클래스 의 인스턴스 이지만 원시 클래스를 사용할 수 없으며로 celery.result.AsyncResult래핑 된 함수에서 클래스를 가져와야합니다 app.task(). 당신의 경우 당신은 할 것입니다async_result = run_instance.AsyncResult('task-id')
ArnauOrriols

1
but you cannot use the raw class celery.result.AsyncResult, you need to get the class from the function wrapped by app.task(). -이게 실제로 사용되던 방법 인 것 같아요. 코드의 읽기 유무 : github.com/celery/celery/blob/...이
nevelis

70

만들기 AsyncResult작업 ID와 객체 것은 입니다 에서 권장하는 방법 자주 묻는 질문 당신이 가진 유일한 것은 작업 ID입니다 때 작업 상태를 얻을.

그러나 Celery 3.x부터는 사람들이주의를 기울이지 않으면 물릴 수있는 중요한주의 사항이 있습니다. 실제로 특정 사용 사례 시나리오에 따라 다릅니다.

기본적으로 Celery는 "실행 중"상태를 기록하지 않습니다.

위해 셀러리는 작업이 실행되는 것을 기록하기 위해, 당신은 설정해야합니다 task_track_started으로 True. 다음은이를 테스트하는 간단한 작업입니다.

@app.task(bind=True)
def test(self):
    print self.AsyncResult(self.request.id).state

task_track_started입니다 False기본 인, 상태 표시는 PENDING작업이 시작에도 불구하고. 사용자가 설정 한 경우 task_track_startedTrue, 그 상태가 될 것입니다 STARTED.

상태 PENDING는 "모름"을 의미합니다.

AsyncResult상태로는 PENDING더 셀러리는 작업의 상태를 모르는 것보다 것을하지 평균 아무것도 않습니다. 이것은 여러 가지 이유 때문일 수 있습니다.

우선 AsyncResult잘못된 작업 ID로 구성 할 수 있습니다. 이러한 "작업"은 Celery에서 보류중인 것으로 간주됩니다.

>>> task.AsyncResult("invalid").status
'PENDING'

좋아, 아무도 분명히 유효하지 않은 ID를 AsyncResult. 충분히 AsyncResult공평하지만 성공적으로 실행되었지만 Celery가 잊혀진 작업을 고려하는PENDING 효과도 있습니다 . 다시 말하지만, 일부 사용 사례 시나리오에서는 이것이 문제가 될 수 있습니다. 문제의 일부는 결과 백엔드에서 "삭제 표시"의 가용성에 따라 다르기 때문에 작업 결과를 유지하도록 Celery를 구성하는 방법에 달려 있습니다. ( "묘비는"기록이 작업이 어떻게 끝났는지하는 데이터 청크에 대한 셀러리 설명서의 용어 사용이다.)를 사용 AsyncResult하면 전혀하지 않습니다 일 task_ignore_result입니다 True. 더 짜증나는 문제는 셀러리가 기본적으로 삭제 표시를 만료한다는 것입니다. 그만큼result_expires기본 설정은 24 시간으로 설정됩니다. 따라서 작업을 시작하고 장기 저장소에 ID를 기록하고 24 시간 후에 작업을 생성 AsyncResult하면 상태는 PENDING.

모든 "실제 작업"은 PENDING주 에서 시작됩니다 . 따라서 PENDING작업을 수행한다는 것은 작업이 요청되었지만 (어떤 이유로 든) 이보다 더 진행되지 않았 음을 의미 할 수 있습니다. 또는 작업이 실행되었지만 Celery가 상태를 잊어 버렸음을 의미 할 수 있습니다.

아야! AsyncResult나를 위해 작동하지 않습니다. 그 밖에 무엇을 할 수 있습니까?

작업 자체를 추적하는 것보다 목표를 추적하는 것을 선호 합니다 . 나는 몇 가지 작업 정보를 유지하지만 목표를 추적하는 것은 정말 부차적입니다. 목표는 셀러리와는 독립적 인 저장소에 저장됩니다. 요청이 계산을 수행해야 할 때 달성 된 목표에 따라 달라지며, 목표가 이미 달성되었는지 확인하고, 그렇다면이 캐시 된 목표를 사용하고, 그렇지 않으면 목표에 영향을 미칠 작업을 시작하고 HTTP 요청을 한 클라이언트가 결과를 기다려야 함을 나타내는 응답입니다.


위의 변수 이름과 하이퍼 링크는 Celery 4.x 용입니다. 3.X에 대응하는 변수와 하이퍼 링크이다 : CELERY_TRACK_STARTED, CELERY_IGNORE_RESULT, CELERY_TASK_RESULT_EXPIRES.


그래서 나중에 결과를 확인하고 싶다면 (다른 프로세스 내에서도 가능할 수도 있습니다), 내 자신의 구현이 더 낫습니까? 결과를 데이터베이스에 수동으로 저장 하시겠습니까?
Franklin Yu

예, "목표"를 추적하는 것과 "작업"을 추적하는 것을 분리합니다. 나는 "어떤 목표에 의존하는 계산을 수행한다"라고 썼다. 일반적으로 "목표"는 계산이기도합니다. 예를 들어 기사 X를 사용자에게 표시하려면 XML에서 HTML로 변환해야하지만 그 전에 모든 참고 문헌을 확인해야합니다. (X는 저널 기사와 같습니다.) "모든 서지 참조가 해결 된 X 조"라는 목표가 있는지 확인하고 원하는 목표를 계산했을 셀러리 작업의 작업 상태를 확인하려고 시도하지 않고이를 사용합니다.
Louis

그리고 "모든 서지 참조가 해결 된 기사 X"정보는 메모리 캐시에 저장되고 eXist-db 데이터베이스에 저장됩니다.
Louis

61

모든 Task개체에는 개체 .request를 포함 하는 속성이 있습니다 AsyncRequest. 따라서 다음 줄은 Task의 상태를 제공합니다 task.

task.AsyncResult(task.request.id).state

2
작업 진행률을 저장하는 방법이 있습니까?
patrick

4
이렇게하면 작업이 완료 될 때까지 충분히 기다려도 영구적으로 PENDING AsyncResult가 표시됩니다. 이보기 상태를 변경하는 방법이 있습니까? 내 백엔드가 구성되었다고 생각하며 CELERY_TRACK_STARTED = True를 아무 소용으로 설정하지 않았습니다.
dstromberg

1
@dstromberg 불행히도 이것이 나에게 문제가 된 지 4 년이 지났으므로 도울 수 없습니다. 상태를 추적하려면 셀러리를 구성해야합니다.
Marcin

16

또한 사용자 지정 상태를 생성하고 작업 실행 중 값을 업데이트 할 수 있습니다. 이 예제는 문서에서 가져온 것입니다.

@app.task(bind=True)
def upload_files(self, filenames):
    for i, file in enumerate(filenames):
        if not self.request.called_directly:
            self.update_state(state='PROGRESS',
                meta={'current': i, 'total': len(filenames)})

http://celery.readthedocs.org/en/latest/userguide/tasks.html#custom-states


11

오래된 질문이지만 최근 에이 문제가 발생했습니다.

task_id를 얻으려는 경우 다음과 같이 할 수 있습니다.

import celery
from celery_app import add
from celery import uuid

task_id = uuid()
result = add.apply_async((2, 2), task_id=task_id)

이제 task_id가 정확히 무엇인지 알았으며 이제이를 사용하여 AsyncResult를 가져올 수 있습니다.

# grab the AsyncResult 
result = celery.result.AsyncResult(task_id)

# print the task id
print result.task_id
09dad9cf-c9fa-4aee-933f-ff54dae39bdf

# print the AsyncResult's status
print result.status
SUCCESS

# print the result returned 
print result.result
4

3
고유 한 작업 ID를 생성하여에 전달할 필요가 전혀 없습니다 apply_async. 에 의해 반환되는 객체는 apply_async 입니다 AsyncResult셀러리를 생성하는 작업의 ID를 가지고 객체.
Louis

1
내가 틀렸다면 정정하십시오. 그러나 동일한 입력을받는 모든 호출이 동일한 UUID를 갖도록 일부 입력을 기반으로 UUID를 생성하는 것이 때때로 유용하지 않습니까? IOW, 때로는 task_id를 지정하는 것이 유용 할 수 있습니다.
dstromberg

1
@dstromberg OP에서 묻는 질문은 "작업 상태를 확인하는 방법"이고 여기에 대한 대답은 "task_id를 얻으려는 경우 ..."라고 말합니다. 작업 상태를 확인하지 task_id않아도 작업 ID를 직접 생성 할 필요가 없습니다 . 귀하의 의견에서 "작업 상태를 확인하는 방법"과 "task_id를 얻으려는 경우 ...` 그 이상의 이유를 상상했습니다. 필요한 경우 좋지만 그렇지 않은 경우 (게다가, uuid()작업 ID를 생성하는 데 사용 하면 Celery가 기본적 으로 수행하는 작업 외에는 아무것도 하지 않습니다.)
Louis

나는 OP가 예측 가능한 작업 ID를 얻는 방법을 구체적으로 묻지 않았다는 데 동의하지만 OP의 질문에 대한 대답은 현재 "작업 ID를 추적하고 x를 수행"입니다. 작업 ID를 추적하는 것은 다양한 상황에서 비실용적이므로 대답이 실제로 만족스럽지 않을 수 있습니다. 이 답변은 @dstromberg가 지적한 것과 같은 이유로 내 사용 사례를 해결하는 데 도움이됩니다 (그 이유에 대한 동기 부여 여부에 관계없이).
claytond


1

2020 년 답변 :

#### tasks.py
@celery.task()
def mytask(arg1):
    print(arg1)

#### blueprint.py
@bp.route("/args/arg1=<arg1>")
def sleeper(arg1):
    process = mytask.apply_async(args=(arg1,)) #mytask.delay(arg1)
    state = process.state
    return f"Thanks for your patience, your job {process.task_id} \
             is being processed. Status {state}"

0

시험:

task.AsyncResult(task.request.id).state

셀러리 태스크 상태를 제공합니다. Celery Task가 이미 FAILURE 상태에 있으면 예외가 발생합니다.

raised unexpected: KeyError('exc_type',)




0
  • 먼저 셀러리 앱에서 :

vi my_celery_apps / app1.py

app = Celery(worker_name)
  • 다음으로 작업 파일로 변경하고 셀러리 앱 모듈에서 앱을 가져옵니다.

vi tasks / task1.py

from my_celery_apps.app1 import app

app.AsyncResult(taskid)

try:
   if task.state.lower() != "success":
        return
except:
    """ do something """


-1

위의 프로그래밍 방식 외에도 Flower Task 상태를 사용하여 쉽게 볼 수 있습니다.

Celery Events를 사용한 실시간 모니터링. Flower는 셀러리 클러스터를 모니터링하고 관리하기위한 웹 기반 도구입니다.

  1. 작업 진행 및 역사
  2. 작업 세부 정보 (인수, 시작 시간, 런타임 등)를 표시하는 기능
  3. 그래프와 통계

공식 문서 : 꽃-셀러리 모니터링 도구

설치:

$ pip install flower

용법:

http://localhost:5555

-1
res = method.delay()
    
print(f"id={res.id}, state={res.state}, status={res.status} ")

print(res.get())

2
답변으로 코드 만 게시하지 말고 코드가하는 일과 질문의 문제를 어떻게 해결하는지에 대한 설명을 제공하십시오. 설명이있는 답변은 일반적으로 더 유용하고 품질이 좋으며 찬성 투표를 유도 할 가능성이 더 높습니다.
Mark Rotteveel
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.