我们的活动遇到了性能问题,原先的单机锁性能太差,以下单购买商品为例,我们考虑使用分布式锁,但传统的方式为了使用Redis锁,我们需要设置一个定长的key,然后当购买完成后,将key删除。但为了防止key提前过期,我们不得不新增一个线程执行定时任务。现在我们可以使用Redissson框架简化代码。getLock()方法代替了Redis的setIfAbsent(),lock()设置过期时间。最终我们在交易结束后释放锁。延长锁的操作则有Redisson框架替我们完成,它会使用轮询去查看key是否过期,在交易没有完成时,自动重设Redis的key过期时间。
1.引入依赖:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.5</version>
</dependency>
2.配置redisson
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* redisson配置
* 目前使用的是腾讯云的单节点redis,因此暂时配置单服务
*
*
*/
@Configuration
public class RedissonConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private String port;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedissonClient getRedisson(){
Config config = new Config();
config.useSingleServer().setAddress("redis://" + host + ":" + port).setPassword(password);
//添加主从配置
//config.useMasterSlaveServers().setMasterAddress("").setPassword("").addSlaveAddress(new String[]{"",""});
return Redisson.create(config);
}
}
3.示例代码
import org.redisson.api.RedissonClient;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class BuyRedissonLock {
@Autowired
private RedissonClient redissonClient;
@GetMapping(value = "buy")
public String get() {
RLock ztLock = redissonClient.getLock("ztLock");
// ztLock.lock(3, TimeUnit.SECONDS); 指定了超时时间的话,使用指定的,
ztLock.lock(); //没指定的话使用30s,有看门狗,延迟10秒执行,循环延期
// 尝试加锁,最多等待100秒,上锁以后10秒自动解锁
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
if (res) {
try {
//TODO... 业务逻辑代码
} finally {
ztLock.unlock();
}
return "";
}
}
}
4、几点说明
- 加锁的时候注意一下锁的粒度,粒度越小性能越好,比如商品的话,可以按照商品id进行锁。
- 为了保证缓存一致性,可以使用读写锁。
评论 (0)