分布式前修课:Zookeeper锁实现方式

分布式知识全景图:Java开发者的进阶必修课 本文为 Java 开发者梳理分布式知识全景,从 CAP/BASE 理论出发,系统讲解 RPC 通信、消息队列、分布式事务(2PC/TCC/Seata)、分布式锁、雪花算法、缓存一致性、服务治理及链路追踪等核心主题,并提供面试高频题解答与学习资源推荐。 阅读详情

前言

聊完MySQL和Redis,我们接下来在聊一聊Zookeeper。相信大家都已经发现了,这些都是我们在开发过程非常常用的技术。搞定他们,一切难题都不在话下。

Zookeeper,盘它

官网是我们学习某一种技术框架的第一手资料,通过官网我们能挖掘到该框架的最新动态

What Is Zookeeper

Zookeeper是一款主要解决分布式协调的服务框架,可以用来维护配置信息、命名、提供分布式同步和服务提供等功能。Zookeeper基于ZAB【ZooKeeper 原子广播】协议,支持高可用。

图片来源自[官方介绍]ZooKeeper: Because Coordinating Distributed Systems is a Zoo)

Zookeeper的设计

设计目标

Zookeeper的设计很简单,其目的就是为了:

  • 减轻分布式应用程序实现协调服务的压力,允许分布式进程通过共享的分层命名空间相互协调

而在Zookeeper中的文件存储可以称为:znodes,类似于Linux下的目录和文件;而不同的一点是:ZooKeeper 数据保存在内存中。这样也就意味着Zookeeper自身可以实现实现高吞吐量和低延迟

命名空间设计

图片来源自官方介绍

Zookeeper中名称全部由斜杠【/】 分隔的一系列路径元素,命名空间中的每个节点都由路径标识。而每个节点都可以拥有与其关联的数据以及子节点。这就像拥有一个允许文件也成为目录的文件系统

专业点来说Zookeeper中的每一个节点都可以称为znode, 主要分为两类:

  • 持久节点:【节点只要创建就存在,除非手动删除】
  • 临时节点:【只要创建znode的会话处于活动状态,那么当前节点就会存在;当会话结束,临时节点自动删除】

有序节点是在临时节点和持久节点的基础上创建的时候后面跟上顺序,本质上没有发生很大的变化

Zookeeper提供了监听/回调的机制,当客户端对znode进行操作之后,会触发watch机制,客户端受到znode已经改变的数据包。

从开发角度来看,这种属于Reactor编程模型,纯异步编程

Netty就是这种编程模型的典型案例

稳定大局

对Zookeeper有一点了解之后,我们就要开始使用它了,我们使用它的目的是为了实现分布式锁。那么我们先来搞定基础环境

我们这里先按照单机环境来做,后面会给出集群环境的配置方式

需要注意的是:2N + 1原则

Zookeeper集群最少需要三台服务器,并且强烈建议使用奇数台服务器。如果您只有两台服务器,那么您会遇到这样的情况:如果其中一台出现故障,则没有足够的机器来形成多数法定人数。两台服务器本质上不如一台服务器稳定,因为有两个单点故障

环境规划

我们这里使用的Zookeeper版本:3.6.2

Zookeeper强依赖于JDK,并且需要安装JDk1.8之上的版本

nodeipport
zookeeper192.168.10.2002181

单机环境

环境规划完成之后,接下来就看我操作吧。

 wget https://archive.apache.org/dist/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
 # 解压
 tar xf apache-zookeeper-3.6.2-bin.tar.gz -C /usr/local/
 ​
 # 进入到/usr/local下,改个名字
 mv apache-zookeeper-3.6.2-bin/ zookeeper-3.6.2

其实到这里环境就已经安装完成了,下面就是针对Zookeeper的配置

 # 配置文件全部存放在conf下,并且我们需要将模板配置换成`zoo.cfg`,不然无法生效
 cd /usr/local/zookeeper-3.6.2/conf && cp ./zoo_sample.cfg ./zoo.cfg
 ​
 vim zoo.cfg
  # 默认在tmp下,但是tmp属于系统临时文件目录,我们最好进行修改
  dataDir=/var/data/bigdata/zookeeper

按照zoo.cfg中的配置,我们也只需要改动dataDir的目录就可以了,其他的暂时默认就好

关于Zookeeper更多的配置,在官网《配置参数》中找到

环境变量配置

 # 编辑配置
 vim /etc/profile
  export ZOOKEEPER_HOME=/usr/local/zookeeper-3.6.2
  export JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
  export PATH=$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$PATH

 # 使其生效
 source /etc/profile

下面就开始启动阶段了

 # 以下为启动的全部命令
 zkServer.sh [--config <conf-dir>] {start|start-foreground|stop|version|restart|status|print-cmd}
 ​
 # 启动:这里已经将Zookeeper加入到了环境变量中
 zkServer.sh start
 # 展示启动状态
 zkServer.sh status

集群配置

集群配置环境下,需要改变两个地方:

第一步:在zoo.cfg配置文件中添加集群节点的配置

 server.1=192.168.10.200:2181:2888:3888
 server.2=192.168.10.201:2181:2888:3888
 server.3=192.168.10.202:2181:2888:3888

第二步:在各自节点的$dataDir目录下添加myid文件,内容对应上面配置的序号

 echo 1 > myid
 echo 2 > myid
 echo 3 > myid

记得要和zoo.cfg中配置的唯一序号一一对应

集群对比单机版只是多了一些配置,其他的没有任何变化。相对比还是非常简单的

客户端操作

Zookeeper提供了命令行的操作方式,通过zkCli.sh来启动,并且操作方式和Linux命令基本相同,下面我们简单演示一下

 # 本地环境可以不配置
 zkCli.sh [-server 127.0.0.1:2181]

这其实非常简单的,而且我们并不用搞懂它,毕竟我们在操作的时候并不能直接连到服务器上,下面我们来看看如何通过提供的API来对Zookeeper进行操作吧

锁住它

知其然

在《分布式锁原理》一文中我们曾经介绍过基于Zookeeper实现分布式锁的思路,主要通过Zookeeper的临时节点来实现:

  • 在主节点下每个客户端过来都会注册临时有序节点
  • 每个节点只监听自己前一个节点,如果发现自己是第一个节点,说明已经获取到了锁

而只要客户端断开session连接,临时有序节点自动删除,客户端锁就被释放

知其所以然

下面我们就通过Zookeeper的API来实现一个分布式锁吧。还是老样子,一版自己写,一版看看人家的实现方式。对比一下。

原生代码

 private static final CountDownLatch LATCH = new CountDownLatch(1);
 // 获取ZooKeeper的操作
 public static ZooKeeper getZk() {
     ZooKeeper zooKeeper = null;
     try {
         zooKeeper = new ZooKeeper("192.168.10.200:2181/locks", 1000, event -> {
             switch (event.getState()) {
                 case SyncConnected:
                     // 等到回到 链接成功的事件,就能释放阻塞
                     LATCH.countDown();
                     break;
             }
         });
         //Reactor编程模型,返回很快,但是内存中并没有构建完成,所以需要等待
         LATCH.await();
     } catch (Exception e) {
         e.printStackTrace();
     }
     return zooKeeper;
 }

主要代码

public class LockWatchCallback implements Watcher, AsyncCallback.StringCallback, AsyncCallback.ChildrenCallback, AsyncCallback.StatCallback {

    private ZooKeeper zk;
    private String name;
    private String nodePathName;

    private CountDownLatch latch = new CountDownLatch(1);

    public LockWatchCallback(ZooKeeper zk, String name) {
        this.zk = zk;
        this.name = name;
    }

    public void lock() {
        /**
         * 创建节点:
         *  path: 如果在192.168.10.200:2181/locks指定了目录,那么这里的 根目录 代表的是 /locks,然后在创建对应的临时节点
         *  ZooDefs.Ids.OPEN_ACL_UNSAFE: 权限:全部开放
         *  CreateMode.EPHEMERAL_SEQUENTIAL: 临时有序节点
         *  StringCallback: 节点创建完成之后的回调
         */
        zk.create("/lock", name.getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, this, name);
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void unLock() {
        try {
            zk.delete(nodePathName, -1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void process(WatchedEvent event) {
        switch (event.getType()) {
            // 当节点删除之后,重新拉取一次全部子节点,然后进行监听处理
            case NodeDeleted:
                zk.getChildren("/", false, this, "abc");
                break;
        }

    }

    // zk.create("/lock", name.getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL, this, name); 回调
    @Override
    public void processResult(int rc, String path, Object ctx, String name) {
        if (null != name) {
            nodePathName = name;
            // 得到根节点下创建的节点,我们不需要watch根目录
            zk.getChildren("/", false, this, "abc");
        }
    }

    // zk.getChildren("/", false, this, "abc"); 回调
    @Override
    public void processResult(int rc, String path, Object ctx, List<String> children) {
        // 得到的children是无序的,所以要先做一个排序
        Collections.sort(children);

        // /lock0000000000, 而children中是没有斜线的,所以要截取一下
        int i = 1;
        if ((i = children.indexOf(nodePathName.substring(1))) < 1) {
            // 自己已经是第一个节点了,获取到了锁,开始执行
            try {
                zk.setData("/", this.name.getBytes(StandardCharsets.UTF_8), 1);
            } catch (Exception e) {
                e.printStackTrace();
            }
            // 释放掉阻塞,让执行
            latch.countDown();
        } else {
            // 监控自己的前一个节点是否还存在
            try {
                zk.exists("/" + children.get(i - 1), this, this, "abc");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void processResult(int rc, String path, Object ctx, Stat stat) {
    }
}

全程采用Zookeeper提供的异步API方式进行回调处理,在每一步回调的地方都添加了注释,看起来是比较方便的。

毕竟是个不成熟的小案例,缺少了分布式锁的很多特性,比如:锁重入等等

『不用太刻意对上面的代码做研究,在生产环境下是不会使用这样的代码的』

下面我看一下如何测试:为了能和之前的程序进行统一,做了一个小小的封装,也可以直接使用LockWatchCallback对象来处理锁操作

public class ZookeeperLock extends AbstractLock {

    ZooKeeper zk;
    LockWatchCallback watchCallback;
    public ZookeeperLock(ZooKeeper zk) {
        this.zk = zk;
    }

    @Override
    public void start() {
        // 每个线程都需要创建一个临时有序节点,所以每个线程都会new一个watchCallback对象
        watchCallback = new LockWatchCallback(zk, Thread.currentThread().getName());
    }

    @Override
    public void lock() {
        // 加锁,创建节点
        this.watchCallback.lock();
    }

    @Override
    public void unlock() {
        // 解锁,删除节点
        this.watchCallback.unLock();
    }

    @Override
    public void destory() {
        try {
            zk.close();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static ExecutorService executorService = Executors.newCachedThreadPool();

    public static void main(String[] args) throws InterruptedException {
        int[] count = {0};
        final ZookeeperLock zkLock = new ZookeeperLock(getZk());
        for (int i = 0; i < 100; i++) {
            executorService.submit(() -> {
                zkLock.start();

                zkLock.lock();
                count[0]++;
                zkLock.unlock();
            });
        }
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.HOURS);
        System.out.println(count[0]);

        zkLock.destory();
    }
}

成熟框架

那接下来我们就聊一聊成熟的框架是怎么实现分布式锁的:Curator

  • 实现方式是不变的,不过在我们上一版的基础丰富了更多的锁特性,并且实现更加稳定,调用更加方便
public class ZkLock extends AbstractLock {

    private static final Logger LOGGER = LoggerFactory.getLogger(ZkLock.class);

    /**
     * Zookeeper地址 ip:port
     */
    private final String zkAddr;
    /**
     * 总路径
     */
    private final String lockPath;
    private CuratorFramework client;
    private InterProcessLock lock;

    public ZkLock(String zkAddr, String lockPath) {
        this.zkAddr = zkAddr;
        this.lockPath = lockPath;
    }

    @Override
    public void lock() {
        try {
            this.lock.acquire();
        } catch (Exception e) {
            LOGGER.error("Lock异常,异常信息:{}", e.getMessage());
        }
    }

    @Override
    public boolean tryLock() {
        boolean isLocked = false;
        try {
            isLocked = this.lock.acquire(0, TimeUnit.SECONDS);
        } catch (Exception e) {
            LOGGER.error("tryLock异常,异常信息:{}", e.getMessage());
        }
        return isLocked;
    }

    @Override
    public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
        boolean isLocked = false;
        try {
            isLocked = this.lock.acquire(time, unit);
        } catch (Exception e) {
            LOGGER.error("tryLock异常,异常信息:{}", e.getMessage());
        }
        return isLocked;
    }

    @Override
    public void unlock() {
        try {
            this.lock.release();
        } catch (Exception e) {
            LOGGER.error("unlock异常,异常信息:{}", e.getMessage());
        }
    }

    @Override
    public void start() {
        client = CuratorFrameworkFactory.newClient(
                this.zkAddr,
                new RetryNTimes(5, 5000)
        );
        client.start();
        if (client.getState() == CuratorFrameworkState.STARTED) {
            LOGGER.info("zk client start successfully!");
            LOGGER.info("zkAddress:{},lockPath:{}", this.zkAddr, lockPath);
        } else {
            throw new RuntimeException("客户端启动失败。。。");
        }
        this.lock = defaultLock(lockPath);
    }

    /**
     * 公平可重入锁
     *
     * @param lockPath 路径
     * @return InterProcessMutex
     */
    InterProcessLock defaultLock(String lockPath) {
        return new InterProcessMutex(client, lockPath);
    }
}

看看这个代码量是不是简洁了很多,虽然简洁,但是功能俱全。我们来验证一下:

private static ExecutorService executorService = Executors.newCachedThreadPool();

public static void main(String[] args) throws InterruptedException {
    ZkLock zkLock = new ZkLock("192.168.10.200:2181","/locks");
    zkLock.start();

    int[] num = {0};
    long start = System.currentTimeMillis();
    for(int i=0;i<200;i++){
        executorService.submit(()->{
            try {
                zkLock.lock();
                num[0]++;
            } catch (Exception e){
                throw new RuntimeException(e);
            } finally {
                zkLock.unlock();
            }
        });

    }
    executorService.shutdown();
    executorService.awaitTermination(1, TimeUnit.HOURS);
    System.out.println(num[0]);

}

完全OK!!!

最后

关于Zookeeper分布式锁的实现我们就介绍到这里。Zookeeper在实际使用中的场景还是非常丰富的,包括分布式协调等功能都在等着大家一一探索。

Zookeeper在大数据领域的分布式系统故障诊断方法 想象一下,你管理着一个庞大的“数据工厂”(大数据平台),里面有无数台机器(节点)在协同工作:有的负责存储数据(HDFS),有的负责计算任务(YARN),有的负责消息传递(Kafka)。这些机器就像工厂里的工人,需要一个“调度中心”来协调分工、同步信息、处理冲突——这个“调度中心”就是Zookeeper。如果Zookeeper出了故障,就像调度中心突然停电:工人不知道该干什么(任务分配失败)、机器之间信息不同步(数据一致性问题)、甚至整个工厂陷入混乱(服务不可用)。 阅读详情

相关推荐

搭建Zookeeper集群:三台服务器,一场分布式之舞

本文将带你探索如何在三台服务器上搭建一个强大而稳定的Zookeeper集群,并深入解析其详细配置过程。通过实用的步骤和生动的示例,你将学到搭建分布式系统的关键知识点,使你的Zookeeper集群达到最佳性能和可靠性。

todoitbo的博客 1万+

基于Zookeeper实现分布式锁

在Zookeeper中的指定路径下创建创建节点,然后客户端根据当前路径下的节点状态来判断是否加锁成功,如下图一种情况为例,线程1创建节点成功后,线程2再去创建节点就会创建失败。(3)如果加锁次数等于0,则释放锁,删除掉创建的临时节点,下一个监听这个节点的客户端会感知到节点删除事件,从而重新去获取锁。3:判断自己的序号是否最小,如果最小的话,代表加锁成功,如果不是最小的话,就对前一个节点创建监听器。2:使用顺序节点的好处是,可以利用锁释放的事件监听机制,来实现。2:第二步客户端拿到加锁路径下所有创建的节点。

weixin_45125989的博客 2915

从零开始:Vivado中自定义串口通信IP核的完整实现

本文详细介绍了在Vivado中从零开始实现自定义串口通信IP核的完整流程,包括Verilog核心代码编写、仿真验证、IP核封装与参数化配置技巧。通过AXI-Lite总线实现动态配置,提升FPGA开发效率,适用于各种嵌入式系统通信需求。

weixin_29274969的博客 326

zookeeper实现分布式锁

逻辑代码 zookeeper集群

weixin_46633487的博客 259

Abaqus 2023 保姆级安装避坑指南:从环境变量到许可证配置,一次搞定

本文提供Abaqus 2023的详细安装指南,涵盖环境变量设置、许可证配置等关键步骤,帮助用户避开常见安装陷阱。通过系统环境检查、目录结构规划、许可证服务器安装及Java环境配置等实用技巧,确保顺利完成安装并优化软件性能。

weixin_42524276的博客 426

2022年全球市场微波等离子体CVD反应器总体规模、主要生产商、主要地区、产品和应用细分研究报告

据GIR (Global Info Research)调研,按收入计,2021年全球微波等离子体CVD反应器收入大约 百万美元,预计2028年达到 百万美元,2022至2028期间,年复合增长率CAGR为 %。

MARKETRESEARCH的博客 1137

ZK(ZooKeeper)分布式锁实现

点赞再看,养成习惯,微信搜索【牧小农】关注我获取更多资讯,风里雨里,小农等你。 本文中案例都会在上传到git上,请放心浏览 git地址:https://github.com/muxiaonong/ZooKeeper/tree/master/mxnzookeeper 准备 本文会使用到 三台 独立服务器,可以自行提前搭建好。 不知道如何搭建的,可以看我之前 ZooKeeper集群 搭建:Zookeeper 集群部署的那些事儿 关于ZooKeeper 一些基础命令可以看这篇:Zookeeper入门看这篇就够.

牧小农 1917

从48V到800V:TI BMS芯片如何应对高压电池管理挑战?

电池管理系统是电动汽车和储能系统的核心,负责监控电池状态、保障安全并优化性能。其核心原理在于通过高精度测量电池电压、电流和温度,结合算法估算电池的荷电状态与健康状态,从而实现精准的能量管理与寿命预测。在技术价值层面,高精度测量能最大化利用电池化学窗口,提升能量密度与续航里程;而符合功能安全标准的设计则是防止热失控等安全事故的基石。随着汽车电气化从48V轻混系统向400V/800V高压平台演进,BMS面临着测量精度、功能安全、高压隔离通信和系统成本等多重挑战。德州仪器的BQ796xx和BQ75614系列芯片,

weixin_27017211的博客 342

三种连接ZooKeeper的方式

1. 使用客户端命令连接Zookeeper 连接Server  使用命令./zkCli.sh -server 127.0.0.1:2181 连接成功后返回如下信息: Connecting to 127.0.0.1:2181 2018-06-20 00:13:40,884 [myid:] - INFO  [main:Environment@100] - Client environment:zo...

心雨先生 1万+

AI Agent在核电站安全监控中的应用

核电站作为一种高效的能源生产设施,其安全问题一直是全球关注的焦点。任何安全事故都可能导致严重的人员伤亡、环境污染和经济损失。传统的核电站安全监控系统主要依赖于人工操作和固定规则的监控算法,存在监控效率低、无法实时应对复杂情况等问题。本文章的目的在于探讨如何利用AI Agent技术提升核电站安全监控的智能化水平,实现实时、准确的监测和智能决策。范围涵盖了AI Agent的基本原理、在核电站安全监控中的应用场景、相关算法和数学模型,以及实际项目的开发和应用。

AGI×大数据,开启智能时代的认知跃迁;解码AGI,赋能数据驱动的智能革命。 371

OpenClaw小白使用全攻略

OpenClaw全能技能解锁指南:从基础到进阶 摘要: 本文提供OpenClaw AI智能体的完整使用教程,帮助用户从安装后"不知道如何用"到熟练掌握核心功能。教程包含:1)控制台5大区域详解和3个必做初始化设置;2)文件管理、浏览器自动化、文档生成等5大基础功能实操,每个功能配有详细操作步骤、指令模板和效果演示;3)10+高频场景解决方案,如整理文件、搜集资料、写总结等;4)进阶技巧和常见问题解答。通过清晰的图文指引,即使电脑小白也能快速上手,实现办公自动化、提升工作效率。

通俗易懂学IT 3059

Kafka与ZooKeeper:分布式集群的“神经中枢“揭秘

分布式协调:通过临时节点+Watcher实现集群状态管理元数据存储:可靠存储主题/分区/消费者组信息领导选举:公平高效的控制器选举机制配置中心:动态推送集群配置变更架构启示分布式系统需要可靠协调层保证一致性临时节点+Watcher是服务发现的黄金方案法定人数选举可避免脑裂问题未来展望虽然KRaft模式正在取代ZooKeeper,但理解其设计思想仍是构建分布式系统的必修课!ZooKeeper的协调理念将长期影响分布式架构设计。思考题。

全栈开发工程师 1227

AI Agent驱动的多模态情感分析方法:从BERT到Vision Transformer的探索

情感分析(Sentiment Analysis)是自然语言处理(NLP)与计算机视觉(CV)中一项重要任务。传统的情感分析主要依赖于文本数据,但在现实应用中,情感往往通过 语言、语音、表情、姿态 等多模态信号共同传达。因此,结合 多模态深度学习 的 AI Agent 在情感理解中具有广阔的前景。

一键难忘的博客 738

全网最新redis+zookeeper架构师必修课

redis 介绍及NIO原理介绍 【录播】redis 介绍及NIO原理介绍(144分钟) 02 redis的string类型&bitmap 【录播】redis的string类型&bitmap(136分钟) 03 redis的list、set、hash、sorted_set、skiplist 【录播】redis的list、set、hash、sorted_set(133分钟) 04 redis消息订阅、pipeline、事务、modules、布隆过滤器、缓存LRU 【录播】redis消息订

weixin_46240993的博客 167

ICC2如何写出floorplan信息

不用-exclude 的话rows_tracks / vias /blockages / routing_rules信息都会写出去,即便用了-include {macro ports}也不行,所以不介意这些东西的话可以用以下两种种def方式去写floorplan。write_floorplan用法和write_def一样,因为写出来的文件夹里就包含def,用write_floorplan的好处和innovus saveFPlan一样,都能写出voltage area和bound信息。

m0_61544122的博客 1071

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

HBase MasterNotRunningException:ZooKeeper连接超时排查与优化实战

在分布式系统中,ZooKeeper作为核心的协调服务,负责维护集群元数据、服务发现和分布式锁等关键功能。其工作原理基于ZAB协议,通过Leader选举和事务日志同步来保证数据一致性和高可用性。ZooKeeper的技术价值在于为上层应用(如HBase、Kafka)提供了可靠的分布式协调基础,是构建稳定分布式架构的基石。在实际应用场景中,ZooKeeper的连接与会话管理尤为关键,客户端通过会话超时机制与服务端保持心跳,一旦网络波动、服务端负载过高或客户端GC停顿,就容易触发OperationTimeout,导

weixin_30402343的博客 314

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

好程序员大数据技术分享:Zookeeper集群管理与选举

  大数据技术的学习,逐渐成为很多程序员的必修课,因为趋势也是因为自己的职业生涯。在各个技术社区分享交流成为很多人学习的方式,今天很荣幸找到好程序员给我们分享一些大数据基础知识,大家可以一起学习!  1.集群机器监控  这通常用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。这样的场景中,往往有一个监控系统,实时检测集群机器是否存活。过去...

weixin_34050427的博客 78

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Java分布式锁六种实现方案深度解析与实战避坑指南

在微服务与分布式系统架构中,协调多服务实例对共享资源的并发访问是核心挑战。分布式锁作为一种关键的并发控制机制,其原理在于通过一个所有节点都能访问的中间件,实现跨进程的互斥访问,从而保障数据的一致性与系统可靠性。这项技术的核心价值在于解决高并发场景下的资源竞争问题,例如电商秒杀库存扣减、优惠券防超领等,是构建健壮分布式系统的基石。本文聚焦于Java生态下的主流实现,涵盖从基于数据库、Redis原生命令到Redisson、ZooKeeper、Etcd及Consul的六种方案,并深入探讨了锁续期、原子性操作等关键

weixin_29255731的博客 327

【高并发微服务架构必修课】:深入剖析Dubbo基于Zookeeper的服务发现机制

掌握高并发微服务架构核心,深入解析Dubbo服务注册与发现Zookeeper机制,涵盖服务暴露、订阅及故障容错流程,适用于分布式系统构建。基于Zookeeper实现高效动态服务治理,提升系统稳定性与扩展性,值得收藏。

DeepNest的博客 348

ZooKeeper 面试必看!这些常用命令你必须掌握!

本文详细介绍了 ZooKeeper 中常用的几个关键命令,如 `create`、`delete`、`exists`、`get` 和 `set` 等,帮助开发者快速掌握节点操作的核心方法。此外,还讲解了权限管理命令 `acl` 以及配置调整命令 `reconfig` 的使用场景和注意事项。这些命令是 ZooKeeper 日常管理和维护的基础工具,在分布式系...

蓝鲸鱼计算机软件开发工作室 691

大数据学习路线:Zookeeper集群管理与选举

大数据技术的学习,逐渐成为很多程序员的必修课,因为趋势也是因为自己的职业生涯。在各个技术社区分享交流成为很多人学习的方式,今天很荣幸给我们分享一些大数据基础知识,大家可以一起学习!   1.集群机器监控   这通常用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。这样的场景中,往往有一个监控系统,实时检测集群机器是否存活。过去的做法通常是:监控系统通过...

weixin_30662109的博客 148

Springboot 整合 Dubbo/ZooKeeper你不知道的那点事,大神必修课

“看看星空,会觉得自己很渺小,可能我们在宇宙中从来就是一个偶然。所以,无论什么事情,仔细想一想,都没有什么大不了的。这能帮助自己在遇到挫折时稳定心态,想得更开。” – 《腾讯传》 本文提纲 一、为啥整合 Dubbo 实现 SOA 二、运行 springboot-dubbo-server 和 springboot-dubbo-client 工程 三、springboot-dubbo-server 和...

weixin_33826609的博客 140
上一篇: Java并发之ThreadLocal
下一篇: GitHub爆热门!最全并发编程合集上线3分钟获星标180K
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值