Clojure使用clojure.core.cache.wrapped按cid缓存API调用失效问题
Clojure GET接口缓存不生效排查方案
根因定位
你的缓存未生效的核心原因是缓存加载函数没有返回有效接口响应,导致缓存值始终无法写入:
- Clojure 函数的返回值为函数体内最后一个表达式的执行结果,当前
get-data函数的最后一行是(println response),该表达式固定返回nil clojure.core.cache.wrapped/lookup-or-miss默认不会将加载函数返回的nil写入缓存,因此每次相同cid的请求进入时,缓存始终查不到对应值,会重复触发接口调用。
其他需要排查的边缘场景
- 确认缓存实例为全局单例:当前代码用顶层
def定义my-cache是正确的,禁止将缓存初始化逻辑(cw/ttl-cache-factory调用)写在请求处理函数内部,否则每次请求都会生成全新的空缓存,永远无法命中 - 确认TTL配置符合预期:当前配置的
:ttl 60000代表缓存值60秒后自动过期,若相同cid的请求间隔超过60秒,触发重新请求属于正常逻辑 - 并发击穿场景:如果高并发下同一个cid的请求同时在缓存未加载时到达,可能出现少量重复请求,属于TTL缓存的正常表现,如需强防击穿可以额外加锁控制。
修复后可直接运行的代码
(:require [clojure-mauth-client.request :refer [get!]] [clojure.core.cache.wrapped :as cw]) ;; 全局单例TTL缓存,缓存有效期60秒 (def my-cache (cw/ttl-cache-factory {} :ttl 60000)) (defn get-data [cid] (let [req-url (str "/api/get-data?id=" cid) response (retry-request (sign-credentials #(get! base-url req-url)) 3)] (println "接口响应内容:" response) ;; 函数最后返回响应本身,确保缓存能拿到有效值写入 response)) (defn get-data-caller [cid] (cw/lookup-or-miss my-cache cid get-data))
验证方式
连续两次调用(get-data-caller "test-cid"),如果控制台只打印一次接口响应日志,说明缓存已经正常生效,第二次请求直接读取缓存值,不会发起实际接口请求。
如果业务场景下接口本身可能返回空值(nil),可以对返回值做一层包装(比如统一返回
{:data 接口返回内容}格式),避免空值无法写入缓存导致的重复请求问题。
内容的提问来源于stack exchange,提问作者Ravi Bhanushali
相关产品推荐
相关产品推荐

