​ 当使用rabbitmq作为airflow的broker的时候,启动scheduler,即执行airflow scheduler命令的时候抛出以下异常:

Traceback (most recent call last):
File "/anaconda/anaconda3/bin/airflow", line 27, in <module>
args.func(args)
File "/anaconda/anaconda3/lib/python3.6/site-packages/airflow/bin/cli.py", line 818, in scheduler
......
......
File "/anaconda/anaconda3/lib/python3.6/site-packages/kombu/connection.py", line 494, in _ensured
return fun(*args, **kwargs)
File "/anaconda/anaconda3/lib/python3.6/site-packages/kombu/messaging.py", line 203, in _publish
mandatory=mandatory, immediate=immediate,
File "/anaconda/anaconda3/lib/python3.6/site-packages/librabbitmq/__init__.py", line 122, in basic_publish
mandatory or False, immediate or False,
TypeError: an integer is required (got type NoneType)

整体环境描述:

python3.6 + apache-airflow1.9.0 + rabbitmq 3.6

​ 因为使用redis作为broker是可以正常运行的,但是换成rabbitmq之后就出现了这种情况。尝试过对rabbitmq降版本,对airflow降低版本,发现依然无解,说明并不是软件版本兼容问题。

​ 于是进一步排查,单独使用celery4.x进行调试,发现celery可以正常运行,但是到了airflow下就出现问题,说明是配置问题。

​ 但是airflow的官方文档中配置是相当简陋的,而源码中相关的配置又相当的多,实在无法定位。于是采用最粗暴的做法,调试,但是服务器无法远程,没有外网端口,不能远程调试,而且airflow并不支持windows平台。于是只能通过日志调试:

首先,根据异常提示,说明有配置属性为空导致了这个异常,于是在异常处加上打印日志:

$ vi /anaconda/anaconda3/lib/python3.6/site-packages/librabbitmq/__init__.py
		......
......
if isinstance(body, tuple):
body, properties = body
elif isinstance(body, self.Message):
body, properties = body.body, body.properties
print("---------------------------------------")
print(self.channel_id)
print("---------------------------------------")
print(body)
print("---------------------------------------")
print(exchange)
print("---------------------------------------")
print(routing_key)
print("---------------------------------------")
print(properties)
print("---------------------------------------")
print(mandatory)
print("---------------------------------------")
print(immediate)
print("---------------------------------------")
#if properties["priority"] is None: 加上这一句后就不会抛出异常了
# properties["priority"] = 0
return self.connection._basic_publish(
self.channel_id, body, exchange, routing_key, properties,
mandatory or False, immediate or False,
)
......
......

打印结果如下:

---------------------------------------
1
---------------------------------------
b'\x80\x02}q\x00(X\x04\x00\x00\x00taskq\x01X1\x00\x00\x00airflow.executors.celery_executor.execute_commandq\x02X\x02\x00\x00\x00idq\x03X$\x00\x00\x0077410b3a-75c6-4ba0-a448-7048c029e80cq\x04X\x04\x00\x00\x00argsq\x05]q\x06X\xcc\x00\x00\x00airflow run example_passing_params_via_test_command run_this 2018-07-02T01:04:00 --local -sd /anaconda/anaconda3/lib/python3.6/site-packages/airflow/example_dags/example_passing_params_via_test_command.pyq\x07aX\x06\x00\x00\x00kwargsq\x08}q\tX\x07\x00\x00\x00retriesq\nK\x00X\x03\x00\x00\x00etaq\x0bNX\x07\x00\x00\x00expiresq\x0cNX\x03\x00\x00\x00utcq\r\x88X\t\x00\x00\x00callbacksq\x0eNX\x08\x00\x00\x00errbacksq\x0fNX\t\x00\x00\x00timelimitq\x10NN\x86q\x11X\x07\x00\x00\x00tasksetq\x12NX\x05\x00\x00\x00chordq\x13Nu.'
---------------------------------------
default
---------------------------------------
celery
---------------------------------------
{'reply_to': 'd0552f0c-b341-30b6-9edb-fa9599715d6c', 'correlation_id': '77410b3a-75c6-4ba0-a448-7048c029e80c', 'delivery_mode': 2, 'content_type': 'application/x-python-serialize', 'content_encoding': 'binary', 'headers': {}, 'priority': None}
---------------------------------------
None
---------------------------------------
None
---------------------------------------

因为mandatory和immediate是bool类型,且都尝试过给其设置值,但是依然报错,最后还为None的就剩下priority属性为None了。于是尝试在代码中对其设置一个int类型的值,结果再次运行并无异常,说明缺少优先级属性导致了这个问题, 于是可以在priority属性为None的时候给它一个默认值:

		......
......
if isinstance(body, tuple):
body, properties = body
elif isinstance(body, self.Message):
body, properties = body.body, body.properties
if properties["priority"] is None: #加上这一句后就不会抛出异常了
properties["priority"] = 0
return self.connection._basic_publish(
self.channel_id, body, exchange, routing_key, properties,
mandatory or False, immediate or False,
)
......
......

后续发现这样修改源码确实不会出现之前的问题,但是会出现

TypeError can't pickle memoryview objects

之类的异常,后确认是librabbitmq 2.0.0 + celery 4.x的兼容性问题,于是选择使用pyamqp协议而不是使用默认的amqp协议,具体操作就是将broker_url改为如下格式:

broker_url = pyamqp://cord:123456@10.55.63.51:5672//
### transport://userid:password@hostname:port/virtual_host

而将celery_result_backend改为其他实现,比如mysql:

celery_result_backend = db+mysql://af:123456@10.55.63.51/airflow

至此问题解决。

总结:

​ 在排查问题的时候需要针对问题深入排查,而不是无根据的臆测,要针对提示去逐步排查,而不是一味无目的去尝试。

​ 虽然该问题已解决,但是推测应该是缺失相关配置导致了这个问题,但是我加上了优先级相关的配置并不起作用,所以暂时通过修改源码修复这个问题。

Airflow:TypeError an integer is required (got type NoneType) 一次诡异问题排查的更多相关文章

  1. Pycharm:设置完Anaconda后报错TypeError: an integer is required (got type bytes)

    背景:安装了最新版本的Anaconda3.9后,在Pycharm中设置Python Interpreter为这个最新版本Anaconda文件下的python.exe后,控制台无法启动并报错TypeEr ...

  2. python使用open经常报错:TypeError: an integer is required的解决方案

    错误是由于从os模块引入了所有的函数导致的,os模块下有一个open函数,接受整型的文件描述符和打开模式,from os import *引入os模块的open函数,覆盖了python内建的open函 ...

  3. 【Selenium+Python Webdriver】报错之:TypeError: user_login() missing 1 required positional argument: 'self'

    先贴一下源码: base.py文件如下: from selenium import webdriver class Page(object): ''' 页面基础类,用于所有页面的继承 ''' rb_u ...

  4. python3.5安装pyHook,解决【TypeError: MouseSwitch() missing 8 required positional arguments: 'msg', 'x', 'y', 'data', 'time', 'hwnd', and 'window_name'】这个错误!

    为什么安装 pyHook包:为Windows中的全局鼠标和键盘事件提供回调. Python应用程序为用户输入事件注册事件处理程序,例如鼠标左键,鼠标左键,键盘键等 先要实时获取系统的鼠标位置或者键盘输 ...

  5. TypeError: Fetch argument 0 has invalid type <type 'int'>, must be a string or Tensor. (Can not convert a int into a Tensor or Operation.)

    6月5日的時候,修改dilated_seg.py(使用tensorflow)出現了報錯: TypeError: Fetch argument 0 has invalid type <type ' ...

  6. Django关联数据库时报错TypeError: __init__() missing 1 required positional argument: 'on_delete'

    sgrade = models.ForeignKey("Grades",) 执行python manage.py makemigrations后出现TypeError: __ini ...

  7. TypeError: Fetch argument None has invalid type <type 'NoneType'>

    (fetch, type(fetch)))TypeError: Fetch argument None has invalid type <type 'NoneType'> 我的解决方案是 ...

  8. TypeError: only integer scalar arrays can be converted to a scalar index

    TypeError: only integer scalar arrays can be converted to a scalar index 觉得有用的话,欢迎一起讨论相互学习~Follow Me ...

  9. Django问题 TypeError: __init__() missing 1 required positional argument: 'on_delete'

    问题:在执行python manage.py makemigrations learning_logs时,系统会报错,提示:TypeError: __init__() missing 1 requir ...

随机推荐

  1. java之异常详解

    一.什么是异常? 异常就是有异于常态,和正常情况不一样,有错误出错.在java中,阻止当前方法或作用域正常运行的情况,称之为异常. 二.异常体系 Java把异常当作对象来处理,并定义一个基类java. ...

  2. Elasticsearch由浅入深(一)

    什么是Elasticsearch 什么是搜索 百度:我们比如说想找寻任何的信息的时候,就会上百度去搜索一下,比如说找一部自己喜欢的电影,或者说找一本喜欢的书,或者找一条感兴趣的新闻(提到搜索的第一印象 ...

  3. 试试 python-dotenv,避免敏感信息被硬编码到代码中

    我们开发的每个系统都离不开配置信息,例如数据库密码.Redis密码.邮件配置.各种第三方配置信息,这些信息都非常敏感,一旦泄露出去后果非常严重,被泄露的原因一般是程序员将配置信息和代码混在一起导致的. ...

  4. Go组件学习——database/sql数据库连接池你用对了吗

    1.案例 case1: maxOpenConns > 1 func fewConns() { db, _ := db.Open("mysql", "root:roo ...

  5. bilibili弹幕爬取与比对分析

    最近受人之托研究了下b站的数据爬取做个小工具,最后朋友说不需要了,本着开源共享的原则,将研究成果与大家分享一波,话不多说直接上干货 需求分析 给定up主uid和用户uid,爬取用户在该up主所有视频中 ...

  6. 玩转SpringBoot 2 快速搭建 | Spring Initializr 篇

    SpringBoot 为我们提供了外网 Spring Initializr 网页版来帮助我们快速搭建 SpringBoot 项目,如果你不想用 IDEA 中的插件,这种方式也是不错的选择.闲话少说,直 ...

  7. Zabbix-3.4快速安装

    过多的介绍不写了,本篇文章主要是快速安装下zabbix服务,如果不知道zabbix监控原理,可以先去了解下. 用的是Centos7.2系统安装的zabbix-3.4 1.下载Zabbix-releas ...

  8. JSON转换方法解析

    JSON.parse() 与 JSON.stringify() 的区别 JSON.parse() :是从一个字符串中解析出 json 对象 JSON.stringify():是从一个对象中解析出字符串 ...

  9. Storm 系列(五)—— Storm 编程模型详解

    一.简介 下图为 Strom 的运行流程图,在开发 Storm 流处理程序时,我们需要采用内置或自定义实现 spout(数据源) 和 bolt(处理单元),并通过 TopologyBuilder 将它 ...

  10. JUC包实现的同步机制,原理以及简单用法总结

    除了用Synchronized关键字修饰同步块,让线程获取某对象的锁实现多线程操作共享变量的同步外,还可以使用java.util.concurrent包.并且,juc包机制下的同步更灵活.juc包的所 ...