redis、zookeeper分布式鎖的實現

來源:互聯網
上載者:User
1.分布式鎖

分布式鎖一般用在分布式系統或者多個應用中,用來控制同一任務是否執行或者任務的執行順序。在項目中,部署了多個tomcat應用,在執行定時任務時就會遇到同一任務可能執行多次的情況,我們可以藉助分布式鎖,保證在同一時間只有一個tomcat應用執行了定時任務。 2.分布式鎖的實現方式 使用redis的setnx()和expire() 使用redis的getset() 使用zookeeper的建立節點node 使用zookeeper的建立臨時序列節點 3.使用redis的setnx()和expire()來實現分布式鎖

setnx(key,value) 如果key不存在,設定為當前key的值為value;如果key存在,直接返回。expire()來設定逾時時間

定義註解類:

@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface Lockable{    // redis緩衝key    String key();    // redis緩衝key中的資料    String value() default "";    // 到期時間(秒),預設為一分鐘    long expire() default 60;}

定時任務增加註解@Lockable:

 @Lockable(key = "DistributedLock:dealExpireRecords") public void dealExpireRecords() { }

定義一個aop切面LockAspect,使用@Around處理所有註解為@Lockable的方法,通過連接點確認此註解是用在方法上,通過方法擷取註解資訊,使用setIfAbsent來判斷是否擷取分布式鎖,如果沒有擷取分布式鎖,直接返回;如果擷取到分布式鎖,通過expire設定到期時間,並調用指定方法。

@Component@Slf4j@Aspectpublic class LockAspect {    @Autowired    private RedisTemplate redisTemplate;    @Around("@annotation(com.records.aop.Lockable)")    public Object distributeLock(ProceedingJoinPoint pjp) {        Object resultObject = null;        //確認此註解是用在方法上        Signature signature = pjp.getSignature();        if (!(signature instanceof MethodSignature)) {            log.error("Lockable is method annotation!");            return resultObject;        }        MethodSignature methodSignature = (MethodSignature) signature;        Method targetMethod = methodSignature.getMethod();        //擷取註解資訊        Lockable lockable = targetMethod.getAnnotation(Lockable.class);        String key = lockable.key();        String value = lockable.value();        long expire = lockable.expire();        // 分布式鎖,如果沒有此key,設定此值並返回true;如果有此key,則返回false        boolean result = redisTemplate.boundValueOps(key).setIfAbsent(value);        if (!result) {            //其他程式已經擷取分布式鎖            return resultObject;        }        //設定到期時間,預設一分鐘        redisTemplate.boundValueOps(key).expire(expire, TimeUnit.SECONDS);        try {            resultObject = pjp.proceed(); //調用對應方法執行        } catch (Throwable throwable) {            throwable.printStackTrace();        }        return resultObject;    }}
4.使用redis的getset()來實現分布式鎖

此方法使redisTemplate.boundValueOps(key).getAndSet(value)的方法,如果返回空,表示擷取了分布式鎖;如果返回不為空白,表示分布式鎖已經被其他程式佔用 5.使用zookeeper的建立節點node

使用zookeeper建立節點node,如果建立節點成功,表示擷取了此分布式鎖;如果建立節點失敗,表示此分布式鎖已經被其他程式佔用(多個程式同時建立一個節點node,只有一個能夠建立成功) 6.使用zookeeper的建立臨時序列節點

使用zookeeper建立臨時序列節點來實現分布式鎖,適用於順序執行的程式,大體思路就是建立臨時序列節點,找出最小的序列節點,擷取分布式鎖,程式執行完成之後此序列節點消失,通過watch來監控節點的變化,從剩下的節點的找到最小的序列節點,擷取分布式鎖,執行相應處理,依次類推......



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.