1. 引言
在本快速教程中,我們將探討如何配置關鍵過期時間(expiration time)在 Spring Data Redis 中。
2. 設置
讓我們創建一個基於 Spring Boot 的 API,用於管理一個使用 Redis 進行持久化的 Session 資源。我們需要完成四個主要步驟來實現。要了解更詳細的設置,請查看我們的 Spring Data Redis 指南。
2.1. 依賴項
首先,我們將以下依賴項添加到我們的 pom.xml 中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>3.1.5</version>
</dependency><a href="https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis">spring-boot-starter-data-redis</a> 將會遞歸地添加 <em >spring-data-redis</em> 和 <em >lettuce-core</em>。
2.2. Redis 配置
接下來,讓我們添加 RedisTemplate 配置:
@Configuration
public class RedisConfiguration {
@Bean
public RedisTemplate<String, Session> getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Session> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}2.3. 模型
第三,讓我們創建我們的 會話 模型:
@RedisHash
public class Session {
@Id
private String id;
private Long expirationInSeconds;
}2.4. Redis 倉庫
現在,終於,我們來創建 SessionRepository,它提供與 Redis 的交互,用於管理我們的 Session 實體:
public interface SessionRepository extends CrudRepository<Session, String> {}
3. 方法
我們將探討三種設置 TTL 的方法。
3.1. 使用 @RedisHash
首先來看最簡單的之一。 @RedisHash 允許我們為它的 timeToLive 屬性提供值:
@RedisHash(timeToLive = 60L)
public class Session {
@Id
private String id;
private Long expirationInSeconds;
}它會採用秒為單位的值。 在上面的示例中,我們設置了過期時間為 60 秒。這種方法在我們需要為所有 會話 對象提供一個恆定的 TTL 值時非常有用。 還可以用來指定默認 TTL。
3.2. 使用 @TimeToLive
在之前的方案中,我們可以為所有 Session 對象設置相同的常量 TTL。 我們的下一項方案允許更大的靈活性。 通過使用 @TimeToLive,我們可以為任何數值屬性或返回數值值的任何方法設置 TTL:
@RedisHash(timeToLive = 60L)
public class Session {
@Id
private String id;
@TimeToLive
private Long expirationInSeconds;
}這使得我們能夠動態地為每個 Session 對象設置 TTL。 與之前的做法類似,TTL 以秒為單位。 @TimeToLive 的值會覆蓋 @RedisHash(timeToLive) 的值。
3.3. 使用 KeyspaceSettings
接下來,我們採用另一種方法,KeyspaceSettings 用於設置 TTL。Keyspace 定義了用於創建 Redis Hash 實際鍵的前綴。 讓我們現在為 Session 類定義 KeyspaceSettings:
@Configuration
@EnableRedisRepositories(keyspaceConfiguration = RedisConfiguration.MyKeyspaceConfiguration.class)
public class RedisConfiguration {
// Other configurations omitted
public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {
@Override
protected Iterable<KeyspaceSettings> initialConfiguration() {
KeyspaceSettings keyspaceSettings = new KeyspaceSettings(Session.class, "session");
keyspaceSettings.setTimeToLive(60L);
return Collections.singleton(keyspaceSettings);
}
}
}與之前的方案類似,我們指定了 TTL 的單位為秒。這種方法與 @RedisHash 非常相似。 此外,如果我們不希望使用 @EnableRepositories,則可以更程序化地設置它:
@Configuration
public class RedisConfiguration {
// Other configurations omitted
@Bean
public RedisMappingContext keyValueMappingContext() {
return new RedisMappingContext(new MappingConfiguration(new IndexConfiguration(), new MyKeyspaceConfiguration()));
}
public static class MyKeyspaceConfiguration extends KeyspaceConfiguration {
@Override
protected Iterable<KeyspaceSettings> initialConfiguration() {
KeyspaceSettings keyspaceSettings = new KeyspaceSettings(Session.class, "session");
keyspaceSettings.setTimeToLive(60L);
return Collections.singleton(keyspaceSettings);
}
}
}
4. 比較
最後,讓我們比較一下我們探討的三種方法,並確定何時使用哪種方法。
@RedisHash 和 KeyspaceSettings 都允許我們一次性設置實體實例 (Session) 的 TTL。另一方面,@TimeToLive 允許我們為每個實體實例動態設置 TTL。
KeyspaceSettings 提供了一種在配置中一次性設置默認 TTL 的方式,適用於多個實體。而@TimeToLive 和 @RedisHash 則需要在每個實體類文件中進行此操作。
@TimeToLive 的優先級最高,其次是 @RedisHash,KeyspaceSettings 則優先級最低。
5. Redis 鍵過期事件
鑑於以上所有設置 Redis 鍵過期的方法,您可能也對何時發生這些事件感興趣。為此,我們提供了 RedisKeyExpiredEvent。讓我們設置一個 EventListener 以捕獲 RedisKeyExpiredEvent:
@Configuration
@EnableRedisRepositories(enableKeyspaceEvents = RedisKeyValueAdapter.EnableKeyspaceEvents.ON_STARTUP)
@Slf4j
public class RedisConfiguration {
// Other configurations omitted
@Component
public static class SessionExpiredEventListener {
@EventListener
public void handleRedisKeyExpiredEvent(RedisKeyExpiredEvent<Session> event) {
Session expiredSession = (Session) event.getValue();
assert expiredSession != null;
log.info("Session with key={} has expired", expiredSession.getId());
}
}
}
我們現在將能夠知道會話 何時過期,並在需要時採取相應措施:
2023-02-10T15:13:38.626+05:30 INFO 16874 --- [enerContainer-1] c.b.s.config.RedisConfiguration:
Session with key=edbd98e9-7b50-45d8-9cf4-9c621899e213 has expired
6. 結論
在本文中,我們探討了通過 Spring Data Redis 設置 Redis TTL 的各種方法。最後,我們研究了 RedisKeyExpiredEvent 以及如何處理過期事件。