溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot整合curator如何實現(xiàn)分布式鎖

發(fā)布時間:2020-10-22 16:27:08 來源:億速云 閱讀:542 作者:小新 欄目:開發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)springboot整合curator如何實現(xiàn)分布式鎖的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。

理論篇:

Curator是Netflix開源的一套ZooKeeper客戶端框架. Netflix在使用ZooKeeper的過程中發(fā)現(xiàn)ZooKeeper自帶的客戶端太底層, 應用方在使用的時候需要自己處理很多事情, 于是在它的基礎(chǔ)上包裝了一下, 提供了一套更好用的客戶端框架. Netflix在用ZooKeeper的過程中遇到的問題, 我們也遇到了, 所以開始研究一下, 首先從他在github上的源碼, wiki文檔以及Netflix的技術(shù)blog入手. 

看完官方的文檔之后, 發(fā)現(xiàn)Curator主要解決了三類問題: 

封裝ZooKeeper client與ZooKeeper server之間的連接處理;

提供了一套Fluent風格的操作API;

提供ZooKeeper各種應用場景(recipe, 比如共享鎖服務, 集群領(lǐng)導選舉機制)的抽象封裝.

Curator列舉的ZooKeeper使用過程中的幾個問題 

初始化連接的問題: 在client與server之間握手建立連接的過程中, 如果握手失敗, 執(zhí)行所有的同步方法(比如create, getData等)將拋出異常 

自動恢復(failover)的問題: 當client與一臺server的連接丟失,并試圖去連接另外一臺server時, client將回到初始連接模式 

session過期的問題: 在極端情況下, 出現(xiàn)ZooKeeper session過期, 客戶端需要自己去監(jiān)聽該狀態(tài)并重新創(chuàng)建ZooKeeper實例 . 

對可恢復異常的處理:當在server端創(chuàng)建一個有序ZNode, 而在將節(jié)點名返回給客戶端時崩潰, 此時client端拋出可恢復的異常, 用戶需要自己捕獲這些異常并進行重試 

使用場景的問題:Zookeeper提供了一些標準的使用場景支持, 但是ZooKeeper對這些功能的使用說明文檔很少, 而且很容易用錯. 在一些極端場景下如何處理, zk并沒有給出詳細的文檔說明. 比如共享鎖服務, 當服務器端創(chuàng)建臨時順序節(jié)點成功, 但是在客戶端接收到節(jié)點名之前掛掉了, 如果不能很好的處理這種情況, 將導致死鎖. 

Curator主要從以下幾個方面降低了zk使用的復雜性: 

重試機制:提供可插拔的重試機制, 它將給捕獲所有可恢復的異常配置一個重試策略, 并且內(nèi)部也提供了幾種標準的重試策略(比如指數(shù)補償). 

連接狀態(tài)監(jiān)控: Curator初始化之后會一直的對zk連接進行監(jiān)聽, 一旦發(fā)現(xiàn)連接狀態(tài)發(fā)生變化, 將作出相應的處理. 

zk客戶端實例管理:Curator對zk客戶端到server集群連接進行管理. 并在需要的情況, 重建zk實例, 保證與zk集群的可靠連接 

各種使用場景支持:Curator實現(xiàn)zk支持的大部分使用場景支持(甚至包括zk自身不支持的場景), 這些實現(xiàn)都遵循了zk的最佳實踐, 并考慮了各種極端情況. 

Curator通過以上的處理, 讓用戶專注于自身的業(yè)務本身, 而無需花費更多的精力在zk本身. 

 實操篇:

CuratorFrameworkFactory類提供了兩個方法, 一個工廠方法newClient, 一個構(gòu)建方法build. 使用工廠方法newClient可以創(chuàng)建一個默認的實例, 而build構(gòu)建方法可以對實例進行定制. 當CuratorFramework實例構(gòu)建完成, 緊接著調(diào)用start()方法, 在應用結(jié)束的時候, 需要調(diào)用close()方法.  CuratorFramework是線程安全的. 在一個應用中可以共享同一個zk集群的CuratorFramework. 

核心對象CuratorFramework的創(chuàng)建如下:

RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);

CuratorFramework client = CuratorFrameworkFactory.builder()

                                      .connectString("")

                                      .sessionTimeoutMs(5000)

                                      .connectionTimeoutMs(5000)

                                      .retryPolicy(retryPolicy)

                                      .build();

client.start();

需要使用分布式鎖的地方,代碼如下:

String lockOn= "test";

InterProcessMutex mutex = new InterProcessMutex(curatorFramework,lockOn);

boolean locked =mutex.acquire(0,TimeUnit.SECONDS);


//finally部分  

mutex.release();

分布式鎖常用于定時任務,使用自定義注解,使用spring aspect around, 在真正的代碼執(zhí)行之前嘗試獲取鎖,獲取不到直接退出,獲取到鎖的,執(zhí)行具體業(yè)務,代碼如下:

@Aspect

public class DistributedLockAspect{

    @Pointcut("@annotation(com.**.**.DistributedLock")

    public void methodAspect(){};  

    

    @Around("methodAspect()")

    public Object execute(ProceedingJoinPoint joinPoint) throws Exception{

    

    String lockPath = "/opt/zookeeper/lock";

    InterProcessMutex mutex = new InterProcessMutex(cruatorFramework,lockPath);

    try{

       boolean locked = mutex.acquire(0,TimeUnit.SECONDS);

       if(!locked){

          return null;

      }else{

        return joinPoint.proceed();

      }

   }catch(Exception e){

       e.printStackTrace();

   }finally{

       mutex.release();

   }

 }

自定義注解:


1 @Target(ElementType.METHOD)

2 @Retention(RetentionPolicy.RUNTIME)

3 public @interface DistributedLock{

4    String lockPath();  

5 }

 

注意事項:


   1.  CuratorFramework對象建議在應用中做單例處理,在具體使用處 注入使用, 并在應用結(jié)束前銷毀,代碼如下:

@Configration

public class CuratorConfigration{

    @Bean    

    public CuratorFramework initCuratorFramework(){

        //忽略 

       // 參照前面 CuratorFramework 對象創(chuàng)建部分

    }    

}

2. 在aspect部分將curatorFramework對象進行關(guān)閉

@PreDestroy

public void destroy(){

   CloseableUtils.closeQuietly(curatorFramework);

}

感謝各位的閱讀!關(guān)于springboot整合curator如何實現(xiàn)分布式鎖就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到吧

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI