Spring?boot?整合?Redisson實(shí)現(xiàn)分布式鎖并驗(yàn)證功能
簡(jiǎn)述
整篇文章寫的比較粗糙,大佬看了輕噴。前半部分 是整合spring boot和redisson, 后半部分是驗(yàn)證分布式鎖。在整個(gè)過(guò)程中遇見了不少的問(wèn)題,在此做個(gè)記錄少走彎路
redisson是官方推薦的分布式鎖實(shí)現(xiàn)方案,采用redis自身的原子命令和lua腳本來(lái)實(shí)現(xiàn)
1. 在idea中新建spring boot工程并引入所需依賴
idea中直接新建一個(gè)spring boot項(xiàng)目即可,再在pom.xml中引入所需依賴,依賴信息如下
<!-- redis所需 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- web頁(yè)面訪問(wèn)所需 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-data-25</artifactId> <version>3.16.4</version> </dependency> <!-- Redisson所需依賴 --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.16.4</version> </dependency>
2. 編寫相關(guān)代碼實(shí)現(xiàn)
采用一個(gè)票卷庫(kù)存來(lái)進(jìn)行鎖的驗(yàn)證,需要預(yù)先在redis里面設(shè)置一個(gè)key為ticket的信息,值為100之類的數(shù)字即可 代碼示例編寫:
@RestController @Slf4j public class RedisController { // spring boot 操作redis的模板方法類 @Autowired private StringRedisTemplate redisTemplate; // redisson操作bean @Resource private Redisson redisson; @RequestMapping("/lock") public String deductTicket(){ String lockKey = "ticket"; // 在spring boot 2.0.6版本中整合的redisson,key和鎖不能一樣 // redis setnx 操作,此處的lockKey在后面追加1是為了避免redisson鎖時(shí)報(bào)錯(cuò), 需要和待鎖住的數(shù)據(jù)的key信息不同 RLock lock = redisson.getLock(lockKey+"1"); try { lock.lock(); int ticketCount = Integer.parseInt(redisTemplate.opsForValue().get(lockKey)); if (ticketCount > 0) { int realTicketCount = ticketCount - 1; log.info("扣除成功:剩余票數(shù):" + realTicketCount); redisTemplate.opsForValue().set(lockKey, realTicketCount + ""); return realTicketCount + ""; } else { log.error("扣除失敗"); return "error"; } return "end"; } finally { lock.unlock(); } } }
application.yml配置信息如下
server: port: 8899 # web服務(wù)對(duì)外端口 redis: host: 192.168.0.160 #redis地址 database: 0 #采用的庫(kù)編號(hào) port: 6379 #redis端口 password: 123456 #redis密碼,如果redis沒(méi)有設(shè)置密碼直接去掉該配置不寫空
3. 模擬實(shí)際環(huán)境驗(yàn)證
一個(gè)簡(jiǎn)單的分布式鎖驗(yàn)證的demo完成了,比較粗糙,驗(yàn)證的方式有多樣的,可以采用java本身的多線程進(jìn)行驗(yàn)證,也可以類似實(shí)際環(huán)境部署多個(gè)節(jié)點(diǎn)來(lái)驗(yàn)證,這里為了技術(shù)的廣度的一個(gè)應(yīng)用,采用后面的方式。
3.1 下載idea的docker插件并配置相關(guān)鏡像信息
- docker插件下載
idea配置docker連接虛擬機(jī)上的docker
開啟docker遠(yuǎn)程連接
vim /usr/lib/systemd/system/docker.service
找到 ExecStart,在最后面添加 -H tcp://0.0.0.0:2375
重啟docker
systemctl daemon-reload systemctl start docker
開放端口
firewall-cmd --zone=public --add-port=2375/tcp --permanent
idea配置docker連接
配置完成后可在idea中看到連接的docker鏡像、容器相關(guān)信息
3.2 將spring boot打包的jar構(gòu)建為docker鏡像
編寫Dockerfile
在工程目錄中新建Dockerfile,與pom.xml文件同級(jí)
Dockerfile內(nèi)容如下
FROM openjdk:8-jdk-alpine # 指定基礎(chǔ)鏡像為jdk8 ADD target/spring-0.0.1-SNAPSHOT.jar app.jar #將打包的jar包放入鏡像中并重命名為app.jar ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"] #啟動(dòng)jar包
在pom.xml中添加插件信息
<plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>1.0.0</version> <configuration> <imageName>com.demo/${project.artifactId}</imageName> <dockerDirectory></dockerDirectory> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin>
idea添加docker構(gòu)建配置
此處操作的目的是為了便于在idea中直接構(gòu)建鏡像啟動(dòng)容器
配置信息如下
(1)Dockerfile文件位置
(2)鏡像tag
(3)構(gòu)建成功后啟動(dòng)的容器名稱
(4)端口映射 宿主機(jī)端口:容器內(nèi)端口
jar包打好之后可直接點(diǎn)擊
如果沒(méi)有問(wèn)題idea的docker控制臺(tái)會(huì)輸出容器內(nèi)啟動(dòng)相關(guān)日志信息
此處為了驗(yàn)證分布式鎖,需要兩個(gè)節(jié)點(diǎn)以上,所以這里我手動(dòng)啟動(dòng)了另外一個(gè)docker容器(暫時(shí)沒(méi)有編寫shell腳本)
啟動(dòng)命令如下
docker run -d --name demo2 -p 8900:8899 demo:1.1
容器名稱demo2 映射到宿主機(jī)端口 8900
查看應(yīng)用日志可使用 docker logs -f 容器名稱
spring boot 構(gòu)建docker鏡像應(yīng)該有更簡(jiǎn)單的方式,歡迎在評(píng)論區(qū)交流補(bǔ)充
3.2 配置nginx
可以更改默認(rèn)的日志格式如下,為了記錄代理的具體節(jié)點(diǎn)信息
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for" ' '"$upstream_addr"';
配置負(fù)載均衡
upstream tomcat { server 192.168.0.160:8899 weight=10; # 此處設(shè)置權(quán)重為相同的即可 server 192.168.0.160:8900 weight=10; }
配置代理
location / { proxy_pass http://tomcat; proxy_redirect default; }
完整的代理配置如下
配置完成后
nginx -s reload
進(jìn)行訪問(wèn)驗(yàn)證
192.168.0.160/lock
可查看nginx、容器內(nèi)日志信息來(lái)驗(yàn)證是否訪問(wèn)成功
nginx如何訪問(wèn)出現(xiàn)error,可查看nginx中的錯(cuò)誤日志。如果是權(quán)限問(wèn)題(# failed (13: Permission denied) while connecting to upstream) 可用root用戶啟動(dòng)或使用命令 setsebool -P httpd_can_network_connect 1
來(lái)解決
3.3 下載安裝Jmeter進(jìn)行測(cè)試
Jmeter下載地址:jmeter.apache.org/download_jm…
下載解壓后在bin目錄中店家jmeter.bat即可啟動(dòng)jmeter
新增計(jì)劃
配置線程信息
(1) 請(qǐng)求線程數(shù)
(2) 多少s內(nèi)啟動(dòng)完線程 設(shè)置為0代表同時(shí)啟動(dòng) 設(shè)置為2代表2s內(nèi)啟動(dòng)完20個(gè)線程,1s啟動(dòng)10個(gè)線程
添加請(qǐng)求
(1) ip地址
(2) 端口
(3) path信息,這里設(shè)置為jar中的地址信息
點(diǎn)擊綠色三角箭頭啟動(dòng)并進(jìn)行驗(yàn)證
查看redis緩存中設(shè)置的數(shù)據(jù)是否在測(cè)試完成后符合預(yù)期值,也可查看nginx中的日志來(lái)確定請(qǐng)求是否平均分配到了兩個(gè)節(jié)點(diǎn)
到此這篇關(guān)于Spring boot 整合 Redisson實(shí)現(xiàn)分布式鎖并驗(yàn)證的文章就介紹到這了,更多相關(guān)Spring boot 分布式鎖內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 微服務(wù)Spring?Boot?整合Redis?阻塞隊(duì)列實(shí)現(xiàn)異步秒殺下單思路詳解
- SpringBoot整合redis及mongodb的詳細(xì)過(guò)程
- springboot整合使用云服務(wù)器上的Redis方法
- Spring?Boot?整合Redis?實(shí)現(xiàn)優(yōu)惠卷秒殺?一人一單功能
- SpringBoot整合Redis實(shí)現(xiàn)常用功能超詳細(xì)過(guò)程
- SpringBoot整合Shiro和Redis的示例代碼
- 微服務(wù)Spring Boot 整合 Redis 實(shí)現(xiàn)好友關(guān)注功能
相關(guān)文章
Spring實(shí)戰(zhàn)之Bean的作用域request用法分析
這篇文章主要介紹了Spring實(shí)戰(zhàn)之Bean的作用域request用法,結(jié)合實(shí)例形式分析了spring中Bean的request作用域相關(guān)使用技巧與操作注意事項(xiàng),需要的朋友可以參考下2019-11-11Springboot pom項(xiàng)目間接依賴包版本與預(yù)期不符原因解決分析
這篇文章主要介紹了Springboot pom項(xiàng)目間接依賴包版本與預(yù)期不符原因解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08java得到某年某周的第一天實(shí)現(xiàn)思路及代碼
某年某周的第一天,此功能如何使用java編程得到呢?既然有了問(wèn)題就有解決方法,感興趣的朋友可以了解下本文,或許會(huì)給你帶來(lái)意想不到的收獲哦2013-01-01Knife4j?3.0.3?整合SpringBoot?2.6.4的詳細(xì)過(guò)程
本文要講的是?Knife4j?3.0.3?整合SpringBoot?2.6.4,在SpringBoot?2.4以上的版本和之前的版本還是不一樣的,這個(gè)也容易導(dǎo)致一些問(wèn)題,本文就這兩個(gè)版本的整合做一個(gè)實(shí)戰(zhàn)介紹2022-09-09SpringBoot實(shí)現(xiàn)固定和動(dòng)態(tài)定時(shí)任務(wù)的三種方法
定時(shí)器是我們項(xiàng)目中經(jīng)常會(huì)用到的,本文主要介紹了SpringBoot實(shí)現(xiàn)固定和動(dòng)態(tài)定時(shí)任務(wù)的三種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09Java實(shí)戰(zhàn)之藥品管理系統(tǒng)的實(shí)現(xiàn)
這篇文章主要介紹了利用Java實(shí)現(xiàn)的藥品管理系統(tǒng),本項(xiàng)目屬于前后端分離的項(xiàng)目,分為兩個(gè)角色藥品管理員和取藥處人員,感興趣的小伙伴可以學(xué)習(xí)一下2022-04-04springboot默認(rèn)日志框架選擇源碼解析(推薦)
這篇文章主要介紹了springboot默認(rèn)日志框架選擇源碼解析(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03