zookeeper的入门学习

目录

1.在官网下载apache-zookeeper-3.6.3-bin.tar

2.解压在linux中的data/zookeeper 下

3.cp  zoo_sample.cfg   zoo.cfg 

4. vim zoo.cfg

4.set get的使用

5.关于ttl节点 我们需要去启动系统参数

 6.启动zookeeper 服务端

7.启动zookeeper客户端

8.创建ttl节点(5秒后消失)

9.事件监听机制(只会生效一次)

10.removeWatches /xxx  移除监听

11.ACL

(1)digest密文授权

(2)auth明文授权 

 (3) IP权限模式

12.zookeeper在idea的使用

13.zookeeper的集群 leader  follower  observer

14.zookeeper的分布式锁

非公平锁

 公平锁

共享锁


1.在官网下载apache-zookeeper-3.6.3-bin.tar

2.解压在linux中的data/zookeeper 下

3.cp  zoo_sample.cfg   zoo.cfg 

4. vim zoo.cfg

4.set get的使用

5.关于ttl节点 我们需要去启动系统参数

  • vim zkServer.sh

 6.启动zookeeper 服务端

./bin/zkServer,sh start conf/zoo.cfg

7.启动zookeeper客户端

./bin/zkCli.sh

8.创建ttl节点(5秒后消失)

create -t 5000 /ttl-node

9.事件监听机制(只会生效一次)

节点监听get 【-s】 【-w】 path

这个 -w 就会对节点开启监听 当客户端这个节点发送变化,服务端会主动通给给我

 目录监听 ls -w /xxx

对多个子节点进行监听 ls -R -w /test

10.removeWatches /xxx  移除监听

11.ACL

(1)digest密文授权

在create 的最后一个参数是ACL

下面这里生成的就是秘钥

注意:user1 和 pass1

 create /zknode ddd digest   :     user1    :    秘钥   :  rw(这里填的是权限信息)


此时再zget /znode 会报错  因为它不知道你是谁   只有user1才能对他访问


我们需要在访问前添加授权信息

addauth digest user1:pass1

(2)auth明文授权 

addauth  digest   user1  :   pass1

create /zknode2 xxx  auth  :  user1  :  pass1   :  rw

 (3) IP权限模式

create /zknode3 node3   ip  :  192.168.109.130  :  rw

设置只有ip为192.168.109.130的客户端连接才能进行ad 

zookeeper数据结构

12.zookeeper在idea的使用

(1)导入包

(2)注意countdownlatch  zookeeper 每次在get的时候,都会重新设置监听w

byte[] data = zooKeeper.getData("/myconfig", this, null);

这个this 指的就是watcher  因为watcher 只能用一次,所以每次改完后都需要重加入

package zookeeper.client;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.*;

import java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

@Slf4j
public class ConfigCenter {

    private final static  String CONNECT_STR="10.0.12.11:22";

    //操作时间
    private final static Integer  SESSION_TIMEOUT=30*1000;

    private static ZooKeeper zooKeeper=null;


    private static CountDownLatch countDownLatch=new CountDownLatch(1);

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {


        //zookeeper的创建时线程异步的一件事情  需要contdownLatch
        //为什么不能直接new zookeeper
        //因为 sentThread  和 eventThead是守护线程
        zooKeeper=new ZooKeeper(CONNECT_STR, SESSION_TIMEOUT, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                    if (event.getType()== Event.EventType.None
                            && event.getState() == Event.KeeperState.SyncConnected){
                        log.info("连接已建立");
                        countDownLatch.countDown();
                    }
            }
        });
        countDownLatch.await();


        MyConfig myConfig = new MyConfig();
        myConfig.setKey("anykey");
        myConfig.setName("anyName");

        //序列化工具
        ObjectMapper objectMapper=new ObjectMapper();

        //转换成字节
        byte[] bytes = objectMapper.writeValueAsBytes(myConfig);

        String s = zooKeeper.create("/myconfig", bytes, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);


        Watcher watcher = new Watcher() {
            @SneakyThrows
            @Override
            public void process(WatchedEvent event) {
                if (event.getType()== Event.EventType.NodeDataChanged
                        && event.getPath()!=null && event.getPath().equals("/myconfig")){
                    log.info(" PATH:{}  发生了数据变化" ,event.getPath());

                    byte[] data = zooKeeper.getData("/myconfig", this, null);

                    MyConfig newConfig = objectMapper.readValue(new String(data), MyConfig.class);

                    log.info("数据发生变化: {}",newConfig);

                }


            }
        };

        byte[] data = zooKeeper.getData("/myconfig", watcher, null);
        MyConfig originalMyConfig = objectMapper.readValue(new String(data), MyConfig.class);
        log.info("原始数据: {}", originalMyConfig);


        TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
    }




}

13.zookeeper的集群 leader  follower  observer

1.首先创建4个文件夹 zk1  zk2 zk3 zk4

2.给他们加上唯一的表示  echo 1 > zk1/myid   echo 2 > zk2/myid  ……

 3.修改配置文件 端口号 data 位置都要改

前一个2001 是我们自己定义的需要通信的端口

后一个3001 是我们自己定义的需要集群选举的端口 

 4.启动三个服务

14.zookeeper的分布式锁

我们如果使用nginx开启十个请求  通过jmeter来模拟,然后商品只有五个库存,十个请求每次拿一个。最终商品就会变成 -5; 此时我们就需要分布式锁

非公平锁

 公平锁

  • lockpath:路径
  • InterProcessMutex  互斥锁

 具体操作

1.创建curator 客户端

@Configuration
public class CuratorCfg {

    @Bean(initMethod = "start")
    public CuratorFramework curatorFramework(){
        //两个参数的意思是 在失败后 等待1000ms  继续重试  最多重试三次
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        //创建 curator客户端
        CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.109.200:2181", retryPolicy);
        return client;
    }
}

2.进行加锁操作

@RestController
public class TestController {


    @Autowired
    private OrderService orderService;

    @Value("${server.port}")
    private String port;


    //curator 客户端
    @Autowired
    CuratorFramework curatorFramework;

    @PostMapping("/stock/deduct")
    public Object reduceStock(Integer id) throws Exception {

        InterProcessMutex interProcessMutex = new InterProcessMutex(curatorFramework, "/product_" + id);

        try {
            // ... 不加参数意味着   如果失败就会一直加锁  
            interProcessMutex.acquire();
            orderService.reduceStock(id);

        } catch (Exception e) {
            if (e instanceof RuntimeException) {
                throw e;
            }
        }finally {
            interProcessMutex.release();
        }
        return "ok:" + port;
    }


}
ourPath = (String)((ACLBackgroundPathAndBytesable)client.create().creatingParentContainersIfNeeded().withProtection().withMode(CreateMode.EPHEMERAL_SEQUENTIAL)).forPath(path, lockNodeBytes);

锁为什么要用容器节点?creatingParentContainersIfNeeded

因为容器的节点全都没了后,就会被自动删除,如果使用持久化节点,还需要自己去维护

CreateMode.EPHEMERAL_SEQUENTIAL  临时顺序节点

为什么用临时节点 和顺序节点 

临时节点是为了解决羊群效应;顺序节点是为了公平锁的实现

共享锁

集群选举

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值