Zookeeper整合SpringBoot2Curator組件方法

這篇文章給大家分享的是Zookeeper整合SpringBoot2 Curator組件方法。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧。

創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站設(shè)計(jì)制作、網(wǎng)站制作和成都IDC機(jī)房托管的網(wǎng)絡(luò)公司,有著豐富的建站經(jīng)驗(yàn)和案例。

一、Zookeeper基礎(chǔ)簡(jiǎn)介

1、概念簡(jiǎn)介

Zookeeper是一個(gè)Apache開(kāi)源的分布式的應(yīng)用,為系統(tǒng)架構(gòu)提供協(xié)調(diào)服務(wù)。從設(shè)計(jì)模式角度來(lái)審視:該組件是一個(gè)基于觀察者模式設(shè)計(jì)的框架,負(fù)責(zé)存儲(chǔ)和管理數(shù)據(jù),接受觀察者的注冊(cè),一旦數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper就將負(fù)責(zé)通知已經(jīng)在Zookeeper上注冊(cè)的觀察者做出相應(yīng)的反應(yīng),從而實(shí)現(xiàn)集群中類似Master/Slave管理模式。ZooKeeper的目標(biāo)就是封裝好復(fù)雜易出錯(cuò)的關(guān)鍵服務(wù),將簡(jiǎn)單易用的接口和性能高效、功能穩(wěn)定的系統(tǒng)提供給用戶。

2、基本理論

  • 數(shù)據(jù)結(jié)構(gòu)

ZooKeeper記錄數(shù)據(jù)的結(jié)構(gòu)與Linux文件系統(tǒng)相似,整體可以看作一棵樹(shù),每個(gè)節(jié)點(diǎn)稱ZNode。每個(gè)Znode默認(rèn)能夠存儲(chǔ)1MB的數(shù)據(jù),每個(gè)ZNode都可以通過(guò)其路徑唯一標(biāo)識(shí)。

Zookeeper整合SpringBoot2 Curator組件方法

  • 節(jié)點(diǎn)類型

短暫(ephemeral):客戶端和服務(wù)器端斷開(kāi)連接后,創(chuàng)建的節(jié)點(diǎn)自動(dòng)刪除。
持久(persistent):客戶端和服務(wù)器端斷開(kāi)連接后,創(chuàng)建的節(jié)點(diǎn)持久化保存。

  • 集群服務(wù)

在Zookeeper集群服務(wù)是由一個(gè)領(lǐng)導(dǎo)者(leader),多個(gè)跟隨者(follower)組成的集群。領(lǐng)導(dǎo)者負(fù)責(zé)進(jìn)行投票的發(fā)起和決議,更新集群服務(wù)狀態(tài)。跟隨者用于接收客戶請(qǐng)求并向客戶端返回結(jié)果,在選舉Leader過(guò)程中參與投票。集群中只要有半數(shù)以上節(jié)點(diǎn)存活,Zookeeper集群就能正常服務(wù)。

  • 數(shù)據(jù)一致性

每個(gè)server保存一份相同的數(shù)據(jù)拷貝,客戶端無(wú)論請(qǐng)求到被集群中哪個(gè)server處理,得到的數(shù)據(jù)都是一致的。

3、應(yīng)用場(chǎng)景

  • 經(jīng)典應(yīng)用:Dubbo框架的服務(wù)注冊(cè)和發(fā)現(xiàn);
  • 分布式消息同步和協(xié)調(diào)機(jī)制;
  • 服務(wù)器節(jié)點(diǎn)動(dòng)態(tài)上下線;
  • 統(tǒng)一配置管理、負(fù)載均衡、集群管理;

二、安全管理操作

1、操作權(quán)限

ZooKeeper的節(jié)點(diǎn)有5種操作權(quán)限:CREATE(增)、READ(查)、WRITE(改)、DELETE(刪)、ADMIN(管理)等相關(guān)權(quán)限,這5種權(quán)限集合可以簡(jiǎn)寫為crwda,每個(gè)單詞的首字符拼接而成。

2、認(rèn)證方式:

  • world

默認(rèn)方式,開(kāi)放的權(quán)限,意解為全世界都能隨意訪問(wèn)。

  • auth

已經(jīng)授權(quán)且認(rèn)證通過(guò)的用戶才可以訪問(wèn)。

  • digest

用戶名:密碼方式認(rèn)證,實(shí)際業(yè)務(wù)開(kāi)發(fā)中最常用的方式。

  • IP白名單

授權(quán)指定的Ip地址,和指定的權(quán)限點(diǎn),控制訪問(wèn)。

3、Digest授權(quán)流程

  • 添加認(rèn)證用戶

addauth digest 用戶名:密碼

  • 設(shè)置權(quán)限

setAcl /path auth:用戶名:密碼:權(quán)限

  • 查看Acl設(shè)置

getAcl /path

  • 完整操作流程
-- 添加授權(quán)用戶
[zk: localhost:2181] addauth digest smile:123456
-- 創(chuàng)建節(jié)點(diǎn)
[zk: localhost:2181] create /cicada cicada
-- 節(jié)點(diǎn)授權(quán)
[zk: localhost:2181] setAcl /cicada auth:smile:123456:cdrwa
-- 查看授權(quán)[zk: localhost:2181] getAcl /cicada

三、整合 SpringBoot2 框架

1、核心依賴

Curator是Apache開(kāi)源的一個(gè)Zookeeper客戶端連接和操作的組件,Curator框架在Zookeeper原生API接口上進(jìn)行二次包裝。提供ZooKeeper各種應(yīng)用場(chǎng)景:比如:分布式鎖服務(wù)、集群領(lǐng)導(dǎo)選舉、共享計(jì)數(shù)器、緩存機(jī)制、分布式隊(duì)列等API封裝。

<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>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-client</artifactId>
    <version>2.12.0</version>
</dependency>

2、Zookeeper參數(shù)

zoo:
  keeper:
    #開(kāi)啟標(biāo)志
    enabled: true
    #服務(wù)器地址
    server: 127.0.0.1:2181
    #命名空間,被稱為ZNode
    namespace: cicada
    #權(quán)限控制,加密
    digest: smile:123456
    #會(huì)話超時(shí)時(shí)間
    sessionTimeoutMs: 3000
    #連接超時(shí)時(shí)間
    connectionTimeoutMs: 60000
     #最大重試次數(shù)
    maxRetries: 2
    #初始休眠時(shí)間
    baseSleepTimeMs: 1000

3、服務(wù)初始化配置

@Configuration
public class ZookeeperConfig {
    private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperConfig.class) ;
    @Resource
    private ZookeeperParam zookeeperParam ;
    private static CuratorFramework client = null ;
    /**
     * 初始化
     */
    @PostConstruct
    public void init (){
        //重試策略,初試時(shí)間1秒,重試10次
        RetryPolicy policy = new ExponentialBackoffRetry(
                zookeeperParam.getBaseSleepTimeMs(),
                zookeeperParam.getMaxRetries());
        //通過(guò)工廠創(chuàng)建Curator
        client = CuratorFrameworkFactory.builder()
                .connectString(zookeeperParam.getServer())
                .authorization("digest",zookeeperParam.getDigest().getBytes())
                .connectionTimeoutMs(zookeeperParam.getConnectionTimeoutMs())
                .sessionTimeoutMs(zookeeperParam.getSessionTimeoutMs())
                .retryPolicy(policy).build();
        //開(kāi)啟連接
        client.start();
        LOGGER.info("zookeeper 初始化完成...");
    }
    public static CuratorFramework getClient (){
        return client ;
    }
    public static void closeClient (){
        if (client != null){
            client.close();
        }
    }
}

4、封裝系列接口

public interface ZookeeperService {
    /**
     * 判斷節(jié)點(diǎn)是否存在
     */
    boolean isExistNode (final String path) ;
    /**
     * 創(chuàng)建節(jié)點(diǎn)
     */
    void createNode (CreateMode mode,String path ) ;
    /**
     * 設(shè)置節(jié)點(diǎn)數(shù)據(jù)
     */
    void setNodeData (String path, String nodeData) ;
    /**
     * 創(chuàng)建節(jié)點(diǎn)
     */
    void createNodeAndData (CreateMode mode, String path , String nodeData) ;
    /**
     * 獲取節(jié)點(diǎn)數(shù)據(jù)
     */
    String getNodeData (String path) ;
    /**
     * 獲取節(jié)點(diǎn)下數(shù)據(jù)
     */
    List<String> getNodeChild (String path) ;
    /**
     * 是否遞歸刪除節(jié)點(diǎn)
     */
    void deleteNode (String path,Boolean recursive) ;
    /**
     * 獲取讀寫鎖
     */
    InterProce***eadWriteLock getReadWriteLock (String path) ;
}

5、接口實(shí)現(xiàn)

@Service
public class ZookeeperServiceImpl implements ZookeeperService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ZookeeperServiceImpl.class);
    @Override
    public boolean isExistNode(String path) {
        CuratorFramework client = ZookeeperConfig.getClient();
        client.sync() ;
        try {
            Stat stat = client.checkExists().forPath(path);
            return client.checkExists().forPath(path) != null;
        } catch (Exception e) {
            LOGGER.error("isExistNode error...", e);
            e.printStackTrace();
        }
        return false;
    }
    @Override
    public void createNode(CreateMode mode, String path) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        try {
            // 遞歸創(chuàng)建所需父節(jié)點(diǎn)
            client.create().creatingParentsIfNeeded().withMode(mode).forPath(path);
        } catch (Exception e) {
            LOGGER.error("createNode error...", e);
            e.printStackTrace();
        }
    }
    @Override
    public void setNodeData(String path, String nodeData) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        try {
            // 設(shè)置節(jié)點(diǎn)數(shù)據(jù)
            client.setData().forPath(path, nodeData.getBytes("UTF-8"));
        } catch (Exception e) {
            LOGGER.error("setNodeData error...", e);
            e.printStackTrace();
        }
    }
    @Override
    public void createNodeAndData(CreateMode mode, String path, String nodeData) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        try {
            // 創(chuàng)建節(jié)點(diǎn),關(guān)聯(lián)數(shù)據(jù)
            client.create().creatingParentsIfNeeded().withMode(mode)
                  .forPath(path,nodeData.getBytes("UTF-8"));
        } catch (Exception e) {
            LOGGER.error("createNode error...", e);
            e.printStackTrace();
        }
    }
    @Override
    public String getNodeData(String path) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        try {
            // 數(shù)據(jù)讀取和轉(zhuǎn)換
            byte[] dataByte = client.getData().forPath(path) ;
            String data = new String(dataByte,"UTF-8") ;
            if (StringUtils.isNotEmpty(data)){
                return data ;
            }
        }catch (Exception e) {
            LOGGER.error("getNodeData error...", e);
            e.printStackTrace();
        }
        return null;
    }
    @Override
    public List<String> getNodeChild(String path) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        List<String> nodeChildDataList = new ArrayList<>();
        try {
            // 節(jié)點(diǎn)下數(shù)據(jù)集
            nodeChildDataList = client.getChildren().forPath(path);
        } catch (Exception e) {
            LOGGER.error("getNodeChild error...", e);
            e.printStackTrace();
        }
        return nodeChildDataList;
    }
    @Override
    public void deleteNode(String path, Boolean recursive) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        try {
            if(recursive) {
                // 遞歸刪除節(jié)點(diǎn)
                client.delete().guaranteed().deletingChildrenIfNeeded().forPath(path);
            } else {
                // 刪除單個(gè)節(jié)點(diǎn)
                client.delete().guaranteed().forPath(path);
            }
        } catch (Exception e) {
            LOGGER.error("deleteNode error...", e);
            e.printStackTrace();
        }
    }
    @Override
    public InterProce***eadWriteLock getReadWriteLock(String path) {
        CuratorFramework client = ZookeeperConfig.getClient() ;
        // 寫鎖互斥、讀寫互斥
        InterProce***eadWriteLock readWriteLock = new InterProce***eadWriteLock(client, path);
        return readWriteLock ;
    }
}

6、基于Swagger2接口

@Api("Zookeeper接口管理")@RestControllerpublic class ZookeeperApi {
    @Resource
    private ZookeeperService zookeeperService ;
    @ApiOperation(value="查詢節(jié)點(diǎn)數(shù)據(jù)")
    @GetMapping("/getNodeData")
    public String getNodeData (String path) {
        return zookeeperService.getNodeData(path) ;
    }
    @ApiOperation(value="判斷節(jié)點(diǎn)是否存在")
    @GetMapping("/isExistNode")
    public boolean isExistNode (final String path){
        return zookeeperService.isExistNode(path) ;
    }
    @ApiOperation(value="創(chuàng)建節(jié)點(diǎn)")
    @GetMapping("/createNode")
    public String createNode (CreateMode mode, String path ){
        zookeeperService.createNode(mode,path) ;
        return "success" ;
    }
    @ApiOperation(value="設(shè)置節(jié)點(diǎn)數(shù)據(jù)")
    @GetMapping("/setNodeData")
    public String setNodeData (String path, String nodeData) {
        zookeeperService.setNodeData(path,nodeData) ;
        return "success" ;
    }
    @ApiOperation(value="創(chuàng)建并設(shè)置節(jié)點(diǎn)數(shù)據(jù)")
    @GetMapping("/createNodeAndData")
    public String createNodeAndData (CreateMode mode, String path , String nodeData){
        zookeeperService.createNodeAndData(mode,path,nodeData) ;
        return "success" ;
    }
    @ApiOperation(value="遞歸獲取節(jié)點(diǎn)數(shù)據(jù)")
    @GetMapping("/getNodeChild")
    public List<String> getNodeChild (String path) {
        return zookeeperService.getNodeChild(path) ;
    }
    @ApiOperation(value="是否遞歸刪除節(jié)點(diǎn)")
    @GetMapping("/deleteNode")
    public String deleteNode (String path,Boolean recursive) {
        zookeeperService.deleteNode(path,recursive) ;
        return "success" ;
    }
}

看完上述內(nèi)容,你們掌握Z(yǔ)ookeeper整合SpringBoot2 Curator組件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!

分享題目:Zookeeper整合SpringBoot2Curator組件方法
本文來(lái)源:http://bm7419.com/article30/pcoeso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、品牌網(wǎng)站設(shè)計(jì)、網(wǎng)站排名、網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司