日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

分布式锁 基于Redis

發布時間:2023/12/18 数据库 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式锁 基于Redis 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

分布式鎖的實現(基于Redis)

參考:http://www.jb51.net/article/75439.htm?

? ? ? ? http://www.linuxidc.com/Linux/2015-01/111827.htm?

? ? ? ? http://www.tuicool.com/articles/6juqmm7?

?方式一: 基于第三方類庫 redssion?

1.安裝redis

安裝redssion的鎖服務隊redis的版本有要求,要求必須高于2.6版本。關于redis的安裝,請參考redis安裝。

2.redssion庫

redssion的庫添加的pom文件中去。

<dependency>
? ?<groupId>org.redisson</groupId>
? ?<artifactId>redisson</artifactId>
? ?<version>2.1.0</version>
</dependency>

3.測試例子

Config config = new Config();
? ? ? ? config.useSingleServer().setAddress("ipaddress:6379");
? ? ? ? Redisson redisson = Redisson.create(config);
?? ? ? ?
? ? ? ? for(int i=0;i<5;i++){
? ? ? ? RLock lock = redisson.getLock("testLock");
? ? ? ? lock.lock(10, TimeUnit.SECONDS);//10s超時
? ? ? ? logger.info("the lock client id is client{}",i);
? ? ? ? Thread.sleep(1000);
? ? ? ? logger.info("client{} unlock",i);
? ? ? ? lock.unlock();
? ? ? ? }

4.參考

redisson

?

?

方式二: 自定義代碼實現?



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;

/**
* redis實現的分布式鎖
*/
public final class Lock {

private static final String LOCK = "redis:lock:%s";
private static final int EXPIRE = 20 * 60;//20分鐘
private static final Logger logger = LoggerFactory.getLogger(Lock.class);

private Lock() {
}


public static Lock getLock() {
return new Lock();
}

/**
* 獲得鎖,超時退出
* @param id
* @param timeout 超時時間(ms)
* @return
*/
public boolean lock(String id, int timeout) {

//這里的Jedis實際上是個代理。代理類JedisCallback,JedisFactoryBean
Jedis jedisProxy = JedisProxy.create();

long lock = 0;

long start = System.currentTimeMillis();

while (lock != 1) {
long now = System.currentTimeMillis();
//判斷超時
if (timeout > 0 && now > start + timeout) {
return false;
}
long timestamp = now + EXPIRE * 1000 + 1;

try {
String key = String.format(LOCK, id);
lock = jedisProxy.setnx(key, String.valueOf(timestamp));
if (lock == 1) {
logger.info("設置redis鎖key成功,lock key=" + key);
jedisProxy.expire(key, EXPIRE);
logger.info("設置redis鎖key過期時間成功,lock key=" + key);
} else {
String s = jedisProxy.get(key);
Long lastLockTime = Long.parseLong(s);

//一個項目部署多個服務,鎖可能已經被相同定時任務的其他進程獲得,則直接返回false
if (jedisProxy.ttl(key)!=-1&&lastLockTime > System.currentTimeMillis()){
logger.info("redis鎖已經被其他服務獲得,lock key=" + key);
return false;
}
/**
* 如果上次鎖定的時間已經過期,則清除key鎖,以便定時任務能夠啟動
* 造成未能釋放的原因主要是jedis.expire(key, EXPIRE);失敗
* 或者是獲取鎖之后,由于程序錯誤或網絡錯誤,unlock未被成功調用
*/
if (jedisProxy.ttl(key)==-1||lastLockTime < System.currentTimeMillis()) {
jedisProxy.del(key);
continue;
}
// this.wait(100);
Thread.sleep(100);
}
} catch (Exception e) {
logger.error("從redis獲取定時任務鎖錯誤,key="+String.format(LOCK, id), e);
return false;
}
}
return true;
}

/**
* 釋放鎖
* @param id
*/
public void unLock(String id) {

//這里的Jedis實際上是個代理。代理類JedisCallback,JedisFactoryBean
Jedis jedisProxy = JedisProxy.create();
String key = String.format(LOCK, id);
jedisProxy.del(key);
}
}

JedisProxy類

/**
* Jedis代理
*/
@Component
public class JedisProxy implements ApplicationContextAware {

private static volatile ApplicationContext ac;

/**
* 創建Jedis 代理
*
* @return
*/
public static Jedis create() {
return ac.getBean(Jedis.class);
}

@Override
public void setApplicationContext(ApplicationContext applicationContext) {
if (ac != null) {
return;
}
synchronized (JedisProxy.class) {
if (ac != null) {
return;
}
ac = applicationContext;
}
}
}

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/wangdaijun/p/5301858.html

總結

以上是生活随笔為你收集整理的分布式锁 基于Redis的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。