欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

Redis實(shí)現(xiàn)高并發(fā)分布式鎖-創(chuàng)新互聯(lián)

分布式鎖場景

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),中衛(wèi)企業(yè)網(wǎng)站建設(shè),中衛(wèi)品牌網(wǎng)站建設(shè),網(wǎng)站定制,中衛(wèi)網(wǎng)站建設(shè)報(bào)價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,中衛(wèi)網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競爭力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。

在分布式環(huán)境下多個操作需要以原子的方式執(zhí)行

首先啟一個springboot項(xiàng)目,再引入redis依賴包:

org.springframework.boot

spring-boot-starter-data-redis

2.2.2.RELEASE

以下是一個扣減庫存的接口作為例子:

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

return "end";

}

}

1.單實(shí)例應(yīng)用場景

以上代碼使用JMeter壓測工具進(jìn)行調(diào)用,設(shè)置參數(shù)為:

Number Of Threads[users]:100

Ramp Up Period[in seconds]:0

Loop Count:2

用單個web調(diào)用,結(jié)果出現(xiàn)并發(fā)問題:

Redis實(shí)現(xiàn)高并發(fā)分布式鎖

解決方案:加入同步鎖(synchronized)

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

synchronized(this) {

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

return "end";

}

}

}

2.多實(shí)例分布式場景

以上代碼,比如有多個應(yīng)用程序,用nginx做負(fù)載均衡,進(jìn)行同時調(diào)用壓測

兩個程序存在同樣的扣減,出現(xiàn)并發(fā)現(xiàn)象。

第一個應(yīng)用扣減結(jié)果顯示:

Redis實(shí)現(xiàn)高并發(fā)分布式鎖

第二個應(yīng)用扣減結(jié)果顯示:

Redis實(shí)現(xiàn)高并發(fā)分布式鎖

解決方案:redis的setnx方法(可參考SETNX的api)

多個線程setnx調(diào)用時,有且僅有一個線程會拿到這把鎖,所以拿到鎖的執(zhí)行業(yè)務(wù)代碼,最后釋放掉鎖,代碼如下:

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

String lockkey = "lockkey";

Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,"lockvalue");//jedis.setnx

if(!result) {

return "";

}

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

springRedisTemplate.delete(lockkey);

return "end";

}

}

調(diào)用200次,壓測結(jié)果顯示還是有問題,只減掉了一部分:

Redis實(shí)現(xiàn)高并發(fā)分布式鎖

這時,加大壓測次數(shù),結(jié)果正常了:

第一個應(yīng)用扣減結(jié)果顯示:

Redis實(shí)現(xiàn)高并發(fā)分布式鎖

第二個應(yīng)用扣減結(jié)果顯示:

Redis實(shí)現(xiàn)高并發(fā)分布式鎖

這個只是因?yàn)榧哟罅苏{(diào)用次數(shù),執(zhí)行業(yè)務(wù)代碼需要一點(diǎn)時間,這段時間拒絕了很多等待獲取鎖的請求。但是,還是有問題,假如redis服務(wù)掛掉了,拋出異常了,這時鎖不會被釋放掉,出現(xiàn)死鎖問題,可以添加try catch處理,代碼如下:

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

String lockkey = "lockkey";

try{鄭州專業(yè)婦科醫(yī)院 http://fk.zyfuke.com/

Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,"lockvalue");//jedis.setnx

if(!result) {

return "";

}

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

}finally{

springRedisTemplate.delete(lockkey);

}

return "end";

}

}

這時,Redis服務(wù)掛掉導(dǎo)致死鎖的問題解決了,但是,如果服務(wù)器果宕機(jī)了,又會導(dǎo)致鎖不能被釋放的現(xiàn)象,所以可以設(shè)置超時時間為10s,代碼如下:

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

String lockkey = "lockkey";

try{

Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,"lockvalue",10,TimeUnit.SECONDS);//jedis.setnx

//Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,"lockvalue");//jedis.setnx

//stringRedisTemplate.expire(lockkey,10,TimeUnit.SECONDS);

if(!result) {

return "";

}

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

}finally{

springRedisTemplate.delete(lockkey);

}

return "end";

}

}

這時,如果有一個線程執(zhí)行需要15s,當(dāng)執(zhí)行到10s時第二個線程進(jìn)來拿到這把鎖,會出現(xiàn)多個線程拿到同一把鎖執(zhí)行,在第一個線程執(zhí)行完時會釋放掉第二個線程的鎖,以此類推…就會導(dǎo)致鎖的永久失效。所以,只能自己釋放自己的鎖,可以給當(dāng)前線程取一個名字,代碼如下:

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

String lockkey = "lockkey";

String clientId = UUID.randomUUID().toString();

try{

Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,clientId ,10,TimeUnit.SECONDS);//jedis.setnx

//Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,"lockvalue");//jedis.setnx

//stringRedisTemplate.expire(lockkey,10,TimeUnit.SECONDS);

if(!result) {

return "";

}

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

}finally{

springRedisTemplate.delete(lockkey);

}

return "end";

}

}

永久失效的問題解決了,但是,如果第一個線程執(zhí)行15s,還是會存在多個線程擁有同一把鎖的現(xiàn)象。所以,需要續(xù)期超時時間,當(dāng)一個線程執(zhí)行5s后對超時時間進(jìn)行續(xù)期都10s,就可以解決了,續(xù)期設(shè)置可以借助redission工具。

Redission使用

Redission分布式鎖實(shí)現(xiàn)原理

pom.xml

org.redisson

redisson

3.6.5

Application.java啟動類

@bean

public Redission redission {

//此為單機(jī)模式

Config config = new Config();

config.useSingleServer().setAddress("redis://120.0.0.1:6379").setDatabase(0);

return (Redission)Redission.creat(config);

}

最終解決以上所有問題的代碼如下:

@RestController

public class IndexController {

@Autowired

private StringRedisTemplate stringRedisTemplate;

@Autowired

private Redissionredission;

@RequestMapping("/deduct_stock")

public Stirng deductStock() {

String lockkey = "lockkey";

//String clientId = UUID.randomUUID().toString();

RLock lock = redission.getLock();

try{

//Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,clientId ,10,TimeUnit.SECONDS);//jedis.setnx

//Boolean result = stringRedisTemplate.opsForValue.setIfAbsent(lockkey,"lockvalue");//jedis.setnx

//stringRedisTemplate.expire(lockkey,10,TimeUnit.SECONDS);

//加鎖:redission默認(rèn)超時時間為30s,每10s續(xù)期一次,也可以自己設(shè)置時間

lock.lock(60,TimeUnit.SECONDS);

int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));//jedis.get(key)

if (stock > 0) {

int realStock = stock - 1;

stringRedisTemplate.opsForValue.set("stock",realStock+"");//jedis.set(key,value)

System.out.println(扣減成功,剩余庫存:" + realStock + "");

} else {

System.out.println(扣減失敗,庫存不足!" );

}

}finally{

lock.unlock();

//springRedisTemplate.delete(lockkey);

}

return "end";

}

}

高并發(fā)分布式鎖的問題得到解決。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)站欄目:Redis實(shí)現(xiàn)高并發(fā)分布式鎖-創(chuàng)新互聯(lián)
地址分享:http://chinadenli.net/article0/ceppio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站Google、小程序開發(fā)定制網(wǎng)站、網(wǎng)站收錄、微信公眾號

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
亚洲中文字幕三区四区| 亚洲欧美国产精品一区二区| 欧美91精品国产自产| 激情五月天免费在线观看| 中日韩美一级特黄大片| 久久精品亚洲精品一区| 国产精品一区欧美二区| 女同伦理国产精品久久久| 丰满人妻熟妇乱又乱精品古代| 欧美成人免费视频午夜色| 国产小青蛙全集免费看| 精产国品一二三区麻豆| 一区中文字幕人妻少妇| 国产一级一片内射视频在线| 美女极度色诱视频在线观看| 在线视频免费看你懂的| 91人妻人人精品人人爽| 亚洲午夜福利不卡片在线 | 国产日本欧美韩国在线| 欧美丰满人妻少妇精品| 国产精品一区二区视频成人 | 加勒比系列一区二区在线观看| 男人和女人干逼的视频| 日韩人妻少妇一区二区| 色婷婷激情五月天丁香| 国产精品免费无遮挡不卡视频| 91老熟妇嗷嗷叫太91| 久久国产精品熟女一区二区三区 | 亚洲美女国产精品久久| 日韩中文字幕欧美亚洲| 成人三级视频在线观看不卡| 久久永久免费一区二区| 欧美国产日韩变态另类在线看| 国产99久久精品果冻传媒| 国产一区二区三区精品免费| 福利新区一区二区人口| 亚洲欧美一二区日韩高清在线| 国产又粗又猛又爽色噜噜| 在线懂色一区二区三区精品| 亚洲视频一级二级三级| 国产丝袜美女诱惑一区二区|