7 redis分散式鎖+redisson
阿新 • • 發佈:2018-12-10
redis分散式鎖解決叢集環境下的定時任務
需要特殊考慮的是,異常關機碟機而產生的死鎖(程式碼剛剛走到set的時候) package com.mmall.common.schedule; import lombok.extern.slf4j.Slf4j; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import com.mmall.util.RedisShardedPoolUtil; @Component public class ScheduleTest { // @Scheduled(cron="0/5 * * * * ?") // public void schbobo(){ // Date date = new Date(); // SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // String dateStr = sim.format(date); // log.info("這是spring定時器1,每五秒執行一次,當前時間:" + dateStr); // System.out.println("這是spring定時器1,每五秒執行一次,當前時間:" + dateStr); // // } //reids分散式鎖的定時任務 @Scheduled(cron="0/5 * * * * ?") public void schbobo_1(){ String key="bobodekey"; Long setresult=RedisShardedPoolUtil.setNx(key,String.valueOf(System.currentTimeMillis()+50000)); if(setresult!=null&&setresult.intValue()==1){ System.out.println("我獲得到了鎖哦來自schbobo_1"); //獲取鎖成功,並且進行業務操作 add(key); System.out.println("結束了生命週期"); }else{//為了防止異常碟機而產生的死鎖 String oldKey=RedisShardedPoolUtil.get(key); if(oldKey!=null&&System.currentTimeMillis()>Long.parseLong(oldKey)){//已經超過vlued的有效期 String getsetVlue=RedisShardedPoolUtil.getset(key, String.valueOf(System.currentTimeMillis()+50000)); if(getsetVlue==null||getsetVlue.equals(oldKey)){ add(key); } } System.out.println("沒有獲取到鎖,我是schbobo_1裡面的else"); } } /** * 進行業務操作並且防止死鎖的發生 * @param key */ private void add(String key){ //設定50秒的有效期 RedisShardedPoolUtil.exPire(key,50); System.out.println("我做了好多事情唉,都做完了"); RedisShardedPoolUtil.del(key); } }
-
redisson
- 官網redisson.org
匯入架包: <!-- redisson需要的架包 --> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-avro</artifactId> <version>2.9.0</version> </dependency> 編寫工具類獲取redisson例項 package com.mmall.util; import javax.annotation.PostConstruct; import lombok.extern.slf4j.Slf4j; import org.redisson.Redisson; import org.redisson.config.Config; import org.springframework.stereotype.Component; @Component @Slf4j public class RedissonManager { private Config config=new Config(); private Redisson redisson=null; public Redisson getRedisson() { return redisson; } @PostConstruct private void init() { try { config.useSingleServer().setAddress("111.231.114.12:6379").setPassword("bobo"); redisson=(Redisson)redisson.create(config); log.info("獲取redisson例項成功"); } catch (Exception e) { log.info("獲取redisson例項失敗,error{}",e); } } } 重新設計分散式鎖,使用redisson的可重入鎖解決分散式的定時任務 /** * 使用redisson操作鎖 */ @Scheduled(cron="0/5 * * * * ?") public void shcbobo_2(){ String key="bobodekeyzuihouyige"; RLock lock= RedissonManager.getRedisson().getLock(key); Boolean getlock=false; try { //第一個引數是等待多少秒,一般設定成0,因為無法估算業務執行完的一個時間,如果設定短了,就會被其他的進行獲取到鎖,所以設定成0,不進行等待 //第二個引數是有效期50秒,超過50秒就會失效 //第三個引數是單位是秒 if(getlock=lock.tryLock(0,50,TimeUnit.SECONDS)){ System.out.println("執行了業務"); }else{ System.out.println("沒有獲取到鎖"); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ if(!getlock){ return; } //刪除鎖 lock.unlock(); System.out.println("刪除了鎖"); } } redis,主從配置,讀寫分離,哨兵模式 redis主從配置,配置master 只能為寫,slave只能為讀,在客戶端對poolconnect請求時候,,會將讀請求轉到slave上面,寫請求轉到master上面,同時,master和slave有同步功能,這就實現了(資料層)讀寫分離對上層(邏輯層)透明的正常邏輯。無需再通過中介軟體或者程式碼進行讀寫分析實現。 https://blog.csdn.net/zmx729618/article/details/76671746