zookeeper之分布式队列

Zookeeper学习:Zookeeper应用场景之分布式队列 1. 分布式队列介绍 分布式队列可以简单分为两大类∶一种是常规的FIFO先入先出队列模型,还有一种是 等待队列元素聚集后统一安排处理执行的Barrier模型。 2. FIFO先入先出 FIFO(First Input First Output,先入先出),FIFO队列是一种非常典型且应用广泛的按序执行的队列模型∶先进入队列的请求操作先完成后,才会开始处理后面的请求。 使用ZooKeeper实现FIFO队列,和之前提到的共享锁的实现非常类似。FIFO队列就类似于一个全写的共享锁模型,大体的设计思路其实非常简单 阅读详情

设计:

使用路径为/queue的znode下的节点表示队列中的元素。/queue下的节点都是顺序持久化的znode。这些znode名字的后缀数字表示了对应队列元素在队列中的位置。Znode名字后缀数字越小,对应队列元素在队列中的位置越靠前。

offer方法:

在/queue下面创建一个顺序znode。因为znode的后缀数字是/queue下面现有znode最大后缀数字加1,所有znode对应的队列元素处于队尾

    /**
     * 向队列提交数据
     *
     * @param element 提交的数据
     * @return
     * @throws Exception
     */
    public boolean offer(T element) throws Exception {

        String nodeFullPath = root.concat("/").concat(Node_NAME);
        try {
            // 创建持久的顺序节点
            zkClient.createPersistentSequential(nodeFullPath, element);
        } catch (ZkNoNodeException e) {
            zkClient.createPersistent(root);
            offer(element);
        } catch (Exception e) {
            throw ExceptionUtil.convertToRuntimeException(e);
        }
        return true;
    }

poll方法:

/**
     * 从队列获取数据
     *
     * @return
     * @throws Exception
     */
    public T poll() throws Exception {
        try {

            List<String> list = zkClient.getChildren(root);
            if (list.size() == 0) {
                return null;
            }

            // 排序队列 根据名称由小到大
            Collections.sort(list, new Comparator<String>() {
                public int compare(String lhs, String rhs) {
                    return getNodeNumber(lhs, Node_NAME).compareTo(getNodeNumber(rhs, Node_NAME));
                }
            });

            for (String nodeName : list) {

                String nodeFullPath = root.concat("/").concat(nodeName);
                try {
                    T node = (T) zkClient.readData(nodeFullPath);
                    zkClient.delete(nodeFullPath);
                    return node;
                } catch (ZkNoNodeException e) {
                    // 其他客户端消费了 继续循环
                }
            }
            return null;

        } catch (Exception e) {
            throw ExceptionUtil.convertToRuntimeException(e);
        }

    }

注意:T node = (T) zkClient.readData(nodeFullPath);的成功,并不代表删除的成功,原因是该队列元素可能会被其他的用户出队。

总体的代码:

package com.queue.model;


import java.io.Serializable;

public class User implements Serializable {

    private static final long serialVersionUID = 7726840211952830151L;

    String name;
    String id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", id='" + id + '\'' +
                '}';
    }

}
package com.queue;


import org.I0Itec.zkclient.ExceptionUtil;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkNoNodeException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * 简单的分布式队列
 *
 * @author jerome_s@qq.com
 * @date 2016/8/30 20:19
 */
public class DistributedSimpleQueue<T> {

    protected final ZkClient zkClient;

    /**
     * 根节点路径
     */
    protected final String root;

    /**
     * 顺序节点的前缀
     */
    protected static final String Node_NAME = "qn_";


    public DistributedSimpleQueue(ZkClient zkClient, String root) {
        this.zkClient = zkClient;
        this.root = root;
    }

    /**
     * 获取队列的大小
     *
     * @return
     */
    public int getQueueSize() {
        return zkClient.getChildren(root).size();
    }

    /**
     * 向队列提交数据
     *
     * @param element 提交的数据
     * @return
     * @throws Exception
     */
    public boolean offer(T element) throws Exception {

        String nodeFullPath = root.concat("/").concat(Node_NAME);
        try {
            // 创建持久的顺序节点
            zkClient.createPersistentSequential(nodeFullPath, element);
        } catch (ZkNoNodeException e) {
            zkClient.createPersistent(root);
            offer(element);
        } catch (Exception e) {
            throw ExceptionUtil.convertToRuntimeException(e);
        }
        return true;
    }

    public List<T> element() {
        List<String> list = zkClient.getChildren(root);
        // 排序队列 根据名称由小到大
        Collections.sort(list, new Comparator<String>() {
            public int compare(String lhs, String rhs) {
                return getNodeNumber(lhs, Node_NAME).compareTo(getNodeNumber(rhs, Node_NAME));
            }
        });
        List<T> res = new ArrayList<>();
        try {
            for (String nodeName : list) {
                String nodeFullPath = root.concat("/").concat(nodeName);
                res.add((T)zkClient.readData(nodeFullPath));
            }
        } catch (ZkNoNodeException e) {
            // 其他客户端消费了 继续循环
        }
        return res;
    }


    /**
     * 从队列获取数据
     *
     * @return
     * @throws Exception
     */
    public T poll() throws Exception {
        try {

            List<String> list = zkClient.getChildren(root);
            if (list.size() == 0) {
                return null;
            }

            // 排序队列 根据名称由小到大
            Collections.sort(list, new Comparator<String>() {
                public int compare(String lhs, String rhs) {
                    return getNodeNumber(lhs, Node_NAME).compareTo(getNodeNumber(rhs, Node_NAME));
                }
            });

            for (String nodeName : list) {

                String nodeFullPath = root.concat("/").concat(nodeName);
                try {
                    T node = (T) zkClient.readData(nodeFullPath);
                    zkClient.delete(nodeFullPath);
                    return node;
                } catch (ZkNoNodeException e) {
                    // 其他客户端消费了 继续循环
                }
            }
            return null;

        } catch (Exception e) {
            throw ExceptionUtil.convertToRuntimeException(e);
        }

    }

    private String getNodeNumber(String str, String nodeName) {
        int index = str.lastIndexOf(nodeName);
        if (index >= 0) {
            index += Node_NAME.length();
            return index <= str.length() ? str.substring(index) : "";
        }
        return str;
    }

}

测试用例:

package com.queue;

import com.queue.model.User;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;

import java.util.List;

/**
 * 测试简单的分布式队列
 *
 * @author jerome_s@qq.com
 * @date 2016/8/30 19:48
 */
public class TestDistributedSimpleQueue {

    public static void main(String[] args) {

        ZkClient zkClient = new ZkClient("192.168.40.138:2181", 10000, 500000, new SerializableSerializer());
        DistributedSimpleQueue<User> queue = new DistributedSimpleQueue<>(zkClient, "/queue");

        User user1 = new User();
        user1.setId("1");
        user1.setName("jerome1");

        User user2 = new User();
        user2.setId("2");
        user2.setName("jerome2");

        try {
            queue.offer(user1);
            queue.offer(user2);
            System.out.println("queue.offer end!");

            List<User> element = queue.element();
            System.out.println(element.toString());

            User u1 = queue.poll();
            User u2 = queue.poll();
            System.out.println("queue.poll() u1 = " + u1.toString());
            System.out.println("queue.poll() u2 = " + u2.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /* console:
    queue.offer end!
    queue.poll() u1 = User{name='jerome1', id='1'}
    queue.poll() u2 = User{name='jerome2', id='2'}
    */
}

运行结果:

Zookeeper场景实践:(8) 分布式队列 按照ZooKeeper典型应用场景一览里的说法,分布式队列有两种,一种是常规的先进先出队列,另一种是要等到队列成员聚齐之后的才统一按序执行。 第二种队列可以先建立一个/queue,赋值为n,表达队列的大小。然后每个队列成员加入时,就判断是否达到队列要求的大小,如果是可以进行下一步动作,否则继续等待队列成员的加入。比较典型的情况是,当一个大的任务可能需要很多的子任务完成才能开始进行。 阅读详情

相关推荐

001:InVEST学习——产水/水源涵养

InVEST产水模块介绍 前言 (一些碎碎念着急的可以忽略)最开始做inVEST模型是2020年中,应该说对这个软件有很特殊的感情,之前一直想出一个教程,但是因为事情多加上拖延加上懒就耽搁了,事实证明东西不用就确实荒废了,现在面对当初自己做的东西顶多也就能想起一些思路,很多细节都忘了,所以这个教程也相当于是一个备忘录吧。 ...

Victoriaac的博客 2万+

分布式项目中 如何保证线程安全问题?-------ZooKeeper

前沿: 上篇文章我们聊到了在解决分布式项目中线程安全问题,提到解决方案还有其他的,那么在此提出 基于 zookeeper 解决分布式项目中的线程安全问题 也是目前市面上比较流行的。做为一个高级开发工程师也是必须要学习的。 ZooKeeper是什么东西? 是协调多个分布式进程之间的活动的。 主要应用在分布式系统中 保证跨jvm虚拟机之间的线程安全。 ZooKeeper是怎么在分布式应用使用的? ...

weixin_56310628的博客 6028

opencv 常用函数总结

本文是一份OpenCV图像处理的常用函数总结,详细介绍了图像的读入、显示、保存、像素处理、图像属性获取、基础操作、阈值处理、图像平滑、形态学转换以及直方图处理等关键技术。文章通过代码示例和参数说明,帮助读者快速掌握OpenCV在图像处理领域的应用。

weixin_44063529的博客 1600

ookeeper入门到实战 (五):ZkClient开源客户端节点操作,监听子节点,监听节点数据变化

这里写自定义目录标题欢迎使用Markdown编辑器新的改变1. ZkClient 开源客户端1.1 连接zookeeper,创建会话1.2 创建节点1.3 删除节点1.4 监听子节点变化1.4 监听节点数据变化功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchar

不吃姜的博客 1608

华为CCA架构软件栈VehicleStack解析:3层服务化设计与AOS/VOS双核OS

本文深入解析华为CCA架构下的VehicleStack软件平台,重点介绍其三层服务化设计(硬件抽象层、服务框架层、应用层)与AOS/VOS双核操作系统协同机制。该架构通过计算与通信的深度融合,推动汽车电子电气架构向集中式发展,为智能汽车提供灵活、高效的软件定义汽车解决方案。

weixin_33491377的博客 324

Arcgis中的模型构建器技术之按属性批量建库并对应输出

好久没更新了,之前我们已经介绍过四至点提取模型,前两天有同事问怎么样按属性批量建数据库并对应输出相关图斑。比如将一个县的永农数据按乡镇建立数据库并将对应乡镇的永农数据输出到相应的数据库里。今天就介绍一下相关的模型构建过程。

weixin_44671081的博客 518

Zookeeper 客户端命令行基础操作

通过上述步骤,您可以验证 Zookeeper 中设置的 ACL 是否生效。不同类型的 ACL 有不同的认证和访问方式,确保在实际应用中正确配置和验证 ACL,以保护 ZNode 数据的安全性。

欢迎来到我的技术分享博客!这里将带你深入了解AI技术、Java架构设计、系统开发与优化等前沿技术内容。我专注于从实战经验 1876

51单片机 驱动有源/无源蜂鸣器+Proteus仿真

51单片机 驱动有源/无源蜂鸣器+Proteus仿真 相关篇《51单片机 Proteus仿真有源蜂鸣器始终不响原因及解决方法》 电路搭建 采用NPN管驱动有源蜂鸣器电路 采用PNP管驱动有源蜂鸣器电路 采用PNP管驱动无源蜂鸣器 采用NPN管驱动无源蜂鸣器 Proteus元器件列表 实例代码 /************************************************************************************* * 实验现象:下载程序

perseverance51博客 2万+

Zookeeper使用详解

1、Zookeeper是什么?用来干什么? Zookeeper中文动物管理员,Zookeeper是java语言开发的,它主要用在分布式系统架构中。官方文档上这么解释Zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。我们在分布式系统架构中主要用来实现如下功能: 配制中心; 分布式锁; 服务注册; 发布订阅(消息中间件); Master选举

weixin_36741151的博客 1757

华为OD机试:查找接口成功率最优时间段 (C/C++/Py/Java/JS/GO)

华为OD机试双机位C卷 查找接口成功率最优时间段,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。

qq_45776114的博客 4687

【数据集】全球首个10米分辨率精细分类土地覆盖数据集GLC_FCS10

【数据集】全球首个10米分辨率精细分类土地覆盖数据集GLC_FCS10

WW、forever的博客 1567

Zookeeper--(二)配置文件讲解、客户端使用

   Java操作zookeeper创建节点 创建子节点CreateMode.EPHEMETAL临时节点保证本次回话有效,本次会话结束临时节点消失,可以实现分布式事务锁        获取子节点   ...

superviser3000的博客 375

2、实时DSP编程技术及其应用

本文详细介绍了实时数字信号处理(DSP)技术及其应用,涵盖三种流行的浮点DSP处理器系列的特点、开发工具和优化方法。通过具体的应用实例,如语音压缩、音乐信号处理和雷达信号处理,展示了如何在实际项目中应用这些技术,帮助工程师提高系统的性能和可靠性。

cicd6pipeline的博客 840

Zookeeper的分布式队列实践

1.背景介绍 Zookeeper的分布式队列实践 作者:禅与计算机程序设计艺术 1. 背景介绍 1.1. 什么是分布式队列 分布式队列是一种基于分布式系统的消息中间件,它可以在多个节点上维护一个先进先出的队列,并支持多 producer 和 multiple consumer 的场景。分布式队列通常被用于解耦系统、流量控制、任务调度等场景。 1.2. 为什么选择 Zookeeper ...

AI天才研究院 829

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Zookeeper(61)Zookeeper如何实现分布式队列?

添加依赖:在项目中添加 Zookeeper 的依赖。实现 ZookeeperClient 类:负责连接和关闭 Zookeeper 客户端,并提供获取ZooKeeper实例的方法。实现 DistributedQueue 类:负责实现分布式队列的逻辑,包括入队和出队操作。测试分布式队列:通过运行多个实例来测试分布式队列的功能。通过以上方法,可以在 Zookeeper 中实现分布式队列,确保其高效稳定地运行。根据实际情况和需求,选择适合你的实现方法并进行实施。

qq_43012298的博客 1043

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

zookeeper 实现分布式队列

zookeeper是一种高性能,可扩展的服务。其本身提供了一致性保证,特点如下:(1)顺序一致性:客户端的更新顺序与它们被发送的顺序一致。(2)原子性:更新操作要么成功,要么失败,没有第三种结果。(3)单系统镜像:无论客户端连接到哪一个服务器,他都将看到相同的zookeeper视图。(4)可靠性:一旦一个更新操作被应用,那么在客户端再次更新之前,其值不会再改变。zookeeper实现分布式队列基于

惜暮 2625

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Zookeeper实现分布式队列

常见的消息队列有:RabbitMQ,RocketMQ,Kafka等。Zookeeper作为一个分布式的小文件管理系统,同样能实现简单的队列功能。Zookeeper不适合存储大数据量存储,官方并不推荐作为队列使用,但由于实现简单,集群搭建较为便利,因此在一些吞吐量不高的小型系统中还是比较好用的。 本案例设立一个订单生产者,两个订单消费者,订单生产者将下单信息存入Zookeeper队列,两个消费者监听队列,共同消费订单。以此模拟下单业务,使用队列来提升订单系统的可用性及处理订单的吞吐量。 1.项目依赖 在

jockerwu的博客 2291

Zookeeper分布式队列实战

ZooKeeper实现队列步骤1.创建队列根节点:在Zookeeper中创建一个持久节点,用作队列的根节点。所有队列元素的节点将放在这个根节点下。2.实现入队操作:当需要将一个元素添加到队列时,可以在队列的根节点下创建一个临时有序节点。节点的数据可以包含队列元素的信息。3.实现出队操作:当需要从队列中取出一个元素时,先获取根节点下的所有子节点。再找到具有最小序号的子节点,获取该节点的数据,删除该节点,然后返回节点的数据。

尽力而为! 1274

ZooKeeper实现分布式队列Queue

http://f.dataguru.cn/portal.php?mod=view&aid=3299

tycoon的专栏 471

【从入门到放弃-ZooKeeper】ZooKeeper实战-分布式队列

前言 上文【从入门到放弃-ZooKeeper】ZooKeeper入门中,我们学习了ZooKeeper的简单安装和cli使用。 接下来我们开始基于java API的实战编程。本文先来写一个分布式队列的代码实现。 设计 我们来写一个先进先出的分布式无界公平队列。参考我们之前介绍的【从入门到放弃-Java】并发编程-JUC-ConcurrentLinkedQueue和【从入门到放弃-Java】并发...

阿里云云栖号 2010

zookeeper实现分布式队列

zookeeper实现分布式队列 利用zookeeper的有序节点和节点一旦被删除,其他连接就不能重复删除的特性实现一个非常简单的分布式队列,说实话,我觉得用zookeeper实习分布式队列并不合适,而且我这里实现的也是最简单的,效率也不高 实现细节,利用create -s /queue/q_创建有序节点,这样数据就放到队列了,当然这一步是使用zookeeper的客户端Curator实现的,然后取...

mjlfto的博客 628

深入浅出理解基于 Kafka 和 ZooKeeper 的分布式消息队列

消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题。实现高性能,高可用,可伸缩和最终一致性架构,是大型分布式系统不可缺少的中间件。 消息队列在电商系统、消息通讯、日志收集等应用中扮演着关键作用,以阿里为例,其研发的消息队列(MQ)服务于阿里集团超过11年,在历次天猫双十一活动中支撑了万亿级的数据洪峰,为大规模交易提供了有力保障。 目前在生产环境,使用较多的消息队列有...

GitChat 1万+

zookeeper分布式队列

一、简介 在此介绍基于zookeeper实现的分布式队列。包括类似jdk队列的简单队列SimpleDistributedQueue、 分布式队列DistributedQueue、带Id的分布式队列DistributedIdQueue、带优先级的分布式队列DistributedPriorityQueue。 二、添加maven依赖 org.apache.zookeeper

panda-star的博客 1221

Zookeeper与分布式消息队列的案例

1.背景介绍 1. 背景介绍 分布式系统中,分布式消息队列是一种常见的异步通信方式,它可以解耦系统之间的通信,提高系统的可扩展性和可靠性。Zookeeper是一个开源的分布式协调服务,它可以用于实现分布式消息队列的一些功能,如集中式配置管理、集群管理、分布式同步等。 在本文中,我们将从以下几个方面进行探讨: 分布式消息队列的核心概念与联系 Zookeeper的核心算法原理和具体操作步骤 ...

AI天才研究院 1143
上一篇: 高并发之-死锁
下一篇: idea连接mysql报错
给自己加加油
博客等级 码龄8年 302粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值