技术博客
全国城市空气质量查询:免费额度下如何设计缓存策略节省调用

全国城市空气质量查询:免费额度下如何设计缓存策略节省调用

作者: 万维易源
2026-08-31
空气质量缓存策略免费额度Redis
# 全国城市空气质量查询:免费额度下如何设计缓存策略节省调用 > 接口/接入点:全国城市空气质量查询(apiCode=104)· 104-41/104-42 · 免费 · 返回 JSON · 适用人群:中高级开发者 · 阅读时间:约 7 分钟 ## 核心要点 - 接口虽免费,但每次调用仍计 1 次免费额度(`showapi_fee_num:1`),无节制轮询会快速耗尽档位。 - 空气质量半小时级变化,单城缓存 TTL 设为 30 分钟量级即可;排行榜可整表缓存刷新。 - 用城市名/`area_code` 作缓存 key,配合「缓存未命中才回源 + 失败兜底旧值」模式,既省钱又稳。 ## Why:为什么要缓存 免费不等于无限。若每个用户请求、每次前端刷新都直连接口,免费档位会被瞬间打满,导致正常用户拿不到数据。合理的缓存让「1000 次用户访问」可能只需「几次真实调用」,体验与成本双赢。 ## What:接口与额度事实 | 项 | 内容 | |----|------| | 计费 | 免费服务,每次调用计 1 额度(`showapi_fee_num:1`) | | 更新频率 | 文档口径约每半小时(具体以官方说明为准) | | 返回 | `showapi_res_body`,`ret_code==0` 成功 | ## How:单城缓存(Redis 示例) ```python import json, redis, requests r = redis.Redis() CACHE_TTL = 30 * 60 # 30 分钟 def get_air(city: str, appkey: str) -> dict: key = f"air:{city}" cached = r.get(key) if cached: return json.loads(cached) resp = requests.post( "https://route.showapi.com/104-42", params={"appKey": appkey}, data={"area": city}, timeout=10, ).json() body = resp.get("showapi_res_body", {}) if body.get("ret_code") != 0: old = r.get(key) # 失败兜底旧值 if old: return json.loads(old) raise RuntimeError(body.get("remark")) data = {"city": body["area"], "aqi": int(body["aqi"]), "quality": body["quality"], "pm25": int(body["pm2_5"])} r.setex(key, CACHE_TTL, json.dumps(data, ensure_ascii=False)) return data ``` ### 排行榜整表缓存 ```python def get_ranking(appkey: str) -> list: key = "air:ranking" cached = r.get(key) if cached: return json.loads(cached) resp = requests.post("https://route.showapi.com/104-41", params={"appKey": appkey}, timeout=10).json() body = resp.get("showapi_res_body", {}) if body.get("ret_code") != 0: old = r.get(key) return json.loads(old) if old else [] data = body["list"] r.setex(key, CACHE_TTL, json.dumps(data, ensure_ascii=False)) return data ``` ### cURL 速测(验证回源) ```bash curl -X POST "https://route.showapi.com/104-42?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" -d "area=%E6%88%90%E9%83%BD" ``` ## 返回示例与解析 查「成都」返回 `quality=良好`、`aqi=52`、`pm2_5=36`;该结果进入缓存后,30 分钟内同城的重复请求直接命中缓存,不再消耗额度。 ## 进阶 / 边界 - **TTL 选择**:空气质量变化慢,30 分钟 TTL 足够;若产品要求「更实时」,可缩短到 10~15 分钟,但务必权衡额度。 - **回源失败兜底**:接口偶发失败时用旧缓存,避免用户看到空白/报错;旧值可标注「数据可能延迟」。 - **多设备共享**:若多端共用同一 AppKey,缓存务必放在服务端共享层(Redis),而非各自本地。 - **额度监控**:建议统计真实调用次数,临近免费档位上限时降频或排队。 ## FAQ **Q1:免费接口为什么还要缓存?** 每次调用仍计 1 次免费额度,高频/多用户直连会快速耗尽档位,缓存是必要省钱手段。 **Q2:缓存多久合适?** 空气质量半小时级变化,30 分钟 TTL 是合理起点;具体频率以官方更新说明为准。 **Q3:缓存失败/接口挂了怎么办?** 用上一次成功缓存兜底,并提示「数据可能延迟」,不要直接报错。 **Q4:排行榜和单城能用同一套吗?** 可以,但 key 不同(单城按城市、排行榜单独 key),TTL 可一致。 ## 相关能力 / 下一步阅读 - [全国城市空气质量查询:在微信小程序 / 智能设备中展示空气质量](https://www.showapi.com/guides/air-quality-miniapp-104) - [全国城市空气质量查询:单城市实时查询集成指南(从请求到 UI 展示)](https://www.showapi.com/guides/air-quality-query-integration-104) - **本系列共 11 篇**:查看[全国城市空气质量查询 · 指南总目录](https://www.showapi.com/guides/air-quality-guides-104)