前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >zookeeper应用

zookeeper应用

作者头像
sucl
发布于 2019-08-07 06:52:11
发布于 2019-08-07 06:52:11
70500
代码可运行
举报
文章被收录于专栏:企业平台构建企业平台构建
运行总次数:0
代码可运行

通过上一篇的学习,对zookeeper大致有了一些了解,但是想在实际开发与合适的业务场景中使用,还是需要依赖更多深入的学习,同时在项目中不断的实实践,发现问题并解决,才能对技术有更清晰与独特的见解。

本文从几个方面去学习如何使用zookeeper。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、通过原生的api进行操作
2、通过zkClient进行操作
3、使用curator进行操作
4、各种应用场景的实现

当然以上内容主要来源于他人的成果,同时经过测试与理解,更加方面自己去理解其中的要义。

zookeeper API

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、引入zookeeper依赖jar 
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.10</version>
</dependency>

2、建立连接
public class ZookeeperConnection implements Watcher {
    private ZookeeperProperties properties;
    public static ZooKeeper zooKeeper;
    private CountDownLatch countDownLatch = new CountDownLatch(1);

    public ZookeeperConnection(ZookeeperProperties properties){
        this.properties = properties;
    }

    public void connect(){
        try {
            zooKeeper = new ZooKeeper(properties.getAddress(),properties.getTimeout(),this);
            countDownLatch.await();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("zookeeper connected!");
    }

    public void process(WatchedEvent event) {
        if(event.getState() == Event.KeeperState.SyncConnected){
            countDownLatch.countDown();
        }
    }
}

3API
创建节点:
    zk.create("/node", data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
获取子节点:
    zk.getChildren("/node", true)
获取数据:
    zk.getData("/node", true, null)
设置数据: 
    zk.setData("/node","data".getBytes(),-1)
判断是否存在:
    zk.exists("/node",watch)
删除节点:
    zk.delete("/node",-1)
关于zk的api其实不多,但是我们需要知道的是在什么情况如何搭配使用,上面主要是通过同步的方式操作,当然我们在创建节点、设置数据、删除节点时都可以通过回调函数实现异步操作。同时需要注意的是,watch是一次性的,如果调用,下次如果需要继续监听指定节点,需要再次注册。

下面会对acl、watch进行一些说明。

zkClient使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、引入zkClient依赖jar
<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.9</version>
</dependency>
2、建立连接
    ZkClient zkClient = new ZkClient("10.8.109.60:2181", 10000, 10000, new SerializableSerializer())
3API调用
  创建节点:
    zkClient.create("/user",user, CreateMode.PERSISTENT)
  删除节点:
    zkClient.delete("/node") //节点不存在返回false,节点存在子节点则异常
    zkClient.deleteRecursive("/pnode") //无论有无节点或子节点都能删除
  获取子节点:
    zkClient.getChildren("/")
  获取数据:
    zkClient.readData("/user", stat) //将状态会写入stat
  设置数据:  
    zkClient.writeDataReturnStat("/", data, -1)
  节点是否存在:
    zkClient.exists("/node")
  监听:
    IZkChildListener
        zkClient.subscribeChildChanges("/node", new IZkChildListener(){...}) //监听node节点的创建/删除、创建/删除子节点
    IZkDataListener
        zkClient.subscribeDataChanges("/", new IZkDataListener(){...}) //监听指定节点的数据改变

curator使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、引入依赖
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.4.0</version>
</dependency>
2、创建连接
RetryPolicy retryPolicyOne = new ExponentialBackoffRetry(1000, 3) //重试间隔、重试次数
CuratorFramework client = CuratorFrameworkFactory.newClient("localhost:2181", 5000, 5000, retryPolicyOne)
client.start();
或者
CuratorFramework client = CuratorFrameworkFactory
        .builder()
        .connectString("localhost:2181")
        .sessionTimeoutMs(5000)
        .connectionTimeoutMs(5000)
        .retryPolicy(retryPolicyThree)
        .build()
client.start()
3API
  创建节点:
    client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/node", "".getBytes())
  删除节点: 
// 删除(无子节点的)节点
    client.delete().forPath("/a_node");
// 删除指定版本的(无子节点的)节点
    client.delete().withVersion(4).forPath("/a_node");
// 删除节点(如果有子节点,也一并删除)
    client.delete().deletingChildrenIfNeeded().forPath("/a_node");
// 删除指定版本的节点(如果有子节点,也一并删除)
    client.delete().deletingChildrenIfNeeded().withVersion(4).forPath("/a_node");
// 只要Session有效,那么就会对指定节点进行持续删除,知道删除成功; 这是一种保障机制
    client.delete().guaranteed().deletingChildrenIfNeeded().withVersion(4).forPath("/a_node");
  获取子节点:
    client.getChildren().forPath("/")
  获取数据:
    client.getData().storingStatIn(stat).forPath("/")
  设置数据:
    client.getData().storingStatIn(statOne).forPath("/")
  节点是否存在:
    client.checkExists().forPath("/")
 监听:
    //节点监听
    NodeCache cache = new NodeCache(client,"/node")
    cache.getListenable().addListener(new NodeCacheListener() { //节点创建、节点内容改变
        @Override
        public void nodeChanged() throws Exception {
            byte[] newData = cache.getCurrentData().getData();
        }
    });
    
    //子节点监听
    final PathChildrenCache cache = new PathChildrenCache(client,"/node", true);
    cache.start();
    // 当目标节点的子节点被创建、子节点被删除、子节点数据内容发生变化等时,会触发监听方法
    cache.getListenable().addListener(new PathChildrenCacheListener() {
        @Override
        public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
            byte[] data;
            switch (event.getType()){
                case CHILD_ADDED :
                    System.out.println("新增子节点!");
                    break;
                case  CHILD_REMOVED :
                    System.out.println("删除子节点!");
                    break;
                case CHILD_UPDATED :
                    System.out.println("修改子节点数据内容!");
                    break;
                default :;
            }
        }
    });
和zkClienet相比,zkClient监听的主要分为节点与数据,而curator则是针对本节点、子节点。

ACL与Watch:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1、在新建节点时,我们可以对该节点设置对应的ACL,保证在对节点的后续操作时都必须满足ACL的设定,那么ACL具体如何理解与设置?
其实对节点的访问控制主要是什么对象对该节点有什么样的操作,那么什么对象我们用Id表示,节点则是当前创建的node,而操作则有rwacd(READ\WRITE\ADMIN\CREATE\DELETE)。
而ACL的表达式一般格式为:scheme:id:perm,在zk客户端中我们可以这样来对节点设置acl。eg: world:anyone:wr
scheme:
    world:默认方式,相当于全世界都能访问,唯一id为anyone
    auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户),没有id
    digest:即用户名:密码这种方式认证,这也是业务系统中最常用的,,setAcl <path> digest:<user>:<password(密文)>:<acl>
           第二密码是经过sha1及base64处理的密文
           echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
    host:根据地质认证
    ip:使用Ip地址认证
id:
    anyone
perm:
    CREATE: create
    READ: getData getChildren
    WRITE: setData
    DELETE: delete
    ADMIN: setAcl
代码示例:  
    //world
    List<ACL> acls = ZooDefs.Ids.OPEN_ACL_UNSAFE;
    //auth
    new ACL(ZooDefs.Perms.ALL,new Id("auth","username:password"));
    //digest
    ACL aclDigest = new ACL(ZooDefs.Perms.ALL, new Id("digest", DigestAuthenticationProvider.generateDigest("username:password")));
    //host
    new ACL(ZooDefs.Perms.ALL,new Id("host","scl.com"));
    //ip
    new ACL(ZooDefs.Perms.ALL,new Id("ip","192.168.1.1/25"));
CLI示例:
    auth:
        >addauth digest <username>:<password>
        >setAcl /node auth:<username>:wradc
    digest:
        >echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
        >setAcl <path> digest:<user>:<BASE64[SHA-1[password]]>:<acl>
    host:
        >setAcl <apth> host:<host>:<acl>  //支持后缀 没试过
    ip:
        >setAcl <path> ip:<ip/bits>:<acl> //支持ip段,*匹配 不管怎么设置,不是Authentication is not valid就是alc is valid
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
watch主要是在创建节点、获取数据、判断节点是否存在是触发,针对不同的行为或者是事件被触发时所作出的响应,在zookeeper中有以下事件:
    EventType.NodeCreated
    EventType.NodeDeleted
    EventType.NodeDataChanged
    EventType.NodeChildrenChaged
这些主要是围绕节点与数据变化时对应的事件,但是要注意,NodeDeleted会影响getChildren设置的watcher,详情可以看这个网站。
-

zookeeper应用场景:

在curator-recipes中其实对以下场景基本都有实现,主要是需要了解其实现原理。

  1. 命名服务 由于zookeeper中的节点(路径)的唯一性,我们可以创建唯一的服务命名;同时在分布式环境中,还可以借助节点数据的版本创建有序的分布式id。 我们可以通过数据版本dataVersion实现: @Component public class IdGenerator { private ZookeeperConnection connection; private static final String NODE_ID = "/namespace/id"; @Autowired public IdGenerator(ZookeeperConnection connection){ this.connection = connection; initNode(); } private void initNode() { try { if( connection.zk().exists(NODE_ID,false)==null){ if(connection.zk().exists("/namespace",false)==null){ connection.zk().create("/namespace",null,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); } connection.zk().create(NODE_ID,null,ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public int id(){ try { Stat stat = connection.zk().setData(NODE_ID,null, -1); if(stat!=null){ return stat.getVersion(); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return -1; } } 或者通过持久化有序节点实现: @Component public class IdSequence { private ZookeeperConnection connection; private ZkClient zkClient; private static final String PARENT_NODE = "/namespace"; private static final String NODE = "/idseq"; @Autowired public IdSequence(ZookeeperConnection connection){ this.connection = connection; init(); } private void init() { connection.initZkClient(); this.zkClient = connection.getZkClient(); if(!zkClient.exists(PARENT_NODE)){ zkClient.createPersistent(PARENT_NODE); } } public String id(){ String node = zkClient.createPersistentSequential(PARENT_NODE + NODE, null); return node.substring((PARENT_NODE+NODE).length()); } }
  2. 配置管理 在集群环境中,各个子系统都会有多个相同的实例,如果其相关的配置有改动,则每个系统都要统一修改,通过zookeeper,将配置写入某个节点下,每个子系统通过watcher监听节点的变化,从而能够及时响应配置的修改,而只用关注一个配置中心即可。 @Component public class ConfigManager implements Watcher,ApplicationEventPublisherAware { private String configNode = "/config"; @Autowired private ZookeeperConnection connection; private ApplicationEventPublisher applicationEventPublisher; public String watchConfig(){ try { byte[] data = connection.zk().getData(configNode, this, null); return new String(data); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } return null; } public void setData(String config){ try { connection.zk().setData(configNode,config.getBytes(),-1); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public void process(WatchedEvent event) { String config = watchConfig();//持续监听 applicationEventPublisher.publishEvent(new ConfigChangeEvent(config)); } @Override public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.applicationEventPublisher = applicationEventPublisher; } } @Data public class ConfigChangeEvent extends ApplicationEvent { private String config; /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ public ConfigChangeEvent(Object source) { super(source); this.config = Objects.toString(source,null); } } @Component public class ConfigChangeListener implements ApplicationListener<ConfigChangeEvent> { @Autowired private ConfigRegistry configRegistry; public void onApplicationEvent(ConfigChangeEvent event) { configRegistry.run(event.getConfig()); } } @Component public class ConfigRegistry { private List<Server> servers = new ArrayList<>(); public void regist(Server... ss){ Arrays.stream(ss).forEach(s->{servers.add(s);}); } public void run(String config){ servers.stream().forEach(s->{ s.refresh(config); }); } } public class SimpleServer implements Server{ private String name; public SimpleServer(String name){ this.name = name; } public SimpleServer(){ this.name = UUID.randomUUID().toString(); } @Override public String getName() { return this.name; } @Override public void refresh(String config) { System.out.println(String.format("server :%s config is changed :%s",getName(),config)); } } @Test public void test() throws InterruptedException { Server s1 = new SimpleServer("server1"); Server s2 = new SimpleServer("server2"); Server s3 = new SimpleServer("server3"); configRegistry.regist(s1,s2,s3); configManager.watchConfig(); TimeUnit.SECONDS.sleep(Long.MAX_VALUE); } 原理基本上就是创建一个/config节点,多个服务关注该节点,即监听其数据变化,通过getData置入监听,但注意watch的一次性,需要往复监听,一段该节点数据发生变化,那么注册的所有服务将会通过发布监听事件将新的配置传递到各个子服务上。
  3. 负载均衡 在传统的单应用中,往往会因为用户的激增,导致无法一次性处理较多的请求,这时候可以部署多个完全一样的应用,通过负载均衡将各个请求分发到不同系统中取,一般会用ngixn、LVS完成,当然 zookeeper也可以实现了。 -
  4. 分布式锁 前面用到redis做分布式锁,主要是为了保证分布式环境中,数据的一致性,zookeeper可以通过节点的唯一性实现排它锁,通过有序节点,实现共享锁。借助curator更快地实现。 public void lock(String id){ try { this.lockPath = zk.create(PARENT_NODE.concat(NODE), id.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL); List<String> children = zk.getChildren(PARENT_NODE, true); if(!CollectionUtils.isEmpty(children)){ children.sort(Comparator.comparing(String::valueOf)); if(!PARENT_NODE.concat("/").concat(children.get(0)).equals(lockPath)){ int preIndex = Collections.binarySearch(children,lockPath.substring(PARENT_NODE.length()+1)); System.out.println("id:"+id+" 锁节点:"+lockPath); CountDownLatch countDownLatch = new CountDownLatch(1); zk.exists(PARENT_NODE.concat("/").concat(children.get(preIndex-1)), new Watcher() { @Override public void process(WatchedEvent event) { if(event.getType() == Event.EventType.NodeDeleted){ countDownLatch.countDown(); // System.out.println("删除锁节点:"+event.getPath()); } } }); countDownLatch.await(); } System.out.println("获取锁:"+lockPath+" id:"+id); } } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } public void unlock(){ if(!StringUtils.isEmpty(lockPath)){ try { System.out.println("释放锁:"+lockPath); zk.delete(lockPath,-1); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } } 测试: public void lock() throws InterruptedException { int count = 10; CountDownLatch countDownLatch = new CountDownLatch(count); List<String> result = new ArrayList<>(); for(int i = 0; i<count; i++){ String name = "app"+i; Thread app = new Thread(()->{ ZkLock lock = new ZkLock(connection); lock.lock(name);//阻塞 result.add(name); lock.unlock(); countDownLatch.countDown(); },name); app.start(); } countDownLatch.await(); System.out.println(result); }
  5. 发布订阅 其实就是监听一个节点,但由于watch是一次性的,需要循环监听。可以通过zkClient完成 @Data public class Publisher { private static String NODE = "/info"; private String channel; private ZkClient zkClient; public Publisher(String channel,ZkClient zkClient){ this.channel = channel; this.zkClient = zkClient; if(!zkClient.exists("/".concat(channel))){ zkClient.createPersistent("/".concat(channel)); } } public void push(Object data) { zkClient.createPersistentSequential("/".concat(channel).concat(NODE),data); } public void subscribe(Subscibe subscibe) { zkClient.subscribeChildChanges("/".concat(channel),subscibe); zkClient.subscribeDataChanges("/".concat(channel),subscibe); } public void unsubscribe(Subscibe subscibe){ zkClient.unsubscribeDataChanges("/".concat(channel),subscibe); zkClient.unsubscribeChildChanges("/".concat(channel),subscibe); } } @Data public class Subscibe implements IZkChildListener ,IZkDataListener { private String channel; private ZkClient zkClient; private Callback callback; public Subscibe(String channel,ZkClient zkClient){ this.channel = channel; this.zkClient = zkClient; } @Override public void handleChildChange(String node, List<String> list) throws Exception { List<String> children = zkClient.getChildren("/".concat(channel)); if(children!=null && children.size()>0){ children.sort(Comparator.comparing(String::valueOf)); for(String child : children){ Object data = zkClient.readData("/".concat(channel).concat("/").concat(child)); if(callback!=null){ callback.call(data); } zkClient.delete("/".concat(channel).concat("/").concat(child)); } }else{ } zkClient.subscribeChildChanges("/".concat(channel),this); } @Override public void handleDataChange(String dataPath, Object data) throws Exception { System.out.println("数据修改: "+ dataPath +":" +data); } @Override public void handleDataDeleted(String dataPath) throws Exception { System.out.println("节点数据删除:"+dataPath); } public interface Callback{ void call(Object data); } } @Data @Component public class PSCenterManager { private List<Publisher> publishers = new ArrayList<>(); private ZkClient zkClient; @Autowired public PSCenterManager(ZookeeperConnection connection){ this.zkClient = connection.getZkClient(); } public void addPublisher(Publisher ... _publishers){ publishers.addAll(Arrays.asList(_publishers)); } /** * 发布消息 * @param data */ public void push(Object data){ for(Publisher publisher : publishers){ publisher.push(data); } } /** * 订阅节点 * @param subscibe */ public void registry(Subscibe subscibe){ for(Publisher publisher : publishers){ if(subscibe.getChannel().equals(publisher.getChannel())){ publisher.subscribe(subscibe); } } } public void unregistry(Subscibe subscibe){ for(Publisher publisher : publishers){ if(subscibe.getChannel().equals(publisher.getChannel())){ publisher.unsubscribe(subscibe); } } } } 测试:在/channel节点下新增节点都能及时发现 public class PubSubTest extends AbstractTest { @Autowired private PSCenterManager centerManager; @Test public void test() throws InterruptedException { String channel = "channel"; ZkClient zkClient = centerManager.getZkClient(); zkClient.setZkSerializer(new ZkSerializer(){ @Override public byte[] serialize(Object data) throws ZkMarshallingError { return data==null?null:data.toString().getBytes(); } @Override public Object deserialize(byte[] bytes) throws ZkMarshallingError { return new String(bytes); } });// Publisher publisher = new Publisher(channel,zkClient); Subscibe subscibe = new Subscibe(channel,zkClient); subscibe.setCallback(new Subscibe.Callback() { @Override public void call(Object data) { System.out.println("数据:"+data); } }); centerManager.addPublisher(publisher); centerManager.registry(subscibe); for(int i=0;i<10;i++){ centerManager.push("data"+i); TimeUnit.SECONDS.sleep(1); } while (true){ } } }
  6. 消息队列 类似于mq,生产者生产消息,消费者消费消息,其实核心的是如何构建一个分布式队列。通过某个节点来维护消息的通道,而具体的消息作为该节点的值。分布式消息队列要注意在进行数据存取时如何保证数据的一致性。 -
  7. 集群管理 -

通过zookeeper实现各种场景的应用确实不易,还需深入理解zookeeper,虽然zk的实现非常复杂,但是暴露的api还是比较简单,而且上面说到的场景在其他的jar包中也有实现,以上可能有些地方因为理解或者测试原因可能存在一定的问题,还是需要在不断实践过程中深入理解与实践才是学习的根本。

代码:https://github.com/suspring/springboot-zookeeper

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Zookeeper实现分布式锁
导读 真是有人(锁)的地方就有江湖(事务),今天不谈江湖,来撩撩人。 分布式锁的概念、为什么使用分布式锁,想必大家已经很清楚了。前段时间作者写过Redis是如何实现分布式锁,今天这篇文章来谈谈Zookeeper是如何实现分布式锁的。 陈某今天分别从如下几个方面来详细讲讲ZK如何实现分布式锁: ZK的四种节点 排它锁的实现 读写锁的实现 Curator实现分步式锁 ZK的四种节点 持久性节点:节点创建后将会一直存在 临时节点:临时节点的生命周期和当前会话绑定,一旦当前会话断开临时节点也会删除,当然可以主动删除
爱撒谎的男孩
2020/04/21
6800
Zookeeper实现分布式锁
zookeeper分布式协调机制及创建分布式锁
要了解zookeeper如何创建分布式锁,先了解一下zookeeper。zookeeper官网给出解释:Apache ZooKeeper致力于开发和维护开源服务器,实现高度可靠的分布式协调。
神秘的寇先森
2018/09/29
5580
Zookeeper:实现“分布式锁”的 Demo
Zookeeper 能保证数据的强一致性,用户任何时候都可以相信集群中每个节点的数据都是相同的。一个用户创建一个节点作为锁,另一个用户检测该节点,如果存在,代表别的用户已经锁住,如果不存在,则可以创建一个节点,代表拥有一个锁。
栗筝i
2022/12/02
2140
Zookeeper分布式协调工具【入门到精通】
官方文档上这么解释zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。 上面的解释有点抽象,简单来说zookeeper=文件系统+监听通知机制。
高大北
2022/06/27
5941
Zookeeper分布式协调工具【入门到精通】
【Zookeeper的客户端使用和集群特性】
项目构建 zookeeper 官方的客户端没有和服务端代码分离,他们为同一个jar 文件,所以我们直接引入zookeeper的maven即可, 这里版本请保持与服务端版本一致,不然会有很多兼容性的问题
Java廖志伟
2022/03/07
9480
【Zookeeper的客户端使用和集群特性】
Apache Curator操作zookeeper的API使用
配置完依赖后,我们就可以来写一个简单的demo测试与zookeeper服务端的连接。代码如下:
端碗吹水
2020/09/23
1.1K0
Apache Curator操作zookeeper的API使用
zookeeper应用:屏障、队列、分布式锁
项目地址:https://github.com/windwant/windwant-demo/tree/master/zookeeper-service
WindWant
2020/09/11
4600
Spring整合ZooKeeper基础使用介绍
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,广泛应用于分布式系统中,比如有用它做配置中心,注册中心,也有使用它来实现分布式锁的,作为高并发技术栈中不可或缺的一个基础组件,接下来我们将看一下,zk应该怎么玩,可以怎么玩
一灰灰blog
2021/04/28
1.4K0
Spring整合ZooKeeper基础使用介绍
Zookeeper 操作练习
与ZooKeeper集合进行交互的应用程序称为 ZooKeeper客户端或简称客户端。 Znode是ZooKeeper集合的核心组件,ZooKeeper API提供了一小组方法使用ZooKeeper集合来操纵znode的所有细节。
名字是乱打的
2021/12/22
3140
Zookeeper 操作练习
ZooKeeper分布式协调服务(节点分类、事件监听、java集成)
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
鱼找水需要时间
2023/02/16
4180
ZooKeeper分布式协调服务(节点分类、事件监听、java集成)
分布式之Zookeeper一(分布式锁与Zookeeper集群)
说到分布式开发,不得不说的就是zookeeper了;zookeeper官网说到Apache ZooKeeper致力于开发和维护可实现高度可靠的分布式协调的开源服务器。那么zk作为一个协调者的存在,是分布式比不可少的一部分。废话不多说,直接上干货
Java_老男孩
2019/12/02
4760
zookeeper javaApi 事件监听
Watcher 监听机制是 Zookeeper 中非常重要的特性,我们基于 zookeeper 上创建的节点,可以对这些节点绑定监听 事件,比如可以监听节点数据变更、节点删除、子节点状态变更等事件,通过这个事件机制,可以基于 zookeeper 实现分布式锁、集群管理等功能 watcher 特性:当数据发生变化的时候, zookeeper 会产生一个 watcher 事件,并且会发送到客户端。但是客户端 只会收到一次通知。如果后续这个节点再次发生变化,那么之前设置 watcher 的客户端不会再次收到消息。(watcher 是一次性的操作)。 可以通过循环监听去达到永久监听效果
周杰伦本人
2022/10/25
1.1K0
Zookeeper实现微服务统一配置中心
Zookeeper:它是一个分布式服务框架,是Apache Hadoop 的一个子项目,提供一种集中式信息存储服务,用于解决分布式应用中的一些数据管理问题
阿凯
2019/12/19
1.5K0
Zookeeper实现微服务统一配置中心
ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表
zk做为分布式架构中的重要中间件,通常会在上面以节点的方式存储一些关键信息,默认情况下,所有应用都可以读写任何节点,在复杂的应用中,这不太安全,ZK通过ACL机制来解决访问权限问题,详见官网文档:http://zookeeper.apache.org/doc/r3.4.6/zookeeperProgrammers.html#sc_ZooKeeperAccessControl 总体来说,ZK的节点有5种操作权限: CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,
菩提树下的杨过
2018/01/19
2.6K0
ZooKeeper 笔记(5) ACL(Access Control List)访问控制列表
zookeeper使用
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/09/18
5590
使用zookeeper实现分布式锁
在同一个jvm进程中时,可以使用JUC提供的一些锁来解决多个线程竞争同一个共享资源时候的线程安全问题,但是当多个不同机器上的不同jvm进程共同竞争同一个共享资源时候,juc包的锁就无能无力了,这时候就需要分布式锁了。常见的有使用zk的最小版本,redis的set函数,数据库锁来实现,本节我们谈谈使用zookeeper的序列节点机制来实现一个分布式锁。
加多
2018/09/06
6370
使用zookeeper实现分布式锁
进阶分布式系统架构系列(十三):Zookeeper 分布式锁原理与实现
前面介绍了 Zookeeper 集群 ZAB 协议、配置中心、注册中心、数据与存储、会话与事务管理等相关的知识点,今天我将详细的为大家介绍 zookeeper 分布式锁相关知识,希望大家能够从中收获多多!如有帮助,请点在看、转发支持一波!!!
民工哥
2023/09/09
1.6K0
进阶分布式系统架构系列(十三):Zookeeper 分布式锁原理与实现
Zookeeper分布式锁
在单体项目中jvm中的锁即可完成需要,但是微服务、分布式环境下,同一个服务可能部署在多台服务器上,多个jvm之间无法通过常用的jvm锁来完成同步操作,需要借用分布式锁来完成上锁、释放锁。例如在订单服务中,我们需要根据日期来生成订单号流水,就有可能产生相同的时间日期,从而出现重复订单号。(jdk8使用LocalDateTime线程安全,不会存在这样的问题)
海向
2020/06/17
4660
zk分布式任务管理
在我们的系统开发过程 中不可避免的会使用到定时任务的功能,而当我们在生产环境部署的服务超过1台时,就需要考虑任务调度的问题,防止两台或多台服务器上执行同一个任务,这个问题今天咱们就用zookeeper来解决。
写代码的猿
2019/05/07
1.4K0
zk分布式任务管理
Zookeeper之Watch机制、分布式锁的实现
Zookeeper作为分布式协调组件,在分布式的架构中承担着不可替代的作用,在与dubbo组合的架构中承担着注册中心的重任,有些SC项目也会采用Zookeeper作为配置中心,更多的时候,zookeeper作为分布式锁的的重要实现手段。现来总结一下Zookeeper的watch机制,一方面能够深入加强自己对zk的理解应用,另一方面也能更好地把控zk对我们项目的支持。
不蜇人的小蜜蜂
2019/08/29
2K0
相关推荐
Zookeeper实现分布式锁
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文