Java Caffeine高性能内存

Caffeine是使用Java8对Guava缓存的重写版本,在Spring Boot 2.0中将取代,基于LRU算法实现,支持多种缓存过期策略。

1、pom.xml

1
2
3
4
5
<!--缓存-->
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>

2、配置 CacheConfig.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
@Configuration
@EnableCaching
public class CacheConfig {

public static final int DEFAULT_MAXSIZE = 50000;
public static final int DEFAULT_TTL = 10;

/**
* 定義cache名稱、超時時長(秒)、最大容量
* 每个cache缺省:10秒超时、最多缓存50000条数据,需要修改可以在构造方法的参数中指定。
*/
public static enum Caches {
querySnapshotBlockList(3, 1000),
querySnapshotBlockBySnapshotHash(3, 1000),
queryAccountChainBlock(3, 1000),
queryAccountView(3, 1000),
queryAccountBlock(3, 1000),
transactionTimeLine(60, 1000),
selectAccountTokenBalanceRank(60, 100),
listToken(3, 100),
detailToken(3, 100),
generalDay(60 * 60, 100),
generalSec(3, 100);

Caches() {
}

Caches(int ttl) {
this.ttl = ttl;
}

Caches(int ttl, int maxSize) {
this.ttl = ttl;
this.maxSize = maxSize;
}

private int maxSize = DEFAULT_MAXSIZE; //最大數量
private int ttl = DEFAULT_TTL; //过期时间(秒)

public int getMaxSize() {
return maxSize;
}

public int getTtl() {
return ttl;
}
}

/**
* 创建基于Caffeine的Cache Manager
*
* @return
*/
@Bean(name = "caffeineCacheManager")
@Primary
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();

ArrayList<CaffeineCache> caches = new ArrayList<CaffeineCache>();
for (Caches c : Caches.values()) {
caches.add(new CaffeineCache(c.name(),
Caffeine.newBuilder().recordStats()
.expireAfterWrite(c.getTtl(), TimeUnit.SECONDS)
.maximumSize(c.getMaxSize())
.build())
);
}

cacheManager.setCaches(caches);

return cacheManager;
}


@Bean(name = "cacheKeyGenerator")
public KeyGenerator cacheKeyGenerator() {//缓存key生成者
CacheKeyGenerator cacheKeyGenerator = new CacheKeyGenerator();
return cacheKeyGenerator;

}

}

3、使用

1
2
3
4
5
6
7
8
9
10
11
@Cacheable(value = "getTokenInfoById", key = "T(String).valueOf(#tokenCode)", unless = "#result == null")
public SimpleToken getTokenInfoById(Long tokenCode) {
InfoTokenExample infoTokenExample = new InfoTokenExample();
infoTokenExample.createCriteria().andIdEqualTo(tokenCode);
List<InfoToken> infoTokens = infoTokenMapper.selectByExample(infoTokenExample);
if (CollectionUtils.isEmpty(infoTokens)) {
logger.error("tokenInfo is null,id:{}", tokenCode);
return null;
}
return SimpleToken.builder().tokenCode(tokenCode).symbol(infoTokens.get(0).getSymbol()).tokenId(infoTokens.get(0).getTokenId()).build();
}

tokenId内存内存中存在时直接使用,否则从库中查,然后放内存。