用户登录

技术文章

外部链接将在新标签页打开。

随机图片 API 的随机性放在哪一层:缓存命中、去重与降级的取舍

一句话回答

随机图片 API 的关键设计决策是随机发生在服务端、调用方还是中间层,这直接决定缓存命中率、去重成本与可复现性。把随机值约束在有限集合(随机池)可以同时保住命中率与多样性;要求不重复就必须引入状态,并先确定可接受的重复窗口。图片尺寸、格式参数、缓存许可与配额等细节,本文没有可核验的文档来源,需以服务方官方说明为准。

随机图片 API 看起来只是“每次返回一张图”,但真正决定体验的是随机发生在哪一层:服务端、调用方,还是中间代理。选错层,缓存命中率、去重能力和可复现性会同时受损。本文只讨论这些通用取舍;涉及 API.PLUS 的具体端点、参数名、配额与授权条款,本文写作时没有取得可核验的文档,需以其官方说明为准。

随机的三个位置与各自代价#

随机位置好处代价
服务端每次请求随机接入最简单,调用方无状态同一 URL 的响应不可复用,边缘缓存命中率接近零;同一地址重复请求也可能拿到不同图
调用方先取清单再本地抽样清单可缓存,抽样策略自己定,容易做权重多一次请求;清单会过期;清单规模受响应体限制(上限待核实)
中间层维护图片池池大小、去重、格式转换都可控要自建存储与更新机制,并且必须先确认上游条款是否允许转存或中转,不能默认允许

缓存键与随机的冲突#

浏览器和 CDN 按 URL(以及 Vary 等响应头)区分缓存。如果每次请求都带一个新的随机参数,缓存永远不命中;如果把这个参数从缓存键里剔除,所有请求又会拿到同一张图。这两个极端都不理想,常见的折中是:

  • 有限随机池:把随机值约束在固定集合内(例如 seed 取 0 到 N-1),缓存键空间有限,命中率与多样性可以同时保住。
  • 分层缓存:清单或元数据可以长缓存,图片本体则按它自己的 Cache-Control 处理,两者生命周期分开设定。
  • 不擅自长缓存图片响应:中间层能否缓存、TTL 多长,取决于服务方是否允许,这一项本文标为待核实。

去重与“看起来随机”是两件事#

独立均匀抽样必然出现重复。要做到“不重复”,就必须引入状态:客户端记录已见 ID 的集合,在多实例部署下还得共享存储,读改写会带来一致性问题。

建议先定可接受的重复率与窗口,例如“最近 N 次内不重复”,再决定状态放在服务端、共享缓存还是单机内存。如果只要求观感上足够随机,就不必上共享去重,否则会为很小的收益付出跨实例同步的成本。

图片本身的成本#

  • 优先取接近展示尺寸的图,避免下载大图再缩略;是否支持尺寸参数取决于服务方(待核实)。
  • 格式上 WebP、AVIF 通常比 JPEG 更省流量,但要准备不支持时的回退路径。
  • 随机接口失败不应阻塞页面主内容,客户端要设超时与占位图。
  • 移动端或流量敏感场景,限制预取数量。

一个调用骨架(未执行)#

下面的示例只演示超时与错误处理应放在哪里,未实际运行;端点、鉴权头与返回结构都是占位,不是真实接口。

import requests

URL = "https://api.example.com/random"   # 占位端点,非真实地址
HEADERS = {"Authorization": "Bearer YOUR_KEY"}

def fetch_one(timeout=3.0):
    r = requests.get(URL, headers=HEADERS, timeout=timeout)
    r.raise_for_status()          # 非 2xx 直接抛错,交给上层降级
    return r.content              # 若响应是含图片 URL 的 JSON,需按文档解析

上线前要确认的几件事#

为了不把假设写进架构,至少确认:随机是否在服务端发生、响应是否允许被 CDN 缓存及 TTL、是否提供图片清单或稳定 ID、是否有尺寸与格式参数、配额与超限后的状态码。这些在本文写作时没有可核验的文档来源,均标为待核实。在没有依据之前,不要凭猜测设定缓存 TTL、重试次数或并发上限。

顺序上,先定随机放在哪一层,再谈缓存、去重与降级;反过来做,通常要返工。

作者:沐小悠

本文约 4 分钟读完 · 关键词:随机图片 API、动漫壁纸 API、缓存键、CDN 缓存、去重

更多文章 GET 示例接口

「」标签下的其他文章