一.使用redis锁
/**
* 智慧云-工单系统-抢单-工单ID锁key
*/
public static final String CLOUD_LIVE_GAIN_ORDER_LOCK_ORDERID = "cloud_live_gain_order_lock_orderid_";
// 工单ID加锁
boolean redisLockFlag = redisKeyLockUtil.tryLock(RedisKeyConstant.CLOUD_LIVE_GAIN_ORDER_LOCK_ORDERID + orderEo.getOrderId(), 2, 3 * 1000);
if (!redisLockFlag) {
logger.info("=============>企业app抢单接口 nurseId={},userId={} lock failed", requestDto.getEmployeeId(), orderEo.getOrderId());
context.setResult(Result.getFailureResult(FailureCodeEnum.E_APP_BIZ_005.getCode(), FailureCodeEnum.E_APP_BIZ_005.getMsg()));
return false;
}
@Component
public class RedisKeyLockUtil {
private static final Logger log = LoggerFactory.getLogger(RedisKeyLockUtil.class);
@Autowired
@Qualifier(value = "redisClientTemplate")
private RedisClientTemplate redis;
/**
* 是否有锁权限
*
* @param key
* @param expireSeconds key的过期时间
* @param timeoutMsecs 获取锁的超时时间
* @return
*/
public boolean tryLock(String key, Integer expireSeconds, long timeoutMsecs) {
try {
while (timeoutMsecs >= 0) {
log.info("====================>try lock key: " + key);
Long i = redis.setnx(key, "locked", expireSeconds); //SET if key Not eXists
if (i == 1) {
log.info("====================>get lock, key: " + key + " , expire in " + expireSeconds + " seconds.");
return true;
}
timeoutMsecs -= 1000;
Thread.sleep(1000);
}
return false;
} catch (Exception e) {
log.error("key={}; expireSeconds={}, timeoutMsecs={}", key, expireSeconds, timeoutMsecs, e);
}
return false;
}
}
二:使用google RateLimiter 限流工具类
public class AddDefaultCostConfigBizImpl
{
private static final Logger log = LoggerFactory.getLogger(QueryCostItemRuleBizImpl.class);
private final RateLimiter limiter = RateLimiter.create(0.5);//创建一个具有稳定吞吐量的速率限制器。设置每秒请求数(permits)为1个
在需要阻塞的地方加上就可以了
//阻塞方式
limiter.acquire();//从速率限制器中获取一个许可(permits),超过(permits)会被阻塞,直到请求被授予。
参考网站
http://www.mincoder.com/article/2943.shtml