Django集成Celery执行同步任务时requests报JSONDecodeError如何解决?
错误原因
这个JSONDecodeError: Expecting value: line 1 column 1 (char 0)本质是requests调用.json()方法解析响应时,拿到的内容为空或者不是合法JSON格式,结合你在Celery任务中请求仓库/门店微服务接口的场景,常见触发原因有3类:
- Celery所在运行环境(多为Docker容器)的网络与仓库微服务不互通,无法解析
warehouse服务名,请求直接失败返回空内容/非JSON格式的错误页 - 仓库微服务接口需要鉴权,本地调试时你带了登录态(Cookie/Token),但Celery任务发起请求时没有携带认证信息,接口返回401/403状态的空响应或HTML错误页
- 仓库微服务有限流规则,Celery批量请求触发限流,返回空内容或非JSON的拦截提示
修复方案
第一步:先定位具体问题
先修改代码增加日志,打印请求的状态码和响应原文,确认错误根源:
把所有直接调用.json()的代码都先做响应校验,比如原来的:
response_author = requests.get(url=url).json()
修改为:
# 加超时防止请求卡死 response_author = requests.get(url=url, timeout=10) # 打印排查日志,上线后可以替换为项目的日志组件输出,截取前200字符避免日志过长 print(f"请求地址:{url},状态码:{response_author.status_code},响应原文:{response_author.text[:200]}") # 只有状态码正常时才转JSON if response_author.status_code == 200: response_author = response_author.json() else: raise Exception(f"接口请求失败,状态码{response_author.status_code}")
修改后重新跑Celery任务,根据日志就能确定是网络不通、鉴权失败还是限流问题。
第二步:对应场景修复
- 网络不通场景:确认Celery服务和仓库微服务在同一个Docker网络下,或者把请求地址里的
warehouse替换为仓库微服务的可访问IP/公网域名 - 鉴权失败场景:给requests请求增加认证头,示例如下:
headers = { "Authorization": "Bearer 你对接仓库微服务的接口认证Token" } response_author = requests.get(url=url, headers=headers, timeout=10)
- 限流触发场景:给任务增加重试逻辑,同时降低请求频率,示例使用
tenacity库实现重试:
from tenacity import retry, stop_after_attempt, wait_exponential @shared_task # 最多重试3次,间隔指数增长,避免频繁请求触发限流 @retry(stop=stop_after_attempt(3), wait=wait_exponential(multiplier=1, min=2, max=10)) def shop_sync(): # 原有任务逻辑不变
第三步:代码健壮性优化
后续所有调用第三方接口的逻辑都不要直接调用.json(),先做状态码校验和响应格式判断,避免接口异常时抛出模糊错误。
内容的提问来源于stack exchange,提问作者Hey it's Serge
相关产品推荐
相关产品推荐

