日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Redis實(shí)現(xiàn)分布式鎖具體方法

在很多互聯(lián)網(wǎng)產(chǎn)品應(yīng)用中,有些場(chǎng)景需要加鎖處理,比如:秒殺,全局遞增ID,樓層生成等等。大部分的解決方案是基于DB實(shí)現(xiàn)的,Redis為單進(jìn)程單線程模式,采用隊(duì)列模式將并發(fā)訪問(wèn)變成串行訪問(wèn),且多客戶端對(duì)Redis的連接并不存在競(jìng)爭(zhēng)關(guān)系。其次Redis提供一些命令SETNX,GETSET,可以方便實(shí)現(xiàn)分布式鎖機(jī)制。

成都創(chuàng)新互聯(lián)公司專(zhuān)注于企業(yè)成都營(yíng)銷(xiāo)網(wǎng)站建設(shè)、網(wǎng)站重做改版、射陽(yáng)網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、H5建站、商城建設(shè)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁(yè)設(shè)計(jì)等建站業(yè)務(wù),價(jià)格優(yōu)惠性價(jià)比高,為射陽(yáng)等各大城市提供網(wǎng)站開(kāi)發(fā)制作服務(wù)。

踩坑1. 數(shù)據(jù)庫(kù)事務(wù)超時(shí)

不要感覺(jué)奇怪,分布式鎖怎么會(huì)導(dǎo)致數(shù)據(jù)庫(kù)事務(wù)超時(shí)呢? 我的代碼大概是這樣的:

偽代碼
@Transaction(readOnly=false)
void update(){
   do{
       redis=JedisUtil.getJedis();
       flag = getLock(key,redis);
       if(flag){
           update();
       }
   }while(true)
}

當(dāng)你的key長(zhǎng)時(shí)間獲取不到鎖,并且數(shù)據(jù)庫(kù)事務(wù)都有超時(shí)時(shí)間的限制,那么就會(huì)出現(xiàn)數(shù)據(jù)庫(kù)事務(wù)超時(shí)問(wèn)題; 解決方案

數(shù)據(jù)庫(kù)事務(wù)改為手動(dòng)提交事務(wù);

踩坑2. redis key過(guò)期,而業(yè)務(wù)沒(méi)有執(zhí)行完

我的key的過(guò)期時(shí)間設(shè)置的是30s,如果30秒業(yè)務(wù)還沒(méi)有執(zhí)行完畢,鎖就會(huì)自動(dòng)釋放,鎖釋放之后,其它線程又會(huì)去占用鎖,同樣會(huì)導(dǎo)致問(wèn)題的發(fā)生; 解決方案

最簡(jiǎn)單的解決方案就是使用redisson; 如果非要用redis來(lái)解決的話,只能使用定時(shí)器去檢測(cè)key,如果說(shuō)key還有2秒就快過(guò)期了,那么再為key重新設(shè)置30秒的過(guò)期時(shí)間;

踩坑3. redis連接池爆滿

分布式鎖剛加上之后,生產(chǎn)出現(xiàn)一個(gè)問(wèn)題,就是:redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool 解決辦法 開(kāi)始查代碼,發(fā)現(xiàn)是開(kāi)發(fā)人員沒(méi)有對(duì)連接進(jìn)行釋放;

修復(fù)bug之后,又在線上跑了一段時(shí)間,又出現(xiàn)了redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool 解決辦法

void update(){
   do{
       redis=JedisUtil.getJedis();
       flag = getLock(key,redis);
       if(flag){
           update();
       }else{
           // 釋放當(dāng)前redis連接
           // 由于我們的業(yè)務(wù)場(chǎng)景屬于比較耗時(shí)的業(yè)務(wù)型,所以在這里休眠1000毫秒
           redis.close();
           sleep(1000);
       }
   }while(true)
}

1.當(dāng)前請(qǐng)求獲取鎖,如果獲取不到,則釋放當(dāng)前連接,并休眠一會(huì); 2.合理配置redis連接池大小,主要參考具體業(yè)務(wù)場(chǎng)景的并發(fā)量來(lái)設(shè)置;

踩坑4. 解鈴還須系鈴人

回顧一下加鎖的參數(shù):

set(key, vlue,"NX","PX", 30000);

其中:value,我使用它來(lái)表示加鎖人,必須是一個(gè)唯一的標(biāo)識(shí)

比如: A線程 key=test value=01 B線程 key=test value=02

如果A線程執(zhí)行業(yè)務(wù)耗時(shí)超過(guò)了鎖的持有時(shí)間,鎖會(huì)自動(dòng)釋放;鎖自動(dòng)釋放之后,線程B又加鎖成功,但是,此時(shí)A線程執(zhí)行完業(yè)務(wù)邏輯之后,去釋放鎖,但A線程的鎖已經(jīng)自動(dòng)釋放了,如果沒(méi)有value來(lái)標(biāo)識(shí)的話,它可能就會(huì)去釋放B線程的鎖;

踩坑5. redis集群實(shí)現(xiàn)分布式鎖

這種情況我沒(méi)有遇到,因?yàn)楣镜膔edis集群做了改進(jìn);

先說(shuō)一下這種問(wèn)題產(chǎn)生的原因: 如果master節(jié)點(diǎn)由于某原因發(fā)生了主從切換,那么就會(huì)出現(xiàn)鎖丟失的情況;

在master節(jié)點(diǎn)上拿到了鎖;
但是這個(gè)加鎖的key還沒(méi)有同步到slave節(jié)點(diǎn);
master故障,發(fā)生故障轉(zhuǎn)移,slave節(jié)點(diǎn)升級(jí)為master節(jié)點(diǎn);
故導(dǎo)致鎖丟失;

解決辦法

需要通過(guò)使用redlock算法; 或使用redisson,它有對(duì)redlock算法做封裝;


本文名稱(chēng):Redis實(shí)現(xiàn)分布式鎖具體方法
文章分享:http://www.dlmjj.cn/article/dpgcihd.html