分布式锁
分布式锁可以使用Redisson
库来实现,它提供了一个更加完善的分布式锁实现。
- 添加Redisson依赖到
pom.xml
:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
- 配置Redisson客户端:
@Configuration
public class RedissonConfig {
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379");
return Redisson.create(config);
}
}
- 使用Redisson的锁:
@Service
public class DistributedService {
@Autowired
private RedissonClient redissonClient;
public void doWork() {
RLock lock = redissonClient.getLock("myLock");
try {
if (lock.tryLock(5, 10, TimeUnit.SECONDS)) {
// 执行业务逻辑
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
lock.unlock();
}
}
}
接口限流
接口限流可以使用Redis的INCR
命令和EXPIRE
命令来实现令牌桶或漏桶算法。
@Service
public class RateLimiterService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public boolean isRateLimited(String key, int limit, int timeout, TimeUnit unit) {
long currentTime = System.currentTimeMillis();
long expireTime = currentTime + unit.toMillis(timeout);
// 尝试获取锁
Boolean success = redisTemplate.opsForValue().setIfAbsent(key, currentTime, timeout, unit);
if (success != null && success) {
// 获取锁成功,初始化令牌桶
redisTemplate.opsForValue().set(key, limit, timeout, unit);
return false;
}
// 检查令牌桶
long tokens = (long) redisTemplate.opsForValue().get(key);
if (tokens > 0) {
// 减少令牌
redisTemplate.opsForValue().decrement(key);
return false;
}
// 令牌桶为空,拒绝服务
return true;
}
}
接口缓存
接口缓存可以使用Spring Cache Abstraction与Redis结合使用。
- 在
pom.xml
中添加Spring Boot Cache依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
- 在配置类上添加
@EnableCaching
注解:
@Configuration
@EnableCaching
public class CacheConfig {
// ...
}
- 在需要缓存的方法上使用
@Cacheable
注解:
@Service
public class CacheService {
@Cacheable(value = "items", key = "#id")
public Item findById(String id) {
// 查询数据库
}
}
双写一致性
双写一致性通常是指在缓存和数据库之间更新数据时保持数据一致性的问题。这通常需要使用分布式锁和事务控制来实现。
@Service
public class ConsistencyService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void updateData(String key, Object data) {
// 获取分布式锁
RLock lock = redissonClient.getLock(key);
lock.lock();
try {
// 更新数据库
databaseService.updateData(key, data);
// 更新缓存
redisTemplate.opsForValue().set(key, data);
} finally {
lock.unlock();
}
}
}
Lua脚本事务控制
Lua脚本可以在Redis中原子性地执行一系列命令,用于实现事务控制。
@Service
public class LuaService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
public void executeLuaScript() {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) else return 0 end";
Boolean result = redisTemplate.execute(new DefaultRedisScript<Boolean>(script, Boolean.class),
Arrays.asList("myKey"), "myValue");
}
}