Celery task 执行报错 TypeError: Object of type set is not JSON serializable 问题分析处理

情况描述:

定义了新的shared_task推送到生产环境后,发现无法执行,会报错set对象无法序列化,报错内容如下:

python 复制代码
Traceback (most recent call last):
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/serialization.py", line 50, in _reraise_errors
    yield
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/utils/json.py", line 70, in dumps
    **dict(default_kwargs, **kwargs))
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/__init__.py", line 412, in dumps
    **kw).encode(obj)
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/encoder.py", line 296, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/encoder.py", line 378, in iterencode
    return _iterencode(o, 0)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/utils/json.py", line 59, in default
    return super(JSONEncoder, self).default(o)
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/encoder.py", line 273, in default
    o.__class__.__name__)
TypeError: Object of type set is not JSON serializable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/venv/lib64/python3.6/site-packages/celery/app/trace.py", line 449, in trace_task
    uuid, retval, task_request, publish_result,
  File "/tmp/venv/lib64/python3.6/site-packages/celery/backends/base.py", line 149, in mark_as_done
    self.store_result(task_id, result, state, request=request)
  File "/tmp/venv/lib64/python3.6/site-packages/celery/backends/base.py", line 342, in store_result
    request=request, **kwargs)
  File "/tmp/venv/lib64/python3.6/site-packages/django_celery_results/backends/database.py", line 19, in _store_result
    content_type, content_encoding, result = self.encode_content(result)
  File "/tmp/venv/lib64/python3.6/site-packages/django_celery_results/backends/database.py", line 52, in encode_content
    content_type, content_encoding, content = self._encode(data)
  File "/tmp/venv/lib64/python3.6/site-packages/celery/backends/base.py", line 297, in _encode
    return dumps(data, serializer=self.serializer)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/usr/lib64/python3.6/contextlib.py", line 99, in __exit__
    self.gen.throw(type, value, traceback)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/serialization.py", line 54, in _reraise_errors
    reraise(wrapper, wrapper(exc), sys.exc_info()[2])
  File "/tmp/venv/lib64/python3.6/site-packages/vine/five.py", line 194, in reraise
    raise value.with_traceback(tb)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/serialization.py", line 50, in _reraise_errors
    yield
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/serialization.py", line 221, in dumps
    payload = encoder(data)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/utils/json.py", line 70, in dumps
    **dict(default_kwargs, **kwargs))
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/__init__.py", line 412, in dumps
    **kw).encode(obj)
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/encoder.py", line 296, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/encoder.py", line 378, in iterencode
    return _iterencode(o, 0)
  File "/tmp/venv/lib64/python3.6/site-packages/kombu/utils/json.py", line 59, in default
    return super(JSONEncoder, self).default(o)
  File "/tmp/venv/lib64/python3.6/site-packages/simplejson/encoder.py", line 273, in default
    o.__class__.__name__)
kombu.exceptions.EncodeError: Object of type set is not JSON serializable

初步分析

复制代码
a.考虑是task调用过程中,参数传输过程异常,导致参数无法序列化,因为set 就是{1,2} 这种格式的,命令行验证没问题
b.考虑是其他模块有异常,发现其他模块的定时任务能正常执行
c.在测试环境能完整复现,但是由于celery 的调用无法调试,无法得到有效的反馈
d.命令行直接执行task函数不会报错,所以函数逻辑应该没有问题
e.最终发现是结果集里面存在set集合,导致后续结果传输的过程中无法解析成json,至此问题确定

解决办法:

复制代码
将set转换成其他数据结构

总结:

复制代码
a.对于原先测试验证能通过,修改后无法验证通过的,要先找到变更的内容,修改后要验证
b.这次花费时间较长是因为认为原先验证过,认为后续小的修改没有影响,导致思路不对,修改代码要验证,不要过于自信
c.对于celery这种无法调试的调用过程,复现存在难度,那就需要从函数逻辑,返回结果里面找答案
d.可能会转换成json格式的数据,一定不能包含set集合
e.其他:@shared_task 注解的函数,会加载到内存里面,需要重启Celery才会重新加载
相关推荐
Patrick在香港4 分钟前
MCP 的 initialize 握手真的没了?67 行标准库实测 2026-07-28 规范
python·agent·claude·mcp·json-rpc
vx_Biye_Design7 分钟前
springboot角色扮演服务平台65161-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·python·spring·课程设计
追烽少年x10 分钟前
从零构建一个3D点云预览器:Python + PySide6 + pyqtgraph 实战
python·3d
weixin_4404016923 分钟前
质朴的爬虫+数据处理
爬虫·python·数据分析·pandas
估值探索者24 分钟前
【Python量化系统工程实战 #01】数据存储选型 CSVSQLiteMySQL 对比与 SQLite 实战建库
开发语言·jvm·python·sqlite·api接口·数据api接口·股票数据api接口
计算机毕业编程指导师28 分钟前
计算机毕设答辩技巧:基于Hadoop+Django的公共交通运营数据分析与可视化系统怎么做 源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
大数据·hadoop·python·spark·毕业设计·课程设计·交通运行
砚底藏山河29 分钟前
量化实战:行情数据 Schema 演进与向后兼容
java·python·金融·maven
苏离~Hack31 分钟前
InfoScraper:面向授权目标的一站式资产信息收集工具
python
计算机毕业编程指导师34 分钟前
【计算机毕设选题推荐】基于Hadoop+Django高频电力消耗大数据分析系统从0到1 源码 毕业设计 选题推荐 毕设选题 数据分析 机器学习
hadoop·python·数据分析·spark·毕业设计·课程设计·电力
FYKJ_201036 分钟前
springboot手工蜀绣在线销售系统60947-计算机课程设计、毕业设计
java·spring boot·后端·python·mysql·spark·课程设计