這篇文章給大家分享的是Zookeeper整合SpringBoot2 Curator組件方法。小編覺得挺實用的,因此分享給大家做個參考。一起跟隨小編過來看看吧。
創新互聯公司是一家專注于網站設計制作、網站制作和成都IDC機房托管的網絡公司,有著豐富的建站經驗和案例。
一、Zookeeper基礎簡介
Zookeeper是一個Apache開源的分布式的應用,為系統架構提供協調服務。從設計模式角度來審視:該組件是一個基于觀察者模式設計的框架,負責存儲和管理數據,接受觀察者的注冊,一旦數據的狀態發生變化,Zookeeper就將負責通知已經在Zookeeper上注冊的觀察者做出相應的反應,從而實現集群中類似Master/Slave管理模式。ZooKeeper的目標就是封裝好復雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。
ZooKeeper記錄數據的結構與Linux文件系統相似,整體可以看作一棵樹,每個節點稱ZNode。每個Znode默認能夠存儲1MB的數據,每個ZNode都可以通過其路徑唯一標識。
短暫(ephemeral):客戶端和服務器端斷開連接后,創建的節點自動刪除。
持久(persistent):客戶端和服務器端斷開連接后,創建的節點持久化保存。
在Zookeeper集群服務是由一個領導者(leader),多個跟隨者(follower)組成的集群。領導者負責進行投票的發起和決議,更新集群服務狀態。跟隨者用于接收客戶請求并向客戶端返回結果,在選舉Leader過程中參與投票。集群中只要有半數以上節點存活,Zookeeper集群就能正常服務。
每個server保存一份相同的數據拷貝,客戶端無論請求到被集群中哪個server處理,得到的數據都是一致的。
ZooKeeper的節點有5種操作權限:CREATE(增)、READ(查)、WRITE(改)、DELETE(刪)、ADMIN(管理)等相關權限,這5種權限集合可以簡寫為crwda,每個單詞的首字符拼接而成。
默認方式,開放的權限,意解為全世界都能隨意訪問。
已經授權且認證通過的用戶才可以訪問。
用戶名:密碼方式認證,實際業務開發中最常用的方式。
授權指定的Ip地址,和指定的權限點,控制訪問。
addauth digest 用戶名:密碼
setAcl /path auth:用戶名:密碼:權限
getAcl /path
-- 添加授權用戶 [zk: localhost:2181] addauth digest smile:123456 -- 創建節點 [zk: localhost:2181] create /cicada cicada -- 節點授權 [zk: localhost:2181] setAcl /cicada auth:smile:123456:cdrwa -- 查看授權[zk: localhost:2181] getAcl /cicada
Curator是Apache開源的一個Zookeeper客戶端連接和操作的組件,Curator框架在Zookeeper原生API接口上進行二次包裝。提供ZooKeeper各種應用場景:比如:分布式鎖服務、集群領導選舉、共享計數器、緩存機制、分布式隊列等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: #開啟標志 enabled: true #服務器地址 server: 127.0.0.1:2181 #命名空間,被稱為ZNode namespace: cicada #權限控制,加密 digest: smile:123456 #會話超時時間 sessionTimeoutMs: 3000 #連接超時時間 connectionTimeoutMs: 60000 #最大重試次數 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()); //通過工廠創建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 { /** * 判斷節點是否存在 */ boolean isExistNode (final String path) ; /** * 創建節點 */ void createNode (CreateMode mode,String path ) ; /** * 設置節點數據 */ void setNodeData (String path, String nodeData) ; /** * 創建節點 */ void createNodeAndData (CreateMode mode, String path , String nodeData) ; /** * 獲取節點數據 */ String getNodeData (String path) ; /** * 獲取節點下數據 */ List<String> getNodeChild (String path) ; /** * 是否遞歸刪除節點 */ 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 { // 遞歸創建所需父節點 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 { // 設置節點數據 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 { // 創建節點,關聯數據 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 { // 數據讀取和轉換 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 { // 節點下數據集 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) { // 遞歸刪除節點 client.delete().guaranteed().deletingChildrenIfNeeded().forPath(path); } else { // 刪除單個節點 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="查詢節點數據") @GetMapping("/getNodeData") public String getNodeData (String path) { return zookeeperService.getNodeData(path) ; } @ApiOperation(value="判斷節點是否存在") @GetMapping("/isExistNode") public boolean isExistNode (final String path){ return zookeeperService.isExistNode(path) ; } @ApiOperation(value="創建節點") @GetMapping("/createNode") public String createNode (CreateMode mode, String path ){ zookeeperService.createNode(mode,path) ; return "success" ; } @ApiOperation(value="設置節點數據") @GetMapping("/setNodeData") public String setNodeData (String path, String nodeData) { zookeeperService.setNodeData(path,nodeData) ; return "success" ; } @ApiOperation(value="創建并設置節點數據") @GetMapping("/createNodeAndData") public String createNodeAndData (CreateMode mode, String path , String nodeData){ zookeeperService.createNodeAndData(mode,path,nodeData) ; return "success" ; } @ApiOperation(value="遞歸獲取節點數據") @GetMapping("/getNodeChild") public List<String> getNodeChild (String path) { return zookeeperService.getNodeChild(path) ; } @ApiOperation(value="是否遞歸刪除節點") @GetMapping("/deleteNode") public String deleteNode (String path,Boolean recursive) { zookeeperService.deleteNode(path,recursive) ; return "success" ; } }
看完上述內容,你們掌握Zookeeper整合SpringBoot2 Curator組件的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注創新互聯行業資訊頻道,感謝各位的閱讀!
分享題目:Zookeeper整合SpringBoot2Curator組件方法
本文來源:http://vcdvsql.cn/article30/pcoeso.html
成都網站建設公司_創新互聯,為您提供網站導航、品牌網站設計、網站排名、網站建設、軟件開發、關鍵詞優化
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯