如何通过气流检查长时间运行的http任务的状态?

时间:2018-12-01 15:40:40

标签: airflow job-scheduling

我的用例是使用气流控制跨微服务的许多计划作业。我正在尝试的解决方案是将气流用作集中式作业调度程序,并通过进行http调用来触发作业。其中一些工作将长期运行,例如。超过10分钟或长达1小时。

如何通过气流定期检查这些作业的状态?如果远程任务已完成但气流不知道作业成功怎么办?我可以将活动完成事件发布到kafka并让气流监听kafka以获得工作状态吗?

1 个答案:

答案 0 :(得分:2)

您可以通过多种方式使用Airflow和微服务进行此操作。通常,您将需要使用一个传感器,它是用于类似此类的适当气流对象。首先查看BaseSensorOperator和有关operators的信息。在气流中,传感器的使用就像操作员一样(传感器就是操作员)。因此,您可以创建一个像这样的工作:

http_post_task -> http_sensor_task -> success_task

在http_post_task将触发作业的地方,http_sensor_task将定期检查该作业是否完成(例如GET请求微服务并检查200,也许呢?),并且成功执行http_sensor_task后执行Success_task。

您的http_sensor_task将需要是您自己的自定义传感器。这是一些sudo代码,可以帮助您创建此传感器(请记住,像操作员一样使用传感器)。考虑到您向微服务发出请求,然后又发出另一个请求以检查作业状态(GET请求并检查200)的情况,您将扩展BaseSensorOperator像这样:

from airflow.operators.sensors import BaseSensorOperator
from airflow.utils.decorators import apply_defaults
from time import sleep
import requests

class HTTPSensorOperator(BaseSensorOperator): 
    """
    Pokes a URL until it returns 200
    """
    ui_color = '#000000'
    @apply_defaults
    def __init__( self, url, *args, **kwargs):
        super(HTTPSensorOperator, self).__init__(*args, **kwargs)
        self.url = url


    def poke(self, context):
        """
        GET request url and return True if response is 200, False otherwise
        """
        r = requests.post(self.url)
        if r.status_code == 200:
            return True
        else:
            return False

    def execute(self, context):
        """
        Check the url and wait for it to return 200.
        """
        started_at = datetime.utcnow()
        while not self.poke(context):
            if (datetime.utcnow() - started_at).total_seconds() > self.timeout:
                if self.soft_fail:
                    raise AirflowSkipException("Exporting {0}/{1} took to long.".format(self.project, self.instance))
                else:
                    raise AirflowSkipException("Exporting {0}/{1} took to long.".format(self.project, self.instance))
            sleep(self.poke_interval)
        self.log.info("Success criteria met. Exiting.")

然后使用像这样的运算符:

http_sensor_task = HTTPSensorOperator(
      task_id="http_sensor_task",
      url="http://localhost/check_job?job_id=1",
      timeout=3600, # 1 hour
      dag=dag
   )

因此,您必须决定您的微服务将如何与Airflow通信。就在我的脑海中,我想您会发出1个请求来触发工作,然后再发出一个请求(可能是10秒)来检查工作。祝你好运!