一、基于redis实现的分布式锁
1.引入依赖:在pom.xml文件中添加Spring Cloud的依赖和缓存组件的依赖。例如,可以选择使用Redis作为缓存组件,需要添加spring-boot-starter-data-redis和jedis的依赖。
2.配置缓存:在application.yml文件中配置缓存,指定缓存的地址、端口和密码等信息。
3.定义分布式锁接口:定义一个接口,并在接口上使用@FeignClient注解,指定调用的服务名和上下文路径,该接口的方法用于获取和释放分布式锁。
@FeignClient(value = "distributed-lock-service",contextId = "distributedLockService")
public interface DistributedLockService {@GetMapping("/lock/get")boolean getLock(@RequestParam("key") String key, @RequestParam("value") String value, @RequestParam("expireTime") int expireTime);@GetMapping("/lock/release")boolean releaseLock(@RequestParam("key") String key, @RequestParam("value") String value);
}
4.创建分布式锁实现类:使用RedisTemplate和ValueOperations来实现分布式锁的获取和释放。
@Service
public class DistributedLockServiceImpl implements DistributedLockService{@Autowiredprivate RedisTemplate<String,Object> redisTemplate;@Autowiredprivate ValueOperations<String,Object> valueOperations;@Overridepublic boolean getLock(String key, String value, int expireTime) {Boolean result = valueOperations.setIfAbsent(key, value);if(result != null && result){//设置锁的过期时间redisTemplate.expire(key,expireTime, TimeUnit.SECONDS);return true;}return false;}@Overridepublic boolean releaseLock(String key, String value) {if(redisTemplate.hasKey(key)){Object v = valueOperations.get(key);if(v != null && v.equals(value)){redisTemplate.delete(key);return true;}}return false;}
}
5.使用分布式锁:在需要加锁的方法上加上@DistributedLock注解,并指定锁的key和过期时间。
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate DistributedLockService distributedLockService;@Autowiredprivate UserRepository userRepository;@Override@DistributedLock(lockKey = "#userId",expireTime = 10)public User getUserById(Long userId) {Optional<User> optionalUser = userRepository.findById(userId);if(optionalUser.isPresent()){return optionalUser.get();}return null;}
}
以上步骤可以用于在Spring Cloud中使用分布式锁。其中,关键的是通过缓存组件来实现锁的获取和释放,然后使用注解来简化业务代码的编写。
二、基于Redisson实现的分布式锁
1.引入依赖:在pom.xml文件中添加Redisson的依赖,并排除掉默认使用的Jedis和Lettuce的依赖。例如,可以添加以下依赖:
<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.16.0</version><exclusions><exclusion><groupId>io.lettuce</groupId><artifactId>lettuce-core</artifactId></exclusion><exclusion><groupId>redis.clients</groupId><artifactId>jedis</artifactId></exclusion></exclusions>
</dependency>
2.配置Redisson:在application.yml文件中配置Redisson连接信息,例如Redisson的地址和密码等信息。
spring:redis:host: 127.0.0.1port: 6379password:database: 0redisson:address: redis://${spring.redis.host}:${spring.redis.port}password: "${spring.redis.password}"
3.创建分布式锁实例:使用RedissonClient创建Redisson分布式锁实例。在Spring Boot中,可以直接使用RedissonAutoConfiguration自动配置类,或者使用自定义@Configuration注解来创建RedissonClient实例。例如:
@Configuration
public class RedissonConfig {@Autowiredprivate RedisProperties redisProperties;@Bean(destroyMethod = "shutdown")public RedissonClient redisson() {Config config = new Config();config.useSingleServer().setAddress(String.format("redis://%s:%d", redisProperties.getHost(), redisProperties.getPort()));return Redisson.create(config);}}
4.使用分布式锁:使用Redisson的RLock对象来实现分布式锁的获取和释放。例如在需要加锁的方法中,可以使用RLock.tryLock()方法来获取锁,并使用RLock.unlock()方法来释放锁。
@Service
public class UserServiceImpl implements UserService {@Autowiredprivate RedissonClient redissonClient;@Autowiredprivate UserRepository userRepository;@Overridepublic User getUserById(Long userId) {RLock lock = redissonClient.getLock("user_" + userId);try{//尝试获取锁,如果获取锁失败则等待boolean locked = lock.tryLock(10, TimeUnit.SECONDS);if(locked){Optional<User> optionalUser = userRepository.findById(userId);if(optionalUser.isPresent()){return optionalUser.get();}}}catch(InterruptedException e){e.printStackTrace();}finally{//释放锁lock.unlock();}return null;}
}
以上步骤可以用于在Spring Cloud中使用Redisson分布式锁。其中,关键的是使用Redisson的RLock对象来实现锁的获取和释放,而RLock对象可以通过RedissonClient创建。