技术博客
国际原油价格查询:免费档位下如何设计缓存节省调用成本?

国际原油价格查询:免费档位下如何设计缓存节省调用成本?

作者: 万维易源
2026-09-02
国际原油价格查询原油价格APIWTI原油布伦特原油免费接口
# 国际原油价格查询:免费档位下如何设计缓存节省调用成本? > 接口:国际原油价格查询(apiCode=1108,接入点 1108-1)| 免费(有档位限制)| 请求方式 POST/GET | 返回 JSON | 适用人群:中高级开发者、架构师 | 阅读时间:约 7 分钟 ## 核心要点 - 接口免费但有使用档次限制,无脑高频调用会很快耗尽额度。 - 数据每小时整点更新,缓存 TTL 设为 55~60 分钟即可,绝大多数读请求命中缓存。 - 多实例用共享缓存(Redis)统一拉取,避免重复消耗;配合错峰与限流更进一步。 ## Why 免费意味着"额度有限"。如果你的看板、监控、推送都直接打接口,很容易在一天内把档位额度用光,导致后续调用失败。好在数据每小时才更新一次——只要把"读"和"拉"分开(读走缓存、拉按整点),就能把一天的调用量从几十万次压到 24 次(每种 `code` 各一次)。本文给出生产级缓存设计。 ## What | 项目 | 说明 | |------|------| | 成本来源 | 按次调用,免费档位有上限 | | 最优拉取频率 | 每小时一次(对齐整点更新) | | 缓存目标 | 让 99% 以上的读请求不触达接口 | ## How ### 生产级缓存设计(Redis + 单飞) ```python import redis, requests, time APP_KEY = "YOUR_APPKEY" URL = "https://route.showapi.com/1108-1" rds = redis.Redis(host="localhost", port=6379, db=0) TTL = 55 * 60 # 秒 def get_quote(code="wti"): key = f"oil:{code}" cached = rds.get(key) if cached: return cached.decode("utf-8") # 命中缓存 # 缓存未命中:拉接口(生产环境建议加"单飞"避免并发击穿) resp = requests.get(URL, params={"appKey": APP_KEY, "code": code}, timeout=10).json() body = resp["showapi_res_body"] if body["ret_code"] != 0: raise SystemExit("失败") payload = str(body) rds.setex(key, TTL, payload) return payload ``` ### 令牌桶限流(防止突发打爆) ```python import time class TokenBucket: def __init__(self, rate, capacity): self.rate, self.capacity = rate, capacity self.tokens = capacity self.ts = time.time() def allow(self): now = time.time() self.tokens = min(self.capacity, self.tokens + (now - self.ts) * self.rate) self.ts = now if self.tokens >= 1: self.tokens -= 1 return True return False bucket = TokenBucket(rate=1/3600, capacity=2) # 每小时约 1 次,突发上限 2 ``` **Node.js(fetch + 内存缓存)** ```javascript const APP_KEY = "YOUR_APPKEY"; const cache = new Map(); async function getQuote(code = "wti") { const hit = cache.get(code); if (hit && hit.expire > Date.now()) return hit.value; const r = await fetch( "https://route.showapi.com/1108-1?appKey=" + APP_KEY, { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: "code=" + code, signal: AbortSignal.timeout(10000), } ).then((x) => x.json()); if (r.showapi_res_body.ret_code !== 0) throw new Error("失败"); cache.set(code, { value: r.showapi_res_body, expire: Date.now() + 55 * 60 * 1000 }); return cache.get(code).value; } ``` ## 返回示例与解析 缓存的内容即 `showapi_res_body` 整个对象(含 `nowPrice`/`diff_rate`/`time` 等)。每次整点后缓存过期,下一次读触发重新拉取并刷新。 ## 进阶 / 边界 - **共享缓存优先**:多实例部署务必用 Redis 等共享缓存,否则每台机器各自拉取会成倍消耗额度。 - **错峰拉取**:若拉多种 `code`,可在整点后错开几秒分别拉,降低瞬时压力。 - **额度告警**:建议监控每日调用量,接近档位上限时降级(如只保留核心 `code`)。 - **档位数字以官方为准**:具体免费档位阈值文档未给出,请见 [免费档位说明](https://www.showapi.com/free-api)。 ## FAQ **Q:免费额度用完了会怎样?** 按文档说明,超出使用档次限制后调用会受限制;具体表现以接口/控制台提示为准,建议提前用缓存压低调用量。 **Q:缓存 TTL 设多少最省?** 对齐整点更新,设 55~60 分钟;过短会多调接口、过长会延迟拿到新值。 **Q:单实例和多实例缓存有区别吗?** 有。多实例各自缓存会重复拉取,应用 Redis 等共享缓存统一拉取。 **Q:WTI 和布伦特要算两次额度吗?** 是,两种 `code` 各一次请求;都在整点拉取,一天各 24 次。 ## 相关能力 / 下一步阅读 - [国际原油价格查询:整点更新意味着什么?数据时效与缓存设计](https://www.showapi.com/guides/crude-oil-price-update-frequency-1108) - [国际原油价格查询:如何用数据搭建实时油价看板?从拉取到可视化](https://www.showapi.com/guides/crude-oil-price-dashboard-1108) - [国际原油价格查询:原油涨跌监控与趋势预警搭建指南](https://www.showapi.com/guides/crude-oil-price-alert-1108) - **本系列共 12 篇**:查看[国际原油价格查询官方指南总目录](https://www.showapi.com/guides/crude-oil-price-guides-1108)