🎨 #1488 公众号模块支持分布式锁,设置token过期时加锁

This commit is contained in:
007gzs 2020-04-04 21:38:59 +08:00 committed by GitHub
parent 04f7d76057
commit d752c48dc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 4 deletions

View File

@ -288,7 +288,17 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
|| error.getErrorCode() == ERR_42001 || error.getErrorCode() == ERR_42001
|| error.getErrorCode() == ERR_40014) { || error.getErrorCode() == ERR_40014) {
// 强制设置WxMaConfig的access token过期了这样在下一次请求里就会刷新access token // 强制设置WxMaConfig的access token过期了这样在下一次请求里就会刷新access token
this.getWxMaConfig().expireAccessToken(); Lock lock = this.getWxMaConfig().getAccessTokenLock();
lock.lock();
try {
if(StringUtils.equals(this.getWxMaConfig().getAccessToken(), accessToken)){
this.getWxMaConfig().expireAccessToken();
}
} catch (Exception ex){
this.getWxMaConfig().expireAccessToken();
}finally {
lock.unlock();
}
if (this.getWxMaConfig().autoRefreshToken()) { if (this.getWxMaConfig().autoRefreshToken()) {
return this.execute(executor, uri, data); return this.execute(executor, uri, data);
} }

View File

@ -351,7 +351,17 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH
*/ */
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
// 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token // 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token
this.getWxMpConfigStorage().expireAccessToken(); Lock lock = this.getWxMpConfigStorage().getAccessTokenLock();
lock.lock();
try{
if(StringUtils.equals(this.getWxMpConfigStorage().getAccessToken(), accessToken)){
this.getWxMpConfigStorage().expireAccessToken();
}
} catch (Exception ex){
this.getWxMpConfigStorage().expireAccessToken();
} finally {
lock.unlock();
}
if (this.getWxMpConfigStorage().autoRefreshToken()) { if (this.getWxMpConfigStorage().autoRefreshToken()) {
return this.execute(executor, uri, data); return this.execute(executor, uri, data);
} }

View File

@ -1,9 +1,13 @@
package me.chanjar.weixin.mp.config.impl; package me.chanjar.weixin.mp.config.impl;
import me.chanjar.weixin.common.util.locks.JedisDistributedLock;
import me.chanjar.weixin.mp.enums.TicketType; import me.chanjar.weixin.mp.enums.TicketType;
import redis.clients.jedis.Jedis; import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPool;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/** /**
* 基于Redis的微信配置provider. * 基于Redis的微信配置provider.
* *
@ -17,6 +21,7 @@ import redis.clients.jedis.JedisPool;
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl { public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl {
private static final String ACCESS_TOKEN_KEY = "wx:access_token:"; private static final String ACCESS_TOKEN_KEY = "wx:access_token:";
private static final String LOCK_KEY = "wx:lock:";
/** /**
* 使用连接池保证线程安全. * 使用连接池保证线程安全.
@ -24,6 +29,7 @@ public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl {
private final JedisPool jedisPool; private final JedisPool jedisPool;
private String accessTokenKey; private String accessTokenKey;
private String lockKey;
public WxMpRedisConfigImpl(JedisPool jedisPool) { public WxMpRedisConfigImpl(JedisPool jedisPool) {
this.jedisPool = jedisPool; this.jedisPool = jedisPool;
@ -36,6 +42,11 @@ public class WxMpRedisConfigImpl extends WxMpDefaultConfigImpl {
public void setAppId(String appId) { public void setAppId(String appId) {
super.setAppId(appId); super.setAppId(appId);
this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId); this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId);
this.lockKey = ACCESS_TOKEN_KEY.concat(appId).concat(":");
accessTokenLock = new JedisDistributedLock(jedisPool, lockKey.concat("accessTokenLock"));
jsapiTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("jsapiTicketLock"));
sdkTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("sdkTicketLock"));
cardApiTicketLock = new JedisDistributedLock(jedisPool, lockKey.concat("cardApiTicketLock"));
} }
private String getTicketRedisKey(TicketType type) { private String getTicketRedisKey(TicketType type) {

View File

@ -155,7 +155,18 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
*/ */
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
// 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token // 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token
this.getWxOpenConfigStorage().expireComponentAccessToken(); Lock lock = this.getWxOpenConfigStorage().getComponentAccessTokenLock();
lock.lock();
try {
if (StringUtils.equals(componentAccessToken, this.getWxOpenConfigStorage().getComponentAccessToken()){
this.getWxOpenConfigStorage().expireComponentAccessToken();
}
} catch (Exception ex) {
this.getWxOpenConfigStorage().expireComponentAccessToken();
}finally {
lock.unlock();
}
if (this.getWxOpenConfigStorage().autoRefreshToken()) { if (this.getWxOpenConfigStorage().autoRefreshToken()) {
return this.post(uri, postData, accessTokenKey); return this.post(uri, postData, accessTokenKey);
} }
@ -188,7 +199,17 @@ public class WxOpenComponentServiceImpl implements WxOpenComponentService {
*/ */
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) { if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
// 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token // 强制设置wxMpConfigStorage它的access token过期了这样在下一次请求里就会刷新access token
this.getWxOpenConfigStorage().expireComponentAccessToken(); Lock lock = this.getWxOpenConfigStorage().getComponentAccessTokenLock();
lock.lock();
try {
if (StringUtils.equals(componentAccessToken, this.getWxOpenConfigStorage().getComponentAccessToken()){
this.getWxOpenConfigStorage().expireComponentAccessToken();
}
} catch (Exception ex) {
this.getWxOpenConfigStorage().expireComponentAccessToken();
}finally {
lock.unlock();
}
if (this.getWxOpenConfigStorage().autoRefreshToken()) { if (this.getWxOpenConfigStorage().autoRefreshToken()) {
return this.get(uri, accessTokenKey); return this.get(uri, accessTokenKey);
} }