今日油价数据什么时候刷新?用 ct 字段判断缓存是否过期

约 11 分钟 进阶今日油价ct字段缓存刷新调价日
# 今日油价数据什么时候刷新?用 ct 字段判断缓存是否过期 接口/接入点:今日油价(apiCode=138)· 查询油价(138-46)/ 查询行情(138-49) · 免费 · 适用人群:中高级开发者 · 阅读时间:约 5 分钟 · 最后实测核对:2026-09-18 缓存设成固定 24 小时,起算时刻随用户访问时间漂移,过期点就会偏离数据刷新点。判断数据是否换批,用接口返回的 `ct` 比较更直接。 ## 核心要点 - `ct` 是接口侧这批数据的生成时间,2026-09-18 实测返回 `2026-09-18 12:00:05.916`,同一批 31 条记录取值一致。 - 产品说明写的同步口径是每日凌晨 7 点,与实测 `ct` 不是同一个时点,因此不建议把 TTL 硬编码到某个整点。 - 查询行情(138-49)的 `next_change_time` 是下一次调价日,可用来在调价窗口前后主动刷新缓存。 ## 两个时间字段的分工 | 字段 | 来源接入点 | 含义 | 实测值 | |---|---|---|---| | `ct` | 查询油价(138-46) | 这批数据的生成时间 | `2026-09-18 12:00:05.916` | | `before_change_time` | 查询行情(138-49) | 最近一次调价日 | `20260912` | | `next_change_time` | 查询行情(138-49) | 下一次调价日 | `20260925` | `ct` 描述数据是什么时候生成并写入接口的,`next_change_time` 描述成品油调价窗口。两者不是一回事。 ## 按 ct 判断是否换批 思路是缓存里一并存下 `ct`,回源后比对:变了就替换数据,没变就只续期。这样不依赖刷新时刻。 Python(requests + Redis): ```python import json import requests import redis rds = redis.Redis(host="localhost", port=6379, db=0) KEY = "oil:138:46:snapshot" def fetch(): resp = requests.post( "https://route.showapi.com/138-46", data={"appKey": "YOUR_APPKEY"}, timeout=5, ).json() if resp.get("showapi_res_code") != 0: raise RuntimeError(resp.get("showapi_res_error")) body = resp["showapi_res_body"] if body.get("ret_code") != 0: raise RuntimeError(body.get("remark")) return body["list"] def refresh(ttl_seconds=3600): """回源后比较 ct:变化则替换数据,未变化只续期。""" fresh = fetch() fresh_ct = fresh[0]["ct"] cached = rds.get(KEY) if cached: old = json.loads(cached) if old.get("ct") == fresh_ct: rds.expire(KEY, ttl_seconds) # 同一批数据,只延后过期 return old["list"], False rds.setex(KEY, ttl_seconds, json.dumps({"ct": fresh_ct, "list": fresh}, ensure_ascii=False)) return fresh, True items, changed = refresh() print(f"数据时间 {items[0]['ct']},本次{'已更新' if changed else '沿用缓存'}") ``` cURL: ```bash # 取数据并观察 ct curl -X POST "https://route.showapi.com/138-46?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" -d "prov=%E5%8C%97%E4%BA%AC" # 取调价日,用于调价窗口前主动刷新 curl -X POST "https://route.showapi.com/138-49?appKey=YOUR_APPKEY" \ -H "content-type: application/x-www-form-urlencoded" -d "prov=%E5%8C%97%E4%BA%AC" ``` Node.js(fetch): ```javascript const API = "https://route.showapi.com/138-46"; async function fetchWithCt() { const resp = await fetch(API, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ appKey: "YOUR_APPKEY" }), signal: AbortSignal.timeout(5000), }); const body = (await resp.json()).showapi_res_body; if (body.ret_code !== 0) throw new Error(body.remark); return { ct: body.list[0].ct, list: body.list }; } const { ct, list } = await fetchWithCt(); console.log(`数据生成于 ${ct},共 ${list.length} 条`); // 下一次回源时比较 ct 是否变化,决定是否替换缓存 ``` ## 调价窗口前主动刷新 调价日当天价格会变,这时按常规 TTL 等过期就会晚几个小时才更新。用查询行情(138-49)的 `next_change_time` 做补充:接近这个日期时清掉缓存,强制回源。 ```python from datetime import datetime, date def cache_key(prov="__all__"): return f"oil:138:46:{prov}" def should_invalidate(prov="北京"): """临近调价日时返回 True,提醒清缓存。""" resp = requests.post( "https://route.showapi.com/138-49", data={"appKey": "YOUR_APPKEY", "prov": prov}, timeout=5, ).json() next_change = datetime.strptime(resp["showapi_res_body"]["next_change_time"], "%Y%m%d").date() return (next_change - date.today()).days <= 1 if should_invalidate(): rds.delete(cache_key()) # 全量快照与单省缓存按你的 key 设计一并清理 ``` ## 适用条件与注意事项 - `ct` 是数据生成时间,不是调价公告时间,也有别于 `next_change_time`。 - 2026-09-18 实测同一批 31 条记录的 `ct` 集中在两个毫秒值,属同批写入,取第一条比较即可。 - 产品说明的同步口径为每日凌晨 7 点。实测 `ct` 落在中午,单日单次样本不足以推断长期规律,用比较 `ct` 变化的方式判断是否换批,不依赖具体时刻。 - 查询行情(138-49)的 `prov` 必填,只做调价日判断时随便传一个标准省名即可。 - 定时任务与实时请求共用同一档位额度,把回源收敛到一处更省。 ## FAQ **Q1:缓存设 24 小时为什么会拿到旧数据?** 从访问时刻起算的 24 小时与数据刷新时刻不对齐,过期点会落在刷新点之后。改用比较 `ct` 的方式判断,不依赖起算时刻。 **Q2:怎么知道数据已经是新的?** 看 `ct`。缓存与新回源结果的 `ct` 不同就说明换批了。 **Q3:定时任务放在几点跑?** 不必绑定某个整点。按小时级周期跑,每次比较 `ct`,变了才替换数据。 **Q4:调价日当天要不要特殊处理?** 建议处理。用查询行情(138-49)的 `next_change_time`,在临近调价日时清一次缓存。2026-09-18 实测北京、广西、重庆、吉林四省的 `next_change_time` 都是 `20260925`。 **Q5:`before_change_time` 有什么用?** 它是最近一次调价日。做「上次调价距今多少天」这类展示时用它,`ct` 不能替代。 ## 相关能力 / 下一步阅读 - [今日油价调用量规划:缓存粒度与 TTL 的确定方式](https://www.showapi.com/guides/oilprice-cache-138) - [今日油价涨跌幅怎么查?查询行情接入点的调价日与涨跌率用法](https://www.showapi.com/guides/oilprice-trend-138) - [今日油价:一次调用取回全国 31 省油价的做法](https://www.showapi.com/guides/oilprice-province-list-138) - **本系列共 13 篇**:查看[今日油价指南总目录](https://www.showapi.com/guides/oilprice-guides-138)
加载中...