Browse Source

🎨 #1542 小程序模块配置类增加Redisson的实现,解决分布式锁问题

* 增加Redisson的实现,解决分布式锁问题

* key值重复添加了appid。

Co-authored-by: 袁启勋 <xun.yuan@infoship.cn>
dev1
yuanqixun 4 years ago
committed by GitHub
parent
commit
98aef34fdb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 229 additions and 0 deletions
  1. +4
    -0
      weixin-java-miniapp/pom.xml
  2. +153
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedissonConfigImpl.java
  3. +72
    -0
      weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedissonConfigImplTest.java

+ 4
- 0
weixin-java-miniapp/pom.xml View File

@@ -80,6 +80,10 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>com.github.jedis-lock</groupId>
<artifactId>jedis-lock</artifactId>


+ 153
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedissonConfigImpl.java View File

@@ -0,0 +1,153 @@
package cn.binarywang.wx.miniapp.config.impl;

import lombok.NonNull;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.redis.RedissonWxRedisOps;
import me.chanjar.weixin.common.redis.WxRedisOps;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RedissonClient;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
* 基于Redisson的实现
*
* @author yuanqixun
* @date 2020/5/3
*/
public class WxMaRedissonConfigImpl extends WxMaDefaultConfigImpl {

protected final static String LOCK_KEY = "wechat_ma_lock:";
protected final static String MA_ACCESS_TOKEN_KEY = "wechat_ma_access_token_key:";
protected final static String MA_JSAPI_TICKET_KEY = "wechat_ma_jsapi_ticket_key:";
protected final static String MA_CARD_API_TICKET_KEY = "wechat_ma_card_api_ticket_key:";

/**
* redis 存储的 key 的前缀,可为空
*/
/**
* redis 存储的 key 的前缀,可为空
*/
protected String keyPrefix;
protected String accessTokenKey;
protected String jsapiTicketKey;
protected String cardApiTicketKey;
protected String lockKey;

private final WxRedisOps redisOps;

public WxMaRedissonConfigImpl(@NonNull RedissonClient redissonClient, String keyPrefix) {
this(new RedissonWxRedisOps(redissonClient), keyPrefix);
}

public WxMaRedissonConfigImpl(@NonNull RedissonClient redissonClient) {
this(redissonClient, null);
}

private WxMaRedissonConfigImpl(@NonNull WxRedisOps redisOps, String keyPrefix) {
this.redisOps = redisOps;
this.keyPrefix = keyPrefix;
}

@Override
public void setAppid(String appid) {
super.setAppid(appid);
String prefix = StringUtils.isBlank(keyPrefix) ? "" :
(StringUtils.endsWith(keyPrefix, ":") ? keyPrefix : (keyPrefix + ":"));
lockKey = prefix + LOCK_KEY.concat(appid);
accessTokenKey = prefix + MA_ACCESS_TOKEN_KEY.concat(appid);
jsapiTicketKey = prefix + MA_JSAPI_TICKET_KEY.concat(appid);
cardApiTicketKey = prefix + MA_CARD_API_TICKET_KEY.concat(appid);
}

protected Lock getLockByKey(String key) {
return redisOps.getLock(key);
}

@Override
public Lock getAccessTokenLock() {
return getLockByKey(this.lockKey.concat(":").concat("accessToken"));
}

@Override
public Lock getCardApiTicketLock() {
return getLockByKey(this.lockKey.concat(":").concat("cardApiTicket"));

}

@Override
public Lock getJsapiTicketLock() {
return getLockByKey(this.lockKey.concat(":").concat("jsapiTicket"));
}

@Override
public String getAccessToken() {
return redisOps.getValue(this.accessTokenKey);
}

@Override
public boolean isAccessTokenExpired() {
Long expire = redisOps.getExpire(this.accessTokenKey);
return expire == null || expire < 2;
}

@Override
public void updateAccessToken(WxAccessToken accessToken) {
redisOps.setValue(this.accessTokenKey, accessToken.getAccessToken(), accessToken.getExpiresIn(), TimeUnit.SECONDS);
}

@Override
public void updateAccessToken(String accessToken, int expiresInSeconds) {
redisOps.setValue(this.accessTokenKey, accessToken, expiresInSeconds, TimeUnit.SECONDS);
}

@Override
public String getJsapiTicket() {
return redisOps.getValue(this.jsapiTicketKey);
}

@Override
public boolean isJsapiTicketExpired() {
Long expire = redisOps.getExpire(this.jsapiTicketKey);
return expire == null || expire < 2;
}

@Override
public void expireJsapiTicket() {
redisOps.expire(this.jsapiTicketKey, 0, TimeUnit.SECONDS);
}

@Override
public void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
redisOps.setValue(this.jsapiTicketKey, jsapiTicket, expiresInSeconds, TimeUnit.SECONDS);

}

@Override
public String getCardApiTicket() {
return redisOps.getValue(cardApiTicketKey);
}

@Override
public boolean isCardApiTicketExpired() {
Long expire = redisOps.getExpire(this.cardApiTicketKey);
return expire == null || expire < 2;
}

@Override
public void expireCardApiTicket() {
redisOps.expire(this.cardApiTicketKey, 0, TimeUnit.SECONDS);
}

@Override
public void updateCardApiTicket(String cardApiTicket, int expiresInSeconds) {
redisOps.setValue(this.cardApiTicketKey, cardApiTicket, expiresInSeconds, TimeUnit.SECONDS);
}

@Override
public void expireAccessToken() {
redisOps.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
}

}

+ 72
- 0
weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/config/impl/WxMaRedissonConfigImplTest.java View File

@@ -0,0 +1,72 @@
package cn.binarywang.wx.miniapp.config.impl;

import cn.binarywang.wx.miniapp.config.WxMaConfig;
import lombok.SneakyThrows;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.TransportMode;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

/**
* @author yqx
* @date 2020/5/3
*/
public class WxMaRedissonConfigImplTest {

WxMaDefaultConfigImpl wxMaConfig;

@BeforeMethod
public void setUp() {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379")
.setDatabase(0);
config.setTransportMode(TransportMode.NIO);
RedissonClient redisson = Redisson.create(config);
wxMaConfig = new WxMaRedissonConfigImpl(redisson);
wxMaConfig.setAppid("appid12345678");
wxMaConfig.updateAccessToken("accessToken", 5); //有效期5秒
wxMaConfig.updateJsapiTicket("jsapiTicket", 5);
wxMaConfig.updateCardApiTicket("cardApiTicket", 5);
}

@SneakyThrows
@Test
public void testGetAccessToken() {
String accessToken = wxMaConfig.getAccessToken();
Assert.assertEquals(accessToken, "accessToken");
Assert.assertFalse(wxMaConfig.isAccessTokenExpired());
Thread.sleep(6000);//休眠6s
Assert.assertTrue(wxMaConfig.isAccessTokenExpired());
}

@SneakyThrows
@Test
public void testGetJsapiTicket() {
String jsapiTicket = wxMaConfig.getJsapiTicket();
Assert.assertEquals(jsapiTicket, "jsapiTicket");
Assert.assertFalse(wxMaConfig.isJsapiTicketExpired());
Thread.sleep(6000);//休眠6s
Assert.assertTrue(wxMaConfig.isJsapiTicketExpired());
}

@SneakyThrows
@Test
public void testGetCardApiTicket() {
String cardApiTicket = wxMaConfig.getCardApiTicket();
Assert.assertEquals(cardApiTicket, "cardApiTicket");
Assert.assertFalse(wxMaConfig.isCardApiTicketExpired());
Thread.sleep(6000);//休眠6s
Assert.assertTrue(wxMaConfig.isCardApiTicketExpired());
}

@Test
public void testIsAccessTokenExpired() {
Assert.assertFalse(wxMaConfig.isAccessTokenExpired());
wxMaConfig.expireAccessToken();
Assert.assertTrue(wxMaConfig.isAccessTokenExpired());
}
}

Loading…
Cancel
Save