日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

java 项目做多级缓存_【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)...

發(fā)布時間:2023/12/1 javascript 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 项目做多级缓存_【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、緩存

當系統(tǒng)的并發(fā)量上來了,如果我們頻繁地去訪問數(shù)據(jù)庫,那么會使數(shù)據(jù)庫的壓力不斷增大,在高峰時甚至可以出現(xiàn)數(shù)據(jù)庫崩潰的現(xiàn)象。所以一般我們會使用緩存來解決這個數(shù)據(jù)庫并發(fā)訪問問題,用戶訪問進來,會先從緩存里查詢,如果存在則返回,如果不存在再從數(shù)據(jù)庫里查詢,最后添加到緩存里,然后返回給用戶,當然了,接下來又能使用緩存來提供查詢功能。

而緩存,一般我們可以分為本地緩存和分布式緩存。

常用的本地緩存有 ehcache、guava cache,而我們一般都是使用 ehcache,畢竟他是純 Java 的,出現(xiàn)問題我們還可以根據(jù)源碼解決,并且還能自己進行二次開發(fā)來擴展功能。

常用的分布式緩存當然就是 Redis 了,Redis 是基于內(nèi)存和單線程的,執(zhí)行效率非常的高。

二、Spring Cache

相信如果要整合緩存到項目中,大家都會使用到 Spring Cache,它不但整合了多種緩存框架(ehcache、jcache等等),還可以基于注解來使用,是相當?shù)姆奖恪?/p>

緩存框架的整合在 spring-context-support 中:

緩存注解在 spring-context 中:

當然了,在 Spring 的 context 中沒有整合 Redis,但是我們可以在 spring-data-redis 中找到。

但是我們都知道,不管是在 Spring 項目 還是 Spring Boot 中,我們都只能整合一種緩存,不能同時整合多種緩存。

在 Spring Boot 中,我們一般是利用 spring.cache.type 來指定使用哪種緩存,然后填寫相關配置信息來完成自動配置。

CacheType 的源碼:我們可以看到,Spring 是支持非常多種緩存框架的。

package org.springframework.boot.autoconfigure.cache;

public enum CacheType {

GENERIC,

JCACHE,

EHCACHE,

HAZELCAST,

INFINISPAN,

COUCHBASE,

REDIS,

CAFFEINE,

SIMPLE,

NONE;

private CacheType() {

}

}

那么如果我們就是有這么一種需求,要整合兩種緩存框架:例如一個本地緩存 Ehcache,一個分布式緩存 Redis,

那能整么?

能是能,但是 Spring 可不提供這種多級緩存,而是需要你自己動手來整了。

三、h2cache-spring-boot-starter

1、什么是 h2cache-spring-boot-starter?

在微服務中,每個服務都是無狀態(tài)的,服務之間需要經(jīng)過 HTTP 或者 RPC 來進行通信。而每個服務都擁有自己對應的數(shù)據(jù)庫,所以說如果服務A 需要獲取服務B 的某個表的數(shù)據(jù),那么就需要一次 HTTP 或 RPC 通信,那如果高峰期每秒需要調用100次,那豈不是需要100次 HTTP 或 RPC 通信,這是相當耗費接口性能的。

那怎么解決呢?

本地緩存那是肯定不是的,因為一般不同服務都是部署在不同的機器上面的,所以此時我們需要的是分布式緩存,例如 Redis;但是,訪問量高的的服務當然還是需要本地緩存了。所以最后,我們不但需要本地緩存,還需要分布式緩存,但是 Spring Boot 卻不能提供這種多級緩存的功能,所以需要我們自己來整合。

不用怕,我已經(jīng)自己整了一個 Spring Boot Starter了,就是h2cache-spring-boot-starter,我們只需要在配置文件配置上對應的信息,就可以啟用這個多級緩存的功能了。

2、開始使用

添加依賴:

大家正常引入下面依賴即可,因為我已經(jīng)將此項目發(fā)布到 Maven 中央倉庫了~

com.github.howinfun

h2cache-spring-boot-starter

0.0.1

在 Spring Boot properties 啟用服務,并且加上對應的配置:

開啟多級緩存服務:

# Enable L2 cache or not

h2cache.enabled=true

配置 Ehcache:

# Ehcache Config

## the path of ehcache.xml (We can put it directly under Resources)

h2cache.ehcache.filePath=ehcache.xml

#Set whether the EhCache CacheManager should be shared (as a singleton at the ClassLoader level) or independent (typically local within the application).Default is "false", creating an independent local instance.

h2cache.ehcache.shared=true

配置 Redis:主要包括默認的緩存配置和自定義緩存配置

要注意一點的是:h2cache-spring-boot-starter 同時引入了 Lettuce 和 Jedis 客戶端,而 Spring Boot 默認使用 Lettuce 客戶端,所以如果我們需要使用 Jedis 客戶端,需要將 Lettuce 依賴去除掉。

# Redis Config

## default Config (expire)

h2cache.redis.default-config.ttl=200

### Disable caching {@literal null} values.Default is "false"

h2cache.redis.default-config.disable-null-values=true

### Disable using cache key prefixes.Default is "true"

h2cache.redis.default-config.use-prefix=true

## Custom Config list

### cacheName -> @CacheConfig#cacheNames @Cacheable#cacheNames and other comments, etc

h2cache.redis.config-list[0].cache-name=userCache

h2cache.redis.config-list[0].ttl=60

h2cache.redis.config-list[0].use-prefix=true

h2cache.redis.config-list[0].disable-null-values=true

h2cache.redis.config-list[1].cache-name=bookCache

h2cache.redis.config-list[1].ttl=60

h2cache.redis.config-list[1].use-prefix=true

#Redis

spring.redis.host=10.111.0.111

spring.redis.password=

spring.redis.port=6379

spring.redis.database=15

# 連接池最大連接數(shù)(使用負值表示沒有限制)

spring.redis.jedis.pool.max-active=8

# 連接池中的最小空閑連接

spring.redis.jedis.pool.min-idle=0

# 連接池中的最大空閑連接

spring.redis.jedis.pool.max-idle=8

# 連接池最大阻塞等待時間(使用負值表示沒有限制)

spring.redis.jedis.pool.max-wait=30

如何使用緩存注解

我們只要像之前一樣使用 Spring Cache 的注解即可。

for example:

代碼里的持久層,我使用的是: mybatis-plus.

package com.hyf.testDemo.redis;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;

import org.springframework.cache.annotation.CacheConfig;

import org.springframework.cache.annotation.CacheEvict;

import org.springframework.cache.annotation.CachePut;

import org.springframework.cache.annotation.Cacheable;

import org.springframework.cache.annotation.Caching;

import org.springframework.stereotype.Repository;

/**

* @author Howinfun

* @desc

* @date 2020/3/25

*/

@Repository

// Global cache config,We usually set the cacheName

@CacheConfig(cacheNames = {"userCache"})

public interface UserMapper extends BaseMapper {

/**

* put the data to cache(Ehcache & Redis)

* @param id

* @return

*/

@Cacheable(key = "#id",unless = "#result == null")

User selectById(Long id);

/**

* put the data to cache After method execution

* @param user

* @return

*/

@CachePut(key = "#user.id", condition = "#user.name != null and #user.name != ''")

default User insert0(User user) {

this.insert(user);

return user;

}

/**

* evict the data from cache

* @param id

* @return

*/

@CacheEvict(key = "#id")

int deleteById(Long id);

/**

* Using cache annotations in combination

* @param user

* @return

*/

@Caching(

evict = {@CacheEvict(key = "#user.id", beforeInvocation = true)},

put = {@CachePut(key = "#user.id")}

)

default User updateUser0(User user){

this.updateById(user);

return user;

}

}

測試一下:

查詢:我們可以看到,在數(shù)據(jù)庫查詢到結果后,會將數(shù)據(jù)添加到 Ehcache 和 Redis 緩存中;接著之后的查詢都將會先從 Ehcache 或者 Redis 里查詢。

2020-04-03 09:55:09.691 INFO 5920 --- [nio-8080-exec-7] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...

2020-04-03 09:55:10.044 INFO 5920 --- [nio-8080-exec-7] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.

2020-04-03 09:55:10.051 DEBUG 5920 --- [nio-8080-exec-7] c.h.t.redis.BookMapper2.selectById : ==> Preparing: SELECT id,create_time,update_time,read_frequency,version,book_name FROM book WHERE id=?

2020-04-03 09:55:10.068 DEBUG 5920 --- [nio-8080-exec-7] c.h.t.redis.BookMapper2.selectById : ==> Parameters: 51(Long)

2020-04-03 09:55:10.107 DEBUG 5920 --- [nio-8080-exec-7] c.h.t.redis.BookMapper2.selectById : <== Total: 1

2020-04-03 09:55:10.113 INFO 5920 --- [nio-8080-exec-7] c.hyf.cache.cachetemplate.H2CacheCache : insert into ehcache,key:51,value:Book2(id=51, bookName=微服務架構, readFrequency=1, createTime=2020-03-20T16:10:13, updateTime=2020-03-27T09:14:44, version=1)

2020-04-03 09:55:10.118 INFO 5920 --- [nio-8080-exec-7] c.hyf.cache.cachetemplate.H2CacheCache : insert into redis,key:51,value:Book2(id=51, bookName=微服務架構, readFrequency=1, createTime=2020-03-20T16:10:13, updateTime=2020-03-27T09:14:44, version=1)

2020-04-03 09:55:31.864 INFO 5920 --- [nio-8080-exec-2] c.hyf.cache.cachetemplate.H2CacheCache : select from ehcache,key:51

刪除:刪除數(shù)據(jù)庫中的數(shù)據(jù)后,也會刪除 Ehcache 和 Redis 中對應的緩存數(shù)據(jù)。

2020-04-03 10:05:18.704 DEBUG 5920 --- [nio-8080-exec-3] c.h.t.redis.BookMapper2.deleteById : ==> Preparing: DELETE FROM book WHERE id=?

2020-04-03 10:05:18.704 DEBUG 5920 --- [nio-8080-exec-3] c.h.t.redis.BookMapper2.deleteById : ==> Parameters: 51(Long)

2020-04-03 10:05:18.731 DEBUG 5920 --- [nio-8080-exec-3] c.h.t.redis.BookMapper2.deleteById : <== Updates: 1

2020-04-03 10:05:18.732 INFO 5920 --- [nio-8080-exec-3] c.hyf.cache.cachetemplate.H2CacheCache : delete from ehcache,key:51

2020-04-03 10:05:18.844 INFO 5920 --- [nio-8080-exec-3] c.hyf.cache.cachetemplate.H2CacheCache : delete from redis,key:51

其他的就不用演示了...

四、最后

當然啦,這個 starter 還是比較簡單的,如果大家感興趣,可以去看看源碼是如何基于 Spring Cache 實現(xiàn)多級緩存的~

總結

以上是生活随笔為你收集整理的java 项目做多级缓存_【开源项目系列】如何基于 Spring Cache 实现多级缓存(同时整合本地缓存 Ehcache 和分布式缓存 Redis)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。