加锁工具类
package cn.com.bilibili.alter.manager.tools;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RFuture;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class RedissonLockSupport {
private List<String> lockKeys = new ArrayList<>();
@Resource
RedisTemplate redisTemplate;
@Resource
RedissonClient redissonClient;
public Boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
RLock lock = redissonClient.getLock(lockKey);
try {
boolean locked = lock.tryLock(waitTime, leaseTime, unit);
if (locked) lockKeys.add(lockKey);
return locked;
} catch (InterruptedException | CancellationException e) {
log.error("尝试获取锁 {} 失败", lockKey);
}
return Boolean.FALSE;
}
public void removeAndSaveList(String key, List list, long expire, TimeUnit timeUnit) {
redisTemplate.delete(key);
redisTemplate.opsForList().leftPushAll(key,list);
redisTemplate.expire(key, expire, timeUnit);
}
public List getList(String key) {
return redisTemplate.opsForList().range(key, 0, -1);
}
public boolean unLock(String lockKey) {
try {
RLock lock = redissonClient.getLock(lockKey);
if (null != lock && lock.isHeldByCurrentThread()) {
lock.unlock();
return lockKeys.remove(lockKey);
}
} catch (Exception e) {
log.error("解锁 {} 失败", lockKey);
}
return false;
}
public Boolean tryLockAsync(String lockKey, long waitTime, long leaseTime, TimeUnit unit) {
RLock lock = redissonClient.getLock(lockKey);
try {
RFuture<Boolean> locked = lock.tryLockAsync(waitTime, leaseTime, unit);
if (locked.get()) lockKeys.add(lockKey);
return locked.get();
} catch (InterruptedException | ExecutionException e) {
log.error("尝试获取Async锁 {} 失败", lockKey);
}
return Boolean.FALSE;
}
public boolean unAsyncLock(String lockKey) {
try {
RLock lock = redissonClient.getLock(lockKey);
if (null != lock && lock.isHeldByCurrentThread()) {
RFuture<Void> future = lock.unlockAsync();
if (future.await(5 * 1000) && future.isSuccess()) {
return lockKeys.remove(lockKey);
}
}
} catch (Exception e) {
log.error("解Async锁 {} 失败", lockKey);
}
return false;
}
public boolean isHoldLock(String lockKey) {
try {
RLock lock = redissonClient.getLock(lockKey);
if (null != lock && lock.isHeldByCurrentThread()) {
return true;
}
} catch (Exception e) {
log.error("查询锁状态失败", lockKey);
}
return false;
}
}
缓存工具类
package cn.com.bilibili.alter.manager.tools;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class RedisUtil {
@Resource
RedisTemplate redisTemplate;
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
return false;
}
}
public void del(String key) {
if (key != null) {
redisTemplate.delete(key);
}
}
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
return false;
}
}
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
}
public boolean hmset(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean hmset(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean hset(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean hset(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
public Set<Object> sGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean sHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public long sSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public long sSetAndTime(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0)
expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public long sGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public List<Object> lGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public long lGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
public Object lGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean lUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public long lRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
配置文件
spring:
redis:
timeout: 6000ms
password:
cluster:
max-redirects: 5 # 获取失败 最大重定向次数
nodes: #放 redis 节点
- 172.23.47.1:7479
- 172.23.47.2:7481
- 172.23.47.3:7480
- 172.23.47.4:7480
- 172.23.47.5:7482
- 172.23.47.6:7481
lettuce:
pool:
max-active: 1000 #连接池最大连接数(使用负值表示没有限制)
max-idle: 10 # 连接池中的最大空闲连接
min-idle: 5 # 连接池中的最小空闲连接
max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制)
加锁工具类的使用
private Semaphore semaphore = new Semaphore(3);
boolean isHoldLock = false;
boolean hasPermit = false;
try{
isHoldLock = redissonLockSupport.tryLock(LockType.FLINK_VERSION_MANAGEMENT.name(), 1000, 20 * 60 * 1000, TimeUnit.MILLISECONDS);
if (isHoldLock) {
hasPermit = semaphore.tryAcquire();
if (hasPermit) {
addJobTags();
tagsJob();
calculateTagsProportion();
} else {
log.error("too many batch metric statistic task not finish, skip current task....");
}
}
}catch (Exception e ){
log.error("error to compute traffic result...");
}finally {
if (hasPermit) {
semaphore.release();
}
if (isHoldLock) {
redissonLockSupport.unLock(LockType.KAFKA_TRAFFIC_BATCH_STATISTIC_JOB.name());
}
}