​ 当使用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. python练习题-1

    1.输出正方形 x=input("请输入:") x=int(x) for i in range(0,x): if (i==0) or (i==x-1): print("* ...

  2. Mock Server的搭建

    一.概述 我们系统与第三方开票系统有交互,场景是我们系统请求第三方开票系统,第三方开票系统根据我们的请求数据,生成开票信息然后返回发票号或异常信息,我们根据返回的信息做对应的处理.因为配合上存在一些障 ...

  3. 003——Netty之Buffer、Channel以及多路复用器Selector

    Buffer 1.缓冲区类型 2.缓冲区定义 (1)Buffer是一个对象,其中包含写入与读出的数据.是新IO与原IO的重要区别.任何情况下访问NIO中的数据都需要通过缓存区进行操作. (2)Buff ...

  4. 7.17 正则表达式 re模块

    在介绍正则表达式和re模块之前,先简要介绍一下 正则表达式与re模块的关系 1.正则表达式是一门独立的技术,任何语言均可使用 2.python中要想使用正则表达式需要通过re模块 正则表达式 元字符 ...

  5. 依赖注入在 dotnet core 中实现与使用:1 基本概念

    关于 Microsoft Extension: DependencyInjection 的介绍已经很多,但是多数偏重于实现原理和一些特定的实现场景.作为 dotnet core 的核心基石,这里准备全 ...

  6. JVM(十一):内存分配

    JVM(十一):内存分配 在前面的章节中,我们花了大量的篇幅去介绍 JVM 内的内存布局.对象在内存中的状态.垃圾回收的算法和具体实现等.今天让我们探讨一下对象是如何分配内存的. 堆内存划分 前面说过 ...

  7. $('div','li') 和 $('div , li') 和 $('div li') 区别

    $('div','li')是$(子,父),是从父节点里找子,而不是找li外面的div $('div , li')才是找所有的div和li,之间不存在父子关系 $('div li') 是找div里面所有 ...

  8. MongoDB 数据库的学习与使用

    MongoDB 数据库 一.MongoDB 简介(了解) ​ MongoDB 数据库是一种 NOSQL 数据库,NOSQL 数据库不是这几年才有的,从数据库的初期发展就以及存在了 NOSQL 数据库. ...

  9. MYSQL批量导入数据报:[Err] 2006 - MySQL server has gone away 解决方法

    使用values 后接批量数据插入,因mysql 系统参数设置导致失败(数据量过大).可通过临时修改系统参数来解决,对系统安全性无影响: set global max_allowed_packet=1 ...

  10. 通过视图实现自定义查询<持续完善中。。。>

    目前实现: ----普通查询路径 /viewShow/viewShow/list.htm ----Echarts查询路劲 /viewShow/viewShow/echarts.htm 1.自定义查询条 ...