生活随笔
收集整理的這篇文章主要介紹了
SringBoot+Redis整合
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
緩存使用設(shè)計(jì)
連接緩存
查詢緩存
如果緩存中沒(méi)有再到MySQL中查詢
mysql查詢結(jié)果放入redis
Redis整合步驟
將redis整合到項(xiàng)目中(redis+spring)
引入pom依賴信息(所有redis統(tǒng)一放在service-util)
<dependency><groupId>redis
.clients
</groupId
><artifactId>jedis
</artifactId
><version>2.9.0</version
>
</dependency
>
寫(xiě)一個(gè)redis工具類(lèi)(將redis的初始化到spring容器中)
public class RedisUtil {private JedisPool jedisPool
;public void initPool(String host
,int port
,int database
){JedisPoolConfig poolConfig
= new JedisPoolConfig();poolConfig
.setMaxTotal(200);poolConfig
.setMaxIdle(30);poolConfig
.setBlockWhenExhausted(true);poolConfig
.setMaxWaitMillis(10*1000);poolConfig
.setTestOnBorrow(true);jedisPool
=new JedisPool(poolConfig
,host
,port
,20*1000);}public Jedis getJedis(){Jedis jedis
= jedisPool
.getResource();return jedis
;}}
將redisUtils的連接池整合到spring容器中RedisConfig
@Configuration
public class RedisConfig {@Value("${spring.redis.host:disabled}")private String host
;@Value("${spring.redis.port:0}")private int port
;@Value("${spring.redis.database:0}")private int database
;@Beanpublic RedisUtil getRedisUtil(){if(host
.equals("disabled")){return null;}RedisUtil redisUtil
=new RedisUtil();redisUtil
.initPool(host
,port
,database
);return redisUtil
;}}
同時(shí),任何模塊想要調(diào)用redis都必須在application.properties配置,否則不會(huì)進(jìn)行注入。
spring
.redis
.host
=redis
.server
.com
spring
.redis
.port
=6379
spring
.redis
.database
=0
redis常見(jiàn)問(wèn)題
1.緩存在高并發(fā)和安全壓力下的問(wèn)題
緩存穿透:查詢一個(gè)不存在的數(shù)據(jù),redis緩存沒(méi)命中,去查詢數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù)中因?yàn)闆](méi)有此紀(jì)錄
解決辦法:空結(jié)果進(jìn)行緩存,設(shè)置過(guò)期時(shí)間,最長(zhǎng)不超過(guò)五分鐘緩存雪崩:緩存使用相同的過(guò)期時(shí)間,導(dǎo)致某一時(shí)刻緩存失效,導(dǎo)致DB崩潰
解決辦法:設(shè)置不同的過(guò)期時(shí)間緩存擊穿:某一個(gè)熱點(diǎn)key在高并發(fā)訪問(wèn)情況下突然失效,導(dǎo)致大量請(qǐng)求直至訪問(wèn)MySQL數(shù)據(jù)庫(kù)
解決辦法:使用redis數(shù)據(jù)庫(kù)的分布式鎖,解決MySQL訪問(wèn)壓力
第一種方式:redis自帶的分布式鎖set ex nx
set sku:108:lock(key) 1(value) px 10000(過(guò)期時(shí)間) nx(redis分布式鎖的的參數(shù))
第二種方式:redission框架:一個(gè)redis自帶的jcu的lock功能的客戶端實(shí)現(xiàn)(既有redis功能又有jcu功能)
緩存穿透、緩存雪崩、緩存擊穿區(qū)別:
1.擊穿某一個(gè)熱點(diǎn)key失效
2.雪崩很多key集體失效
3.穿透利用不存在的key繞過(guò)redis直接攻擊db
2.關(guān)于lua腳本問(wèn)題
如果在redis中的鎖已過(guò)期,然后過(guò)期的鎖請(qǐng)求完畢,回來(lái)刪鎖,刪除了其他線程的鎖怎么辦?
解決辦法:
String token
= UUID
.randomUUID().toString();String OK
= jedis
.set("sku:" + skuId
+ ":lock", token
, "nx", "px", 10*1000);String lockToken
= jedis
.get("sku:" + skuId
+ ":lock");if(StringUtils.isNotEmpty(lockToken
)&& lockToken
.equals(token
)) {jedis
.del("sku:" + skuId
+ "lock");
}
如果碰巧在查詢r(jià)edis鎖時(shí)還沒(méi)刪除鎖,正在網(wǎng)絡(luò)傳輸時(shí)key過(guò)期怎么辦?
決解辦法:可以在lua腳本查詢到key的同時(shí)刪除key,防止高并發(fā)下意外的發(fā)生
Redis的分布式工具框架Redission
可重入鎖(
Reentrant Lock)
基于
Redis的
Redisson分布式可重入鎖
RLock Java對(duì)象實(shí)現(xiàn)了
java.util.concurrent.locks.Lock接口。
同時(shí)還提供了異步(
Async)、反射式(
Reactive)和
RxJava2標(biāo)準(zhǔn)的接口。
RLock lock
= redisson
.getLock("anyLock");
lock
.lock();
將Redission整合到Spring中來(lái)
@Configuration
public class RedissonConfig {@Value("${spring.redis.host}")private String host
;@Value("${spring.redis.port}")private String port
;@Value("${spring.redis.password}")private String password
;@Beanpublic RedissonClient redissonClient(){Config config
= new Config();config
.useSingleServer().setPassword(password
);config
.useSingleServer().setAddress("redis://"+host
+":"+port
);RedissonClient redisson
= Redisson.create(config
);return redisson
;}
}
配置Redission在SpringBoot的application.properties文件中
server
.port
=8082#jdbc 配置
spring
.datasource
.url
=jdbc
:mysql
://localhost
:3306/crm
?useUnicode
=true&characterEncoding
=UTF
-8&serverTimezone
=UTC
spring
.datasource
.username
=root
spring
.datasource
.password
=xxxmybatis
.mapper
-locations
=classpath
:mapper
配置RedissionController類(lèi)
@Controller
public class RedissionController {@AutowiredRedisUtil redisUtil
;@AutowiredRedissonClient redissonClient
;@RequestMapping("testRedission")@ResponseBodypublic String lockTest(){Jedis jedis
= redisUtil
.getJedis();RLock lock
= redissonClient
.getLock("redis-lock");lock
.lock();try {String v
= jedis
.get("k");System.err
.print("==>"+v
);if(StringUtil.isBlank(v
)){v
= "1";}int inum
= Integer.parseInt(v
);jedis
.set("k", inum
+1+"");jedis
.close();} finally {lock
.unlock();}return "success";
}
Redission-nginx負(fù)載均衡配置,nginx默認(rèn)監(jiān)聽(tīng)端口號(hào)為80
啟動(dòng)nginx:start nginx
idea中去掉單例模式啟動(dòng)
redisson分布式壓力測(cè)試
Linux
linux直接yum -y install httpd-tools,然后ab -V測(cè)試
Windows
1查看80端口有沒(méi)有被占用,netstat -ano | findstr “80”
2下載地址https://www.apachehaus.com/cgi-bin/download.plx
3解壓后,找到安裝目錄下的httpd.conf,修改為自己的安裝目錄及修改監(jiān)聽(tīng)端口號(hào)默認(rèn)為80端口,需要改為如(8088)
4 啟動(dòng)服務(wù)
5 命令示例(并發(fā)200,一共1000個(gè)請(qǐng)求)
D:\software\apache24\bin>ab -c 200 -n 1000 http:nginx負(fù)載均衡/壓力方法
6 測(cè)試結(jié)果
研究redisson的分布式鎖在并發(fā)下的效果
總結(jié)
以上是生活随笔為你收集整理的SringBoot+Redis整合的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。