溫馨提示×

溫馨提示×

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

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

怎么用springboot+zookeeper實現(xiàn)分布式鎖

發(fā)布時間:2022-03-22 09:06:45 來源:億速云 閱讀:204 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容主要講解“怎么用springboot+zookeeper實現(xiàn)分布式鎖”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學(xué)習(xí)“怎么用springboot+zookeeper實現(xiàn)分布式鎖”吧!

InterProcessMutex內(nèi)部實現(xiàn)了zookeeper分布式鎖的機制,所以接下來我們嘗試使用這個工具來為我們的業(yè)務(wù)加上分布式鎖處理的功能

zookeeper分布式鎖的特點:1、分布式 2、公平鎖 3、可重入

依賴

<dependency>
   <groupId>org.apache.zookeeper</groupId>
   <artifactId>zookeeper</artifactId>
   <version>3.4.10</version>
</dependency>
<!-- zookeeper 客戶端 -->
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-framework</artifactId>
   <version>2.12.0</version>
</dependency>
<dependency>
   <groupId>org.apache.curator</groupId>
   <artifactId>curator-recipes</artifactId>
   <version>2.12.0</version>
</dependency>
<!-- lombok -->
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <version>1.18.16</version>
   <scope>provided</scope>
</dependency>

本地封裝

這個工具類主要封裝CuratorFramework這個client(連接Zookeeper)

@Slf4j
public class CuratorClientUtil {
    private String zookeeperServer;

    @Getter
    private CuratorFramework client;

    public CuratorClientUtil(String zookeeperServer) {
        this.zookeeperServer = zookeeperServer;
    }

  	// 創(chuàng)建CuratorFrameworkFactory并且啟動
    public void init() {
       // 重試策略,等待1s,最大重試3次
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000,3);
        this.client = CuratorFrameworkFactory.builder()
                .connectString(zookeeperServer)
                .sessionTimeoutMs(5000)
                .connectionTimeoutMs(5000)
                .retryPolicy(retryPolicy)
                .build();
        this.client.start();
    }

   // 容器關(guān)閉,CuratorFrameworkFactory關(guān)閉
    public void destroy() {
        try {
            if (Objects.nonNull(getClient())) {
                getClient().close();
            }
        } catch (Exception e) {
            log.info("CuratorFramework close error=>{}", e.getMessage());
        }
    }
}

配置

@Configuration
public class CuratorConfigration {
    @Value("${zookeeper.server}")
    private String zookeeperServer;
    // 注入時,指定initMethod和destroyMethod
    @Bean(initMethod = "init", destroyMethod = "destroy")
    public CuratorClientUtil curatorClientUtil() {
        CuratorClientUtil clientUtil = new CuratorClientUtil(zookeeperServer);
        return clientUtil;
    }
}

測試代碼

模擬不同客戶端的請求

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {
    // 注入client工具類
    @Autowired
    private CuratorClientUtil curatorClientUtil;
    // 在zookeeper的/rootLock節(jié)點下創(chuàng)建鎖對應(yīng)的臨時有序節(jié)點
    private String rootLock = "/rootLock";

    @GetMapping("/testLock")
    public Object testLock() throws Exception {
        // 獲取當(dāng)前線程的名字,方便觀察那些線程在獲取鎖
        String threadName = Thread.currentThread().getName();
        InterProcessMutex mutex = new InterProcessMutex(curatorClientUtil.getClient(), rootLock);
        try {
            log.info("{}---獲取鎖start", threadName);
            // 嘗試獲取鎖,最長等待3s,超時放棄獲取
            boolean lockFlag = mutex.acquire(3000, TimeUnit.SECONDS);
            // 獲取鎖成功,進(jìn)行業(yè)務(wù)處理
            if (lockFlag) {
                log.info("{}---獲取鎖success", threadName);
                // 模擬業(yè)務(wù)處理,時間為3s
                Thread.sleep(3000);
            } else {
                log.info("{}---獲取鎖fail", threadName);
            }
        } catch (Exception e) {
            log.info("{}---獲取鎖異常", threadName);
        } finally {
            // 業(yè)務(wù)處理完成,釋放鎖,喚醒比當(dāng)前線程創(chuàng)建的節(jié)點序號大(最靠近)的線程獲取鎖
            mutex.release();
            log.info("{}---鎖release", threadName);
        }
        return "線程:" + threadName + "執(zhí)行完成";
    }
}

JMeter測試

我們使用JMeter模擬100個客戶端同時并發(fā)的訪問 localhost:8081/test/testLock,相當(dāng)于100個客戶端爭搶分布式鎖,結(jié)果如圖右上角所示,100個請求花了5分6s,每個線程獲取到鎖后業(yè)務(wù)處理3s,100個線程理想時間為300s(Thread.sleep(3000)),所以運行時間符合。

怎么用springboot+zookeeper實現(xiàn)分布式鎖

怎么用springboot+zookeeper實現(xiàn)分布式鎖

zookeeper每個線程在/rooLock節(jié)點下創(chuàng)建的臨時有序節(jié)點如下圖,由于是臨時的,所以線程釋放鎖后這些節(jié)點也會刪除

怎么用springboot+zookeeper實現(xiàn)分布式鎖

100個線程程序日志打印

怎么用springboot+zookeeper實現(xiàn)分布式鎖

到此,相信大家對“怎么用springboot+zookeeper實現(xiàn)分布式鎖”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

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

AI