Spring Cache監(jiān)控配置與使用規(guī)范的建議
建議
- 程序中使用的緩存,請(qǐng)?jiān)赾ache-names里指明,如此,可以通過(guò)配置文件來(lái)明白程序中用到了哪些spring cache。
- 請(qǐng)盡量對(duì)每一個(gè)cache分別設(shè)置緩存策略,因?yàn)椴挥玫腸ache其使用的場(chǎng)景與緩存對(duì)象大小都不一樣。分別設(shè)置緩存請(qǐng)使用common-spring-cache-configuere。默認(rèn)spring不支持。
- 緩存策略建議閱讀緩存策略最佳配置
- Cacheable的sync無(wú)特殊情況都設(shè)置為true,這樣,取數(shù)據(jù)時(shí)有類(lèi)似LoadingCache的效果,同時(shí)利用computeIfAbsent方法實(shí)現(xiàn)了線程安全,也防止雪崩問(wèn)題。
spring boot 2.x 監(jiān)控設(shè)置
spring boot從1.x升級(jí)到2.x之后,原先在spring-boot-actuator里默認(rèn)的一些metrics不在自動(dòng)生效,而是將這些metrics的功能從spring-boot-actuator遷移到了micrometer.io項(xiàng)目里,作為一個(gè)獨(dú)立的微服務(wù)監(jiān)控項(xiàng)目維護(hù)。
為此,為了使spring cache的相關(guān)metrics生效,需要進(jìn)行如下配置:
1.在management.endpoints.web里添加caches與metrics兩個(gè)接口暴露
默認(rèn)只暴露health、info。
management:
endpoints:
web:
exposure:
include: info, health, metrics, caches2.在spring.cache里指定cache-names的配置
spring:
cache:
cache-names: books, rooms如果不指定cache-names,spring cache metrics是不會(huì)生效的,因?yàn)閟pring是在加載的過(guò)程中來(lái)確認(rèn)需要對(duì)哪些cache來(lái)監(jiān)控,像Cacheable之類(lèi)需要?jiǎng)討B(tài)加入的cache,spring在加載過(guò)程中無(wú)法感知到。
3.對(duì)cache provider啟動(dòng)調(diào)用記錄功能
以caffeine為例,在spec中加入recordStats,如下:
spring:
cache:
cache-names: books, rooms
caffeine:
spec: recordStats4.相關(guān)url
- /actuator/caches 獲取cache manager內(nèi)的cache實(shí)例
- /actuator/metrics/cache.gets 獲取cache內(nèi)緩存對(duì)象的情況,包括hit/miss的情況,具體參考tags drillDown的使用方式https://docs.spring.io/spring-boot/docs/2.0.0.BUILD-SNAPSHOT/actuator-
- api//html/#metrics-drilling-down
- /actuator/metrics/cache.puts
- /actuator/metrics/cache.eviction
5.舉例
curl localhost:8080/actuator/metrics/ 訪問(wèn)所有支持的metrics
{
"names":[
"jvm.memory.max",
"jvm.threads.states",
"process.files.max",
"jvm.gc.memory.promoted",
"cache.puts",
"cache.size",
"cache.evictions",
"system.load.average.1m",
"jvm.memory.used",
"jvm.gc.max.data.size",
"jvm.gc.pause",
"jvm.memory.committed",
"system.cpu.count",
"logback.events",
"http.server.requests",
"tomcat.global.sent",
"jvm.buffer.memory.used",
"cache.eviction.weight",
"tomcat.sessions.created",
"jvm.threads.daemon",
"system.cpu.usage",
"jvm.gc.memory.allocated",
"tomcat.global.request.max",
"tomcat.global.request",
"cache.gets",
"tomcat.sessions.expired",
"jvm.threads.live",
"jvm.threads.peak",
"tomcat.global.received",
"process.uptime",
"tomcat.sessions.rejected",
"process.cpu.usage",
"tomcat.threads.config.max",
"jvm.classes.loaded",
"jvm.classes.unloaded",
"tomcat.global.error",
"tomcat.sessions.active.current",
"tomcat.sessions.alive.max",
"jvm.gc.live.data.size",
"tomcat.threads.current",
"process.files.open",
"jvm.buffer.count",
"jvm.buffer.total.capacity",
"tomcat.sessions.active.max",
"tomcat.threads.busy",
"process.start.time"
]
}curl localhost:8080/actuator/metrics/cache.gets 訪問(wèn)緩存get情況
{
"name":"cache.gets",
"description":"The number of times cache lookup methods have returned a cached value.",
"baseUnit":null,
"measurements":[
{
"statistic":"COUNT",
"value":0
}
],
"availableTags":[
{
"tag":"result",
"values":[
"hit",
"miss"
]
},
{
"tag":"cache",
"values":[
"rooms",
"books"
]
},
{
"tag":"name",
"values":[
"rooms",
"books"
]
},
{
"tag":"cacheManager",
"values":[
"cacheManager"
]
}
]
}curl “localhost:8080/actuator/metrics/cache.gets?tag=result:hit&tag=cache:books” 獲取名為books的cache的命中次數(shù)
{
"name":"cache.gets",
"description":"The number of times cache lookup methods have returned a cached value.",
"baseUnit":null,
"measurements":[
{
"statistic":"COUNT",
"value":0
}
],
"availableTags":[
{
"tag":"name",
"values":[
"books"
]
},
{
"tag":"cacheManager",
"values":[
"cacheManager"
]
}
]
}定制化配置
默認(rèn)coffeine.spec的配置是對(duì)全體配置的,如果要分開(kāi)配置可以自定義實(shí)現(xiàn)CacheManager,參見(jiàn)common-spring-cache-configurer. 使用時(shí),直接引入該jar包即可。
<dependency>
<groupId>com.iqiyi.intl.common</groupId>
<artifactId>common-spring-cache-configurer</artifactId>
<version>1.4.0-SNAPSHOT</version>
</dependency>使用配置如下(替換掉原先的spring.cache的配置):
cache.items:
- name: books
spec: recordStats,softValues, maximumSize=1,expireAfterWrite=100s
- name: rooms
spec: expireAfterWrite=50s, maximumSize=10000CacheManager自定義實(shí)現(xiàn)如下:
@Configuration
@ConditionalOnClass({ Caffeine.class, CaffeineCacheManager.class })
@EnableConfigurationProperties(CacheProperties.class)
public class AutoCustomizedCaffeineCacheConfigurer {
@Autowired
private CacheProperties cacheProperties;
@Bean
@Primary
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<CaffeineCache> caches = cacheProperties.getItems().stream()
.map(item -> new CaffeineCache(item.getName(), Caffeine.from(item.getSpec()).build()))
.collect(Collectors.toList());
cacheManager.setCaches(caches);
return cacheManager;
}
}緩存策略最佳配置
- 設(shè)置softvalues, 當(dāng)JVM內(nèi)存耗盡時(shí),會(huì)觸發(fā)GC,回收這些cache的內(nèi)存,防止OOM。
- 設(shè)置size或weight,限定緩存的最大占用空間,保證系統(tǒng)正常運(yùn)行。
- 設(shè)置ttl/tti,設(shè)置過(guò)期時(shí)間,根據(jù)業(yè)務(wù)實(shí)際場(chǎng)景決定時(shí)長(zhǎng)。
可以這么理解:
首先通過(guò)size或者weight來(lái)確定緩存總共占用的最大空間,softValues是用于兜底策略,防止萬(wàn)一size/weight設(shè)置的不正確,導(dǎo)致的OOM。對(duì)于ttl/tti,則是針對(duì)業(yè)務(wù)場(chǎng)景,來(lái)保證數(shù)據(jù)的時(shí)效性,用于程序運(yùn)行的正確性。
舉例如下:
cache.items:
- name: books
spec: softValues, maximumSize=1,expireAfterWrite=100s說(shuō)明:
- 所有的配置都是針對(duì)每一個(gè)cache生效的,對(duì)于cacheManager, 也就是會(huì)有多個(gè)cache,所以占用的內(nèi)容空間也會(huì)增加多份。所以cache不能設(shè)置過(guò)大。
- ttl/tti說(shuō)明,ttl (time to live), 即expireAfterWrite;tti (time to idle), 即expireAfterRead, 如果設(shè)置tti,則意味著,只要這個(gè)key直接被讀到,則緩存會(huì)一直不失效,所以請(qǐng)慎用tti。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java隨機(jī)數(shù)生產(chǎn)算法實(shí)例
下面小編就為大家?guī)?lái)一篇java隨機(jī)數(shù)生產(chǎn)算法實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10
SpringBoot自動(dòng)重啟、熱啟動(dòng)方式
這篇文章主要介紹了SpringBoot自動(dòng)重啟、熱啟動(dòng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
一個(gè)簡(jiǎn)單的Python名片管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了一個(gè)簡(jiǎn)單的Python名片管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-01-01
Java基礎(chǔ)之詳細(xì)總結(jié)五種常用運(yùn)算符
在通常代碼邏輯處理中,我們常常都會(huì)使用到運(yùn)算符,今天我們就詳細(xì)了解一下運(yùn)算符的使用以及分類(lèi).運(yùn)算符是對(duì)常量或者變量進(jìn)行操作的符號(hào),它分為算術(shù)運(yùn)算符,賦值運(yùn)算符,比較運(yùn)算符,邏輯運(yùn)算符以及位運(yùn)算符.需要的朋友可以參考下2021-05-05
Spring Date jpa 獲取最新一條數(shù)據(jù)的實(shí)例代碼
這篇文章主要介紹了Spring Date jpa 獲取最新一條數(shù)據(jù)的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-10-10
SpringBoot集成Validation參數(shù)校驗(yàn)
這篇文章主要為大家詳細(xì)介紹了SpringBoot集成Validation參數(shù)校驗(yàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

