這篇文章給大家分享的是Zookeeper整合SpringBoot2 Curator組件方法。小編覺得挺實(shí)用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站設(shè)計制作、網(wǎng)站制作和成都IDC機(jī)房托管的網(wǎng)絡(luò)公司,有著豐富的建站經(jīng)驗(yàn)和案例。
一、Zookeeper基礎(chǔ)簡介
Zookeeper是一個Apache開源的分布式的應(yīng)用,為系統(tǒng)架構(gòu)提供協(xié)調(diào)服務(wù)。從設(shè)計模式角度來審視:該組件是一個基于觀察者模式設(shè)計的框架,負(fù)責(zé)存儲和管理數(shù)據(jù),接受觀察者的注冊,一旦數(shù)據(jù)的狀態(tài)發(fā)生變化,Zookeeper就將負(fù)責(zé)通知已經(jīng)在Zookeeper上注冊的觀察者做出相應(yīng)的反應(yīng),從而實(shí)現(xiàn)集群中類似Master/Slave管理模式。ZooKeeper的目標(biāo)就是封裝好復(fù)雜易出錯的關(guān)鍵服務(wù),將簡單易用的接口和性能高效、功能穩(wěn)定的系統(tǒng)提供給用戶。
ZooKeeper記錄數(shù)據(jù)的結(jié)構(gòu)與Linux文件系統(tǒng)相似,整體可以看作一棵樹,每個節(jié)點(diǎn)稱ZNode。每個Znode默認(rèn)能夠存儲1MB的數(shù)據(jù),每個ZNode都可以通過其路徑唯一標(biāo)識。
短暫(ephemeral):客戶端和服務(wù)器端斷開連接后,創(chuàng)建的節(jié)點(diǎn)自動刪除。
持久(persistent):客戶端和服務(wù)器端斷開連接后,創(chuàng)建的節(jié)點(diǎn)持久化保存。
在Zookeeper集群服務(wù)是由一個領(lǐng)導(dǎo)者(leader),多個跟隨者(follower)組成的集群。領(lǐng)導(dǎo)者負(fù)責(zé)進(jìn)行投票的發(fā)起和決議,更新集群服務(wù)狀態(tài)。跟隨者用于接收客戶請求并向客戶端返回結(jié)果,在選舉Leader過程中參與投票。集群中只要有半數(shù)以上節(jié)點(diǎn)存活,Zookeeper集群就能正常服務(wù)。
每個server保存一份相同的數(shù)據(jù)拷貝,客戶端無論請求到被集群中哪個server處理,得到的數(shù)據(jù)都是一致的。
ZooKeeper的節(jié)點(diǎn)有5種操作權(quán)限:CREATE(增)、READ(查)、WRITE(改)、DELETE(刪)、ADMIN(管理)等相關(guān)權(quán)限,這5種權(quán)限集合可以簡寫為crwda,每個單詞的首字符拼接而成。
默認(rèn)方式,開放的權(quán)限,意解為全世界都能隨意訪問。
已經(jīng)授權(quán)且認(rèn)證通過的用戶才可以訪問。
用戶名:密碼方式認(rèn)證,實(shí)際業(yè)務(wù)開發(fā)中最常用的方式。
授權(quán)指定的Ip地址,和指定的權(quán)限點(diǎn),控制訪問。
addauth digest 用戶名:密碼
setAcl /path auth:用戶名:密碼:權(quán)限
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
Curator是Apache開源的一個Zookeeper客戶端連接和操作的組件,Curator框架在Zookeeper原生API接口上進(jìn)行二次包裝。提供ZooKeeper各種應(yīng)用場景:比如:分布式鎖服務(wù)、集群領(lǐng)導(dǎo)選舉、共享計數(shù)器、緩存機(jī)制、分布式隊列等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>
zoo: keeper: #開啟標(biāo)志 enabled: true #服務(wù)器地址 server: 127.0.0.1:2181 #命名空間,被稱為ZNode namespace: cicada #權(quán)限控制,加密 digest: smile:123456 #會話超時時間 sessionTimeoutMs: 3000 #連接超時時間 connectionTimeoutMs: 60000 #最大重試次數(shù) maxRetries: 2 #初始休眠時間 baseSleepTimeMs: 1000
@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 (){ //重試策略,初試時間1秒,重試10次 RetryPolicy policy = new ExponentialBackoffRetry( zookeeperParam.getBaseSleepTimeMs(), zookeeperParam.getMaxRetries()); //通過工廠創(chuàng)建Curator client = CuratorFrameworkFactory.builder() .connectString(zookeeperParam.getServer()) .authorization("digest",zookeeperParam.getDigest().getBytes()) .connectionTimeoutMs(zookeeperParam.getConnectionTimeoutMs()) .sessionTimeoutMs(zookeeperParam.getSessionTimeoutMs()) .retryPolicy(policy).build(); //開啟連接 client.start(); LOGGER.info("zookeeper 初始化完成..."); } public static CuratorFramework getClient (){ return client ; } public static void closeClient (){ if (client != null){ client.close(); } } }
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) ; }
@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 { // 刪除單個節(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 ; } }
@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)容,你們掌握Zookeeper整合SpringBoot2 Curator組件的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!
分享題目:Zookeeper整合SpringBoot2Curator組件方法
本文來源:http://www.rwnh.cn/article30/pcoeso.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航、品牌網(wǎng)站設(shè)計、網(wǎng)站排名、網(wǎng)站建設(shè)、軟件開發(fā)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)