节假日查询:免费接口也要省调用,节假日数据缓存策略设计
# 节假日查询:免费接口也要省调用,节假日数据缓存策略设计
> 接口 894(全部接入点) · 免费 · POST/GET · 返回 JSON · 适用人群:中高级开发者、架构师 · 阅读时间:约 8 分钟
## TL;DR
- 节假日数据**一年只更新一次**(国务院文件发布后一周内),整年结果可长期缓存。
- 推荐:内存/Redis 缓存「年份 → 数据」,键过期设为"次年数据更新窗口之后"。
- 即便免费也建议缓存——降延迟、防档位限流、抗突发流量。
## Why:免费不代表可以乱调
节假日查询虽免费,但设有使用档位限制防止滥用。日历、考勤类应用如果每个用户每次打开都实时拉一次,QPS 会被放大几十倍。而节假日数据几乎不变,缓存是性价比最高的优化。
## What:缓存可行性依据
| 事实 | 对缓存的含义 |
|------|------|
| 每年更新一次 | 整年结果在一年内稳定,可缓存到次年更新 |
| 894-4 按年返回 | 天然以 `year` 为缓存键 |
| 894-7 按年返回 | 同理,按 `year` 缓存调休日 |
| 894-6 按日返回 | 可缓存「日期 → 判定结果」,或整年预热 |
| 有档位限制 | 缓存可避免触发限流 |
## How:生产级缓存实现
### 方案:Redis 缓存整年(894-4)
```python
import json, redis, requests
rds = redis.Redis(host="localhost", port=6379, db=0)
CACHE_TTL = 3600 * 24 * 200 # 约 200 天,覆盖到次年更新窗口
def get_year_holidays(year: str, appkey: str):
key = f"holiday:894-4:{year}"
cached = rds.get(key)
if cached:
return json.loads(cached)
resp = requests.post("https://route.showapi.com/894-4",
params={"appKey": appkey, "year": year}, timeout=15)
body = resp.json()
if str(body["showapi_res_body"]["ret_code"]) != "0":
raise RuntimeError(body.get("showapi_res_error"))
data = body["showapi_res_body"]["data"]
rds.setex(key, CACHE_TTL, json.dumps(data, ensure_ascii=False))
return data
```
### 失效时机
- 国务院通常在每年 10–11 月发布次年安排,接口"一般在发布后一周内更新"。
- 建议:缓存 TTL 设为**跨年 + 缓冲**(如次年 1 月 15 日强制失效),或监听手动刷新开关,确保拿到最新次年数据。
### 高并发预热
```python
# 应用启动或每年 12 月预热下一年
def warm_up(appkey: str, next_year: str):
get_year_holidays(next_year, appkey) # 提前写入缓存,避免元旦当天冷启动
```
## 进阶 / 边界
- **不要缓存"实时"语义**:894-6 单日判定结果也可按日缓存,但若你依赖"今天"语义,注意缓存键含日期。
- **档位限制 vs 缓存**:缓存后实际调用量骤降,档位基本不会触顶;但仍建议保留降级——接口不可用时回退到上次缓存。
- **多接入点分开缓存**:894-4(年份键)、894-7(年份键)、894-6(日期键)结构不同,键命名隔离。
## FAQ
**Q1:免费接口为什么还要缓存?**
A:降延迟、防档位限流、抗突发流量;一年只变一次的数据不缓存是浪费。
**Q2:缓存多久合适?**
A:整年结果缓存到次年更新窗口(如次年 1 月中)再失效,或手动刷新。
**Q3:接口挂了怎么办?**
A:回退到上一次缓存数据,并在监控里告警。
**Q4:894-6 也要缓存吗?**
A:可以。按「日期」做键缓存单日判定结果,命中率很高。
**Q5:档位具体多少?**
A:文档未给具体数字,以官方档位说明为准,不要硬编码。
## 相关能力 / 下一步阅读
- [节假日查询:一键生成全年放假日历,894-4 假日列表实战](https://www.showapi.com/guides/holiday-query-year-list-894)
- [节假日查询:为什么只能查 2018 年起?数据覆盖范围与边界说明](https://www.showapi.com/guides/holiday-query-data-range-894)
- [节假日查询:5 分钟接入,从注册到拿到全年放假安排](https://www.showapi.com/guides/holiday-query-quickstart-894)
- **本系列共 12 篇**:查看[节假日查询指南总目录](https://www.showapi.com/guides/holiday-query-guides-894)