字典查询(免费档位):如何设计缓存与降级避免触达调用上限
# 字典查询(免费档位):如何设计缓存与降级避免触达调用上限
> 元信息:接口 **字典查询**(apiCode 1524)· 免费服务(档位限额)· 适用:已在用或准备上线的开发者 · 阅读时间约 7 分钟
## 核心要点
- 字典查询是**免费但有档位限额**的接口,超额会被限流;字典数据变化极低,极适合缓存。
- 静态数据(拼音表、部首表、常用字详情)本地/Redis 缓存,可把接口调用量降到「仅查未命中」。
- 接口不可用时降级到本地词库,保证查字功能不中断。
## Why:为什么免费接口也要做缓存
免费不代表无限。档位限额按调用量约束,高频或突发流量容易触顶,触顶后查询失败影响用户体验。字典数据(一个字的部首、笔画几乎不变)天然适合缓存——命中缓存就完全不消耗额度,既省钱(额度)又提速。
## What:前置条件与接口速览
| 项 | 值 |
|----|----|
| 接口 | 字典查询 1524(含 6 接入点) |
| 计费 | 免费,档位限额(额度见 [免费档位说明](https://www.showapi.com/free-api)) |
| 缓存友好度 | 高:单字/词语释义更新频率极低 |
| 降级需求 | 中:接口不可用时需有兜底 |
## How:缓存与降级设计
### 步骤 1:本地内存缓存(轻量方案)
```python
import requests, time
APP_KEY = "YOUR_APPKEY"
cache = {} # hanzi -> (timestamp, payload)
TTL = 86400 * 30 # 30 天,字典数据几乎不变
def get_char(hanzi: str):
now = time.time()
if hanzi in cache and now - cache[hanzi][0] < TTL:
return cache[hanzi][1] # 命中,零调用
r = requests.post("https://route.showapi.com/1524-5",
params={"appKey": APP_KEY}, data={"hanzi": hanzi},
headers={"content-type": "application/x-www-form-urlencoded"},
timeout=10)
rb = r.json().get("showapi_res_body", {})
if rb.get("ret_code") != "0":
# 降级:返回本地最小词库(如有)或提示
return LOCAL_FALLBACK.get(hanzi)
cache[hanzi] = (now, rb)
return rb
```
### 步骤 2:Redis 缓存(多实例共享)
```python
import redis, json, requests
rds = redis.Redis(host="localhost", port=6379, db=0)
def get_char_redis(hanzi: str):
key = f"dict:char:{hanzi}"
hit = rds.get(key)
if hit:
return json.loads(hit) # 命中,零调用
rb = query_api(hanzi) # 见上
if rb:
rds.set(key, json.dumps(rb), ex=86400*30)
return rb
```
> key 设计:`dict:char:{hanzi}`、`dict:pinyin:{pinyin}`、`dict:radical:{bushou}`、`dict:word:{ciyu}`,按接入点分命名空间,便于分别失效。
### 步骤 3:降级兜底
```python
LOCAL_FALLBACK = { # 仅覆盖最常用字,作为接口不可用时的兜底
"你": {"hanzi":"你","pinyin":"nǐ","bushou":"亻","bihua":"7"},
}
def query_with_fallback(hanzi):
try:
return get_char_redis(hanzi) or LOCAL_FALLBACK.get(hanzi)
except Exception:
return LOCAL_FALLBACK.get(hanzi) # 接口/网络异常时降级
```
## 返回示例与字段解析
被缓存的是 `showapi_res_body` 完整对象(见[字典查询:返回字段全解](https://www.showapi.com/guides/dict-response-codes-1524)),包含 `ret_code`、`hanzi`、`pinyin`、`bushou`、`bihua`、`wubi`、`words`、`basic_explain`、`detail_explain`。
## 进阶 / 边界
- **预热能显著降低首屏延迟**:上线前批量预热高频字(如小学语文常用 2500 字),把热门查询全部转入缓存。
- **TTL 设长但可手动刷新**:字典数据可设 30 天甚至更长 TTL;教材改版时主动清缓存。
- **批量预热注意档位**:预热是真实调用,需错峰、限速,避免一次性打满免费档位。
- **不要缓存失败结果**:`ret_code != "0"` 的结果不入缓存,避免污染。
## FAQ
**Q1:免费接口做缓存能省什么?**
省的是「免费档位额度」——命中缓存不消耗调用次数,避免触达限额后被限流;同时降低延迟。
**Q2:缓存要设多久?**
字典数据极稳定,可设 30 天以上 TTL;遇到教材改版或数据修正时主动清对应 key。
**Q3:接口挂了用户会看到报错吗?**
不会,若配置了本地兜底词库,查不到缓存时回退到本地最小词库,保证核心查字可用。
**Q4:预热能用接口批量拉吗?**
可以,但预热本身是真实调用,注意档位限额,建议错峰、限速执行。
## 相关能力 / 下一步阅读
- [字典查询:5 分钟接入,从注册到查出第一个汉字详情](https://www.showapi.com/guides/dict-quickstart-1524)
- [字典查询:教育类高并发场景下的汉字查询缓存架构](https://www.showapi.com/guides/dict-high-concurrency-1524)
- [字典查询:返回字段全解,ret_code 与 showapi_res_body 一文读懂](https://www.showapi.com/guides/dict-response-codes-1524)
- **本系列共 12 篇**:查看[字典查询指南总目录](https://www.showapi.com/guides/dict-guides-1524)