[Bug] 社区版源码部署时,Celery 自定义序列化器默认密钥是 UUID 对象,导致所有异步任务无法投递

未關閉 適合新手
#7,780 0 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

還沒有人認領這個 Issue。

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
76/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
python

研究方向

從 apps/ops/celery/hmac_signed_serializer.py 開始,追蹤在 secure_dumps 呼叫 .encode() 之前 _local_secret_key 是如何選定的。使用 issue 中的獨立腳本重現故障,然後檢查這個序列化器附近的測試或啟動檢查。當預設金鑰以字串形式正常運作,且無需環境變數即可成功序列化時,工作就完成了。

由索引模型根據 Issue 內容生成。

描述

环境

  • MaxKB 版本:2.10.8(镜像)/ 源码 HEAD 2ac52b3(2026-11-09)仍在
  • 部署方式:Docker Engine(WSL2),从源码构建,未使用官方商用镜像(无 xpack)
  • Python 3.11,celery 5.5.3,uuid-utils 0.14.0
  • 相关文件:apps/ops/celery/hmac_signed_serializer.py

现象

文档上传成功、记录能创建,但永远停在「待处理 / 0 段落」,后台不执行任何向量化任务。
前端无任何报错,日志中仅有一行被吞掉的 AttributeError。

排查后确认:所有 Celery 任务都无法投递(不只是文档解析)。

根因

apps/ops/celery/hmac_signed_serializer.py:

import uuid_utils.compat as uuid
...
_local_secret_key = os.environ.get(
    'MAXKB_HMAC_SIGNED_SERIALIZER_SECRET_KEY',
    os.getenv('MAXKB_SECRET_KEY', uuid.uuid7())   # ← 默认值是 UUID 对象,不是 str
)
...
def secure_dumps(obj):
    data = pickle.dumps(obj)
    signature = hmac.new(_local_secret_key.encode(), data, hashlib.sha256).digest()
    #                        ^^^^^^^^ UUID 没有 encode() → AttributeError

uuid_utils.compat.uuid7() 的返回值是 uuid.UUID 对象(已实测,见下),没有 .encode() 方法。

日志里没有明显报错,是因为任务投递点被 try/except 包住,
异常只落一条 error 日志,文档状态停在「待处理」——用户侧看起来就是「卡住了」。

复现

不启动 Django / Celery / Redis,直接加载上面这个真实文件即可复现:

import sys, types, importlib.util
kombu = types.ModuleType('kombu'); ser = types.ModuleType('kombu.serialization')
ser.register = lambda *a, **k: None
kombu.serialization = ser
sys.modules['kombu'] = kombu; sys.modules['kombu.serialization'] = ser

spec = importlib.util.spec_from_file_location(
    's', 'apps/ops/celery/hmac_signed_serializer.py')
m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m)
m.secure_dumps({'task': 'x'})

输出:

_local_secret_key : type='UUID'  value=UUID('80d34868-8213-47e9-b353-e0fadd316c1c')
AttributeError: 'UUID' object has no attribute 'encode'
  File ".../apps/ops/celery/hmac_signed_serializer.py", line 17, in secure_dumps

设置环境变量后正常:

$ MAXKB_HMAC_SIGNED_SERIALIZER_SECRET_KEY=dev-secret python repro.py
_local_secret_key : type='str'  value='dev-local-secret'
secure_dumps(...) -> OK, 185 bytes

期望

  1. 默认值应转换为 str,例如:
_local_secret_key = os.environ.get(
    'MAXKB_HMAC_SIGNED_SERIALIZER_SECRET_KEY',
    os.getenv('MAXKB_SECRET_KEY') or str(uuid.uuid7())
)
  1. 建议在 ok/启动自检里显式校验 _local_secret_key 类型,或至少把它变成显式必填配置,
    避免不同部署方式(源码 / 官方镜像 / 含 xpack 的版本)表现不一致。

临时规避

-e MAXKB_HMAC_SIGNED_SERIALIZER_SECRET_KEY=<任意字符串>

补充说明(供维护者判断)

  • 该文件第 9–13 行有一个 from xpack import get_md5 的兜底:
    含 xpack 的版本会用它覆盖密钥,因此官方商用镜像可能不受影响;
    而源码构建 / 自行打镜像的社区用户会稳定踩到。
  • MAXKB_SECRET_KEY 在全仓库中除本文件外没有任何写入点(README 的 docker run
    也不传它),所以未设置环境变量是默认路径。
主要語言
Python
星號
23.1k
分支
3.2k
平均合併
41 分鐘
30 天內合併 PR
480

環境準備

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

1Panel-dev/MaxKB 的其他 Issue

查看 1Panel-dev/MaxKB 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。