From 94fdab4e36db98df8ba872547809d5dc06931569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Wed, 7 May 2025 12:09:17 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BC=93=E5=AD=98=E9=A2=84=E7=83=AD=E5=8A=A0?= =?UTF-8?q?=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- httpclient/cache/ICache.go | 40 ++++---------------------------------- httpclient/client.go | 35 +++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 38 deletions(-) diff --git a/httpclient/cache/ICache.go b/httpclient/cache/ICache.go index d931357..3e60591 100644 --- a/httpclient/cache/ICache.go +++ b/httpclient/cache/ICache.go @@ -12,57 +12,25 @@ import ( ) // ICache 缓存定义 -// -// Author : go_developer@163.com<白茶清欢> -// -// Date : 15:49 2024/6/3 type ICache interface { // Enable 是否启用缓存(总开关) - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 15:50 2024/6/3 Enable() bool // CacheTime 缓存时长, 单位 : s , 默认 1800, 最小值 90, 设置失效时间, 会上下波动60s, 避免缓存集中失效 - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 15:50 2024/6/3 CacheTime() int64 // IsAllow 针对当前请求数据和状态, 是否允许缓存 - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 15:52 2024/6/3 IsAllow(reqCfg *define.Request, response *define.Response) bool // GetKey 获取缓存key - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 15:51 2024/6/3 GetKey(reqCfg *define.Request) string // GetValue 获取缓存值 - // - // Author : zhangdeman001@ke.com<张德满> - // - // Date : 16:01 2024/6/3 GetValue(cacheKey string) string // SetValue 设置缓存 - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 16:46 2024/6/3 SetValue(cacheKey string, cacheValue string) error // TTL 缓存剩余生命周期(单位: s) - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 18:39 2024/10/9 TTL(cacheKey string) int64 // PreHeatConfig 缓存预热配置 - // - // Author : go_developer@163.com<白茶清欢> - // - // Date : 18:42 2024/10/9 PreHeatConfig() *define.CachePreHeatConfig + // Lock 设置缓存时加锁 + Lock(lockKey string) error + // Unlock 完成缓存设置时, 释放锁 + Unlock(lockKey string) error } diff --git a/httpclient/client.go b/httpclient/client.go index 89005ea..656a5a7 100644 --- a/httpclient/client.go +++ b/httpclient/client.go @@ -220,10 +220,13 @@ func (hc *HttpClient) Request() *define.Response { return hc.requestBackendApi() } // 上面若命中缓存, 则后续缓存实例不可能为nil, 无需判断 - // TODO : 预热加锁, 并发请求触发预热, 仅触发一个即可 // 判断是否开启预热 cachePreHeatConfig := hc.reqConfig.CacheInstance.PreHeatConfig() - log.RecordDebug("接口请求命中缓存", map[string]any{ + if nil == cachePreHeatConfig { + log.RecordDebug("接口请求命中缓存, PreHeatConfig未返回预热配置, 不做预热处理", map[string]any{}, hc.reqConfig) + return nil + } + log.RecordDebug("接口请求命中缓存, 进行预热策略处理", map[string]any{ "cache_info": cacheResult.CacheInfo, }, hc.reqConfig) defer func() { @@ -285,7 +288,35 @@ func (hc *HttpClient) Request() *define.Response { "remaining_ttl": ttl, }, hc.reqConfig) // 配置了最小剩余时间,并且key剩余有效期小于最小剩余时间 + // 预热加锁, 并发请求触发预热, 仅触发一个即可, 使用接口做key + if err := hc.reqConfig.CacheInstance.Lock(hc.reqConfig.FullUrl); err != nil { + log.RecordWarn("接口请求命中缓存, 缓存结果有效期大于剩余时长小于配置阈值, 触发预热, 加锁失败, 未执行预热", map[string]any{ + "min_ttl": cachePreHeatConfig.MinTTL, + "remaining_ttl": ttl, + "err_msg": err.Error(), + }, hc.reqConfig) + return + } + log.RecordDebug("接口请求命中缓存, 缓存结果有效期大于剩余时长小于配置阈值, 触发预热, 加锁成功, 执行预热", map[string]any{ + "min_ttl": cachePreHeatConfig.MinTTL, + "remaining_ttl": ttl, + "lock_key": hc.reqConfig.FullUrl, + }, hc.reqConfig) _ = hc.requestBackendApi() + if err := hc.reqConfig.CacheInstance.Unlock(hc.reqConfig.FullUrl); nil != err { + log.RecordError("接口请求命中缓存, 缓存结果有效期大于剩余时长小于配置阈值, 触发预热, 执行预热后, 释放锁失败", map[string]any{ + "min_ttl": cachePreHeatConfig.MinTTL, + "remaining_ttl": ttl, + "lock_key": hc.reqConfig.FullUrl, + "err_msg": err.Error(), + }, hc.reqConfig) + return + } + log.RecordDebug("接口请求命中缓存, 缓存结果有效期大于剩余时长小于配置阈值, 触发预热, 执行预热后, 释放锁成功", map[string]any{ + "min_ttl": cachePreHeatConfig.MinTTL, + "remaining_ttl": ttl, + "lock_key": hc.reqConfig.FullUrl, + }, hc.reqConfig) }() }() // 命中缓存必然请求成功, 直接记录成功日志即可