From a571bf354692a4f28c678ccb59fcc6b27164bcee Mon Sep 17 00:00:00 2001 From: yangyl12345 Date: Tue, 26 Nov 2024 12:13:49 +0800 Subject: [PATCH] Update default_access_token.go (#805) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update default_access_token.go 微信获取稳定版token,只有不等于空字符串的情况下才会返回access_token信息,未空的情况,继续调去微信服务 * 微信稳定性获取 access_token 接口,添加防止并发性获取 access_token 和多次微信服务获取代码 --------- Co-authored-by: w_yangyili --- credential/default_access_token.go | 33 ++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/credential/default_access_token.go b/credential/default_access_token.go index 00ad481..ec88a89 100644 --- a/credential/default_access_token.go +++ b/credential/default_access_token.go @@ -101,10 +101,11 @@ func (ak *DefaultAccessToken) GetAccessTokenContext(ctx context.Context) (access // 不强制更新access_token,可用于不同环境不同服务而不需要分布式锁以及公用缓存,避免access_token争抢 // https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/mp-access-token/getStableAccessToken.html type StableAccessToken struct { - appID string - appSecret string - cacheKeyPrefix string - cache cache.Cache + appID string + appSecret string + cacheKeyPrefix string + cache cache.Cache + accessTokenLock *sync.Mutex } // NewStableAccessToken new StableAccessToken @@ -113,10 +114,11 @@ func NewStableAccessToken(appID, appSecret, cacheKeyPrefix string, cache cache.C panic("cache is need") } return &StableAccessToken{ - appID: appID, - appSecret: appSecret, - cache: cache, - cacheKeyPrefix: cacheKeyPrefix, + appID: appID, + appSecret: appSecret, + cache: cache, + cacheKeyPrefix: cacheKeyPrefix, + accessTokenLock: new(sync.Mutex), } } @@ -130,7 +132,20 @@ func (ak *StableAccessToken) GetAccessTokenContext(ctx context.Context) (accessT // 先从cache中取 accessTokenCacheKey := fmt.Sprintf("%s_stable_access_token_%s", ak.cacheKeyPrefix, ak.appID) if val := ak.cache.Get(accessTokenCacheKey); val != nil { - return val.(string), nil + if accessToken = val.(string); accessToken != "" { + return + } + } + + // 加上lock,是为了防止在并发获取token时,cache刚好失效,导致从微信服务器上获取到不同token + ak.accessTokenLock.Lock() + defer ak.accessTokenLock.Unlock() + + // 双检,防止重复从微信服务器获取 + if val := ak.cache.Get(accessTokenCacheKey); val != nil { + if accessToken = val.(string); accessToken != "" { + return + } } // cache失效,从微信服务器获取