一.springboot整合redis.
1.引入依賴.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
? ? ?其實(shí)springboot整合其他主流框架直接在后面加上名稱即可,比如spring-boot-starter-redis,然后就直接可以用,可以直接注入了.
? ? ?主要原因大概就是springboot框架已經(jīng)包含了自動(dòng)注入的功能,對(duì)于每一個(gè)引入的主要jar包(包含starter),都有一個(gè)factory的配置文件,里面配置了jar包的全路徑,有了這個(gè)路徑就可以將這些類處理然后注入到spring工廠中,我們就可以直接使用.
2.添加配置.
#地址
spring.redis.host=192.168.68.2
#端口
spring.redis.port=6379
#超時(shí)時(shí)間
spring.redis.timeout=60000
集群的話可以使用以下兩個(gè)配置
#以下是最關(guān)鍵的兩個(gè)配置,
#最大的切換連接節(jié)點(diǎn)的數(shù)目,當(dāng)連接某一個(gè)節(jié)點(diǎn)不成功時(shí),會(huì)去連接另一個(gè)節(jié)點(diǎn)
spring.redis.cluster.max-redirects=1000
spring.redis.cluster.nodes=192.168.5.111:6380,192.168.5.111:6381,192.168.5.111:6382,192.168.5.111:6383,192.168.5.111:6384,192.168.5.111:6385
3.使用封裝對(duì)象舉例
@Service
public class RedisService {
@Resource
RedisTemplate<String,String> template;
ValueOperations<String, String> string = template.opsForValue();
HashOperations<String, Object, Object> hash = template.opsForHash();
ListOperations<String, String> list = template.opsForList();
SetOperations<String, String> set = template.opsForSet();
ZSetOperations<String, String> zset = template.opsForZSet();
//封裝String類型方法
public void set(String key,String value){
string.set(key,value);
}
public String get(String key){
return string.get(key);
}
//封裝hash方法
public void hset(String key,String itemKey,String itemValue){
hash.put(key,itemKey,itemValue);
}
public String hget(String key,String itemKey){
return (String)hash.get(key,itemKey);
}
}
-----測(cè)試-----
@org.junit.Test
public void TestRedisService(){
redis.set("name","wang");
redis.hset("hset","韓信","刺客");
System.out.println(redis.get("name"));
System.out.println(redis.hget("hset","韓信"));
}
二.細(xì)節(jié)講解
出現(xiàn)問題,堆外內(nèi)存溢出
當(dāng)我們的項(xiàng)目直接使用以上配置的時(shí)候,對(duì)項(xiàng)目進(jìn)行壓測(cè),可能很快就出現(xiàn)堆外內(nèi)存溢出.
? ? ?出現(xiàn)這個(gè)問題的原因就是lettuce操作netty的bug,在springboot2.0以后,默認(rèn)使用lettuce作為操作redis的客戶端.它使用netty進(jìn)行網(wǎng)絡(luò)通信,因?yàn)檫@個(gè)bug導(dǎo)致netty堆外內(nèi)存溢出.
? ? ? 假如我們的項(xiàng)目設(shè)置jvm最大內(nèi)存為200m,那么netty如果沒有指定堆外內(nèi)存的話,就會(huì)默認(rèn)使用我們這里的200m作為堆外內(nèi)存的大小.同時(shí)這個(gè)堆外內(nèi)存的使用并不會(huì)得到及時(shí)釋放,將會(huì)不斷增加.所以會(huì)出現(xiàn)堆外內(nèi)存溢出.
解決方案,切換客戶端
這里有兩個(gè)解決方案:
- 升級(jí)lettuce客戶端
- 切換客戶端為jedis.
因?yàn)榭紤]到升級(jí)版本可能會(huì)帶來其他的兼容問題,這里選擇一種比較簡(jiǎn)單的方式,切換客戶端為jedis.
切換方式:
直接修改pom即可,其他代碼,配置都不用改.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
三.補(bǔ)充原理.
??????我們直接將操作redis的客戶端由lettuce切換成jedis,但是使用的時(shí)候卻不用做任何修改操作,
可以說非常方便,這是為什么呢?
??????無論是lettuce還是jedis,都是操作redis的底層客戶端, spring都對(duì)其進(jìn)行了統(tǒng)一的封裝,也就是封裝成restTemplate. 從配置層面就可以看到這個(gè)關(guān)系.
??????那怎么看底層的注入配置呢?其實(shí)springboot整合很多其他第三方組件,Redis,Mybatis,Elasticsearch等等都會(huì)有一個(gè)XXXAutoConifguration的配置類.直接搜索這個(gè)配置類即可.
這里我們主要看RedisAutoConfiguration.
而在對(duì)應(yīng)的LettuceConnectionConfiguration和JedisConnectionConfiguration配置類中,都會(huì)向spring注入RedisConnectionFactory這個(gè)bean(在spring缺失這個(gè)bean的條件下)
??????這樣,即使底層切換了客戶端,在使用層面也不需要做任何修改.是非常方便的.
??????其實(shí)想一想如果我們自己去實(shí)現(xiàn)這個(gè)功能,你很有可能直接一套if else,沒有jedis的話用lettuce,將來再新增一個(gè)其他的客戶端,又增加個(gè)if else,這樣是非常不美觀,且不具有擴(kuò)展性的,所以我們最重要的還是要學(xué)習(xí)這種思想,運(yùn)用到我們自己的實(shí)際工作中.文章來源:http://www.zghlxwxcb.cn/news/detail-490360.html
今天的分享就到這里了,有問題可以在評(píng)論區(qū)留言,均會(huì)及時(shí)回復(fù)呀.
我是bling,未來不會(huì)太差,只要我們不要太懶就行, 咱們下期見.文章來源地址http://www.zghlxwxcb.cn/news/detail-490360.html
到了這里,關(guān)于springboot(spring)整合redis(集群)、細(xì)節(jié)、底層配置講解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!