- 源码来自infinispan: git@github.com:infinispan/infinispan.git
基于Infinispan 内部架构的了解,让我为你详细解释 DefaultSegmentedDataContainer 中 TTL 的存储位置:
DefaultSegmentedDataContainer 中 TTL 的存储结构
核心结构层次
- DefaultSegmentedDataContainer
- │
- ├── DataSegment[] segments ← 分段数组(根据 key 的 hash 分配)
- │ │
- │ └── ConcurrentHashMap<Object, InternalCacheEntry>
- │ │
- │ └── InternalCacheEntry<K, V> ← 每个缓存条目对象
- │ │
- │ ├── key : K ← 缓存键
- │ ├── value : V ← 缓存值
- │ ├── metadata : Metadata ← 元数据(包含TTL信息)★
- │ ├── created : long ← 创建时间戳
- │ └── lastUsed : long ← 最后访问时间戳
复制代码 TTL 信息的具体位置
TTL 不是存储在 DefaultSegmentedDataContainer 的直接属性中,而是在每个 InternalCacheEntry 对象的 Metadata 属性里。
Infinispan 中有多种 InternalCacheEntry 实现类,根据是否有过期时间分类:
实现类特点TTL 相关属性ImmortalCacheEntry永不过期无 TTL 属性MortalCacheEntry有 lifespanlifespan, createdTransientCacheEntry有 maxIdlemaxIdle, lastUsedTransientMortalCacheEntry同时有两者lifespan, maxIdle, created, lastUsedMetadataImmortalCacheEntry使用 Metadata 对象metadata.lifespan(), metadata.maxIdle()MetadataMortalCacheEntry使用 Metadata 对象metadata.lifespan(), metadata.maxIdle()下面的缓存sessions表示永不过期,因为它的类型是ImmortalCacheEntry
下面的缓存sessions是有过期时间的,它的类型是TransientMortalCacheEntry
实际的 TTL 属性
- 对于 Keycloak 的会话缓存,通常使用 **带 Metadata 的条目**,TTL 信息在:
复制代码- InternalCacheEntry entry = ...;
- // 获取 lifespan (生命周期 TTL)
- long lifespan = entry.getLifespan(); // 返回毫秒值,-1 表示永不过期
- // 获取 maxIdle (空闲 TTL)
- long maxIdle = entry.getMaxIdle(); // 返回毫秒值,-1 表示永不过期
- // 获取创建时间
- long created = entry.getCreated(); // 创建时的时间戳
- // 获取最后访问时间
- long lastUsed = entry.getLastUsed(); // 最后访问的时间戳
- // 检查是否过期
- boolean expired = entry.isExpired(System.currentTimeMillis());
- // 计算过期时间点
- long expiryTime = entry.expiryTime(); // 返回具体的过期时间戳
复制代码 在 JVM 调试时查看 TTL
如果你想在调试器中查看某个缓存项的 TTL,路径是:- DefaultSegmentedDataContainer
- └── segments (DataSegment[])
- └── [segment index]
- └── entries (ConcurrentHashMap)
- └── [key]
- └── InternalCacheEntry 对象
- ├── metadata
- │ ├── lifespan ← 这里是 TTL(毫秒)
- │ └── maxIdle ← 这里是空闲超时(毫秒)
- ├── created ← 创建时间戳
- └── lastUsed ← 最后访问时间戳
复制代码 过期判断逻辑
[code]// 在 InternalCacheEntry 中的过期检查逻辑(简化版):public boolean isExpired(long now) { // lifespan 检查 if (lifespan > 0 && (created + lifespan) 0 && (lastUsed + maxIdle) 0 && (created + lifespan) 0 && (lastUsed + maxIdle) |