基于zookeeper的分布式Queue

Zookeeper教程(一):快速开始以及结合java实现分布式Barrier和Queue 前言:现在网上对于详细系统的Zookeeper教程较少,于是自己想着来写一个,其实也是结合官方英文文档进行学习,计划将覆盖Zookeeper配置使用,结合java实现一些案例,源码解读,以及最终与dubbo等进行结合部署一个分布式系统。所有相关的代码都会上传到git,需要的可以下载一下。 这篇教程最后将会结合ZooKeeper讲讲分布式Barrier和分布式队列 阅读详情
       原理:ZooKeeper通过一个Node来维护Queue的实体,用其children来存储Queue的内容,并且ZooKeeper的create方法中提供了顺序递增的模式,会自动地在name后面加上一个递增的数字来插入新元素。可以用其children来构建一个queue的数据结构,offer的时候使用create,take的时候按照children的顺序删除第一个即可。ZooKeeper保障了各个server上数据是一致的,因此也就实现了一个分布式Queue。代码如下:
package com.zero.zookeeper;

import java.io.IOException;
import java.util.List;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.NoNodeException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.EventType;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class DistributedQueue {
	private static DistributedQueue instance = new DistributedQueue();
	private static ZooKeeper zookeeper;
	private String dir = "/distributedQueue";
	private String prefix = "queueIndex";

	private DistributedQueue() {
		if (null != instance) {
			throw new AssertionError();
		}
		try {
			zookeeper = new ZooKeeper("localhost:2181", 10000, null);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static DistributedQueue getInstanceQueue() {
		return instance;
	}

	public byte[] take() throws KeeperException, InterruptedException {
		return take(Long.MAX_VALUE);
	}

	public byte[] take(long time) throws KeeperException, InterruptedException {
		while (true) {
			LatchChildWatcher childWatcher = new LatchChildWatcher();
			TreeMap<Long, String> orderedChildren;
			try {
				orderedChildren = (TreeMap<Long, String>) orderChildren(childWatcher);
			} catch (KeeperException.NoNodeException e) {
				zookeeper.create(dir, new byte[0], Ids.OPEN_ACL_UNSAFE,
						CreateMode.PERSISTENT);
				continue;
			}
			if (orderedChildren.size() == 0) {
				// 等待时间超时,则返回 false,否则返回 true
				boolean idNotified = childWatcher.await(time);
				if (idNotified) {
					continue;
				}
				return null;
			}
			for (String childNode : orderedChildren.values()) {
				try {
					byte[] data = zookeeper.getData(childNode, false, null);
					zookeeper.delete(childNode, -1);// 也会触发NodeChildrenChanged
					return data;
				} catch (KeeperException.NoNodeException e) {
				}
			}
		}
	}

	/**
	 * 将数据插入队列中
	 * 
	 * @param data
	 * @return
	 * @throws KeeperException
	 * @throws InterruptedException
	 */
	public boolean offer(byte[] data) throws KeeperException,
			InterruptedException {
		for (;;) {
			try {
				zookeeper.create(dir + "/" + prefix, data, Ids.OPEN_ACL_UNSAFE,
						CreateMode.PERSISTENT_SEQUENTIAL);
				return true;
			} catch (KeeperException.NoNodeException e) {
				zookeeper.create(dir, new byte[0], Ids.OPEN_ACL_UNSAFE,
						CreateMode.PERSISTENT);
			}
		}
	}

	public static void close() {
		try {
			zookeeper.close();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private TreeMap<Long, String> orderChildren(Watcher watcher)
			throws NoNodeException {
		Stat stat = null;
		try {
			stat = zookeeper.exists(dir, true);// 这里如果加watcher,会监控dir的NodeCreated与NodeDeleted
		} catch (KeeperException | InterruptedException e) {
			e.printStackTrace();
		}
		if (stat == null) {
			throw new KeeperException.NoNodeException();
		}

		List<String> childernList = null;
		try {
			childernList = zookeeper.getChildren(dir, watcher);// 这里如果加watcher,会监控dir的NodeChildrenChanged
		} catch (KeeperException | InterruptedException e) {
			e.printStackTrace();
		}
		TreeMap<Long, String> orderedChildren = new TreeMap<Long, String>();
		for (String childNode : childernList) {
			try {
				String childNodePath = dir + "/" + childNode;
				Stat s = zookeeper.exists(childNodePath, true);
				if (s != null) {// 多线程下可能zookeeper.getChildren后childNode被删除
					orderedChildren.put(s.getCzxid(), childNodePath);
				}
			} catch (KeeperException | InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return orderedChildren;
	}

	/**
	 * Watcher是一次性,只会触发一次process,除非多次设置zookeeper.getChildren(dir, watcher)
	 * 
	 * @author zero
	 *
	 */
	private class LatchChildWatcher implements Watcher {
		private volatile boolean isNotify = false;

		@Override
		public void process(WatchedEvent event) {
			if (EventType.NodeChildrenChanged == event.getType()) {
				isNotify = true;
			}
		}

		public boolean await(long time) throws InterruptedException {
			long end = System.currentTimeMillis() + time * 1000;
			for (;;) {
				TimeUnit.MILLISECONDS.sleep(100);
				if (isNotify) {
					return true;
				} else if (System.currentTimeMillis() >= end) {
					return false;
				}
			}
		}
	}
}









ZooKeeper实现分布式队列Queue 现在硬件越来越便宜,一台非品牌服务器,2颗24核CPU,配48G内存,2T的硬盘,已经降到2万块人民币以下了。这种配置如果简单地放几个web应用,显然是奢侈的浪费。就算是用来实现单节点的hadoop,对计算资源浪费也是非常高的。对于这么高性能的计算机,如何有效利用计算资源,就成为成本控制的一项重要议题了。通过虚拟化技术,我们可以将一台服务器,拆分成12台VPS,每台2核CPU,4G内存,40G硬盘,并且支持资源重新分配。多么伟大的技术啊!现在我们有了12个节点的hadoop集群,让Hadoop跑在云端,让世界加速。ZooKeeper是一个分步式的协作系统,何为协作,ZooKeeper价值又有何 立即下载

相关推荐

STM32铅酸蓄电池内阻测试仪的交流阻抗测量与数据采集优化

本文深入探讨了基于STM32的铅酸蓄电池内阻测试仪设计,重点解析了交流阻抗测量原理与数据采集优化方案。通过采用1kHz交流小信号注入和数字相敏检波技术,实现对电池欧姆内阻的无损精准测量,并详细介绍了硬件前端调理、ADC过采样及系统标定等关键优化手段,有效提升了测量精度与稳定性。

weixin_29168393的博客 487

Redisson_队列Queue

分布式队列Queue还可以分为双端队列Deque、阻塞队列Blocking Queue、有界阻塞队列(Bounded Blocking Queue)、阻塞双端队列(Blocking Deque)、阻塞公平队列(Blocking Fair Queue)、阻塞公平双端队列(Blocking Fair Deque)。 不管是哪种队列,底层都是借助”基于发布—订阅式的主题“来实现的。

看表该写博客了 2289

爬取百度图片

最开始,我们想要爬取图片,首先需要打开百度图库,然后在搜索栏中输入自己想要的图片(比如说壁纸)。接着右键检查,点击网络:起初可能没有名称信息,刷新界面就可以了。打开信息,查看标头内容可以看到请求URL为:复制这串URL,然后在浏览器中打开这个就是我们搜索的壁纸图片的网页内容。怎么找到图片的URL呢?在上述内容中,找到data,可以发现里面每隔一个aiEditData,下面代码的形式是一样的,就相当于一张图片。

weixin_54143563的博客 1939

Zookeeper实现分布式队列(非阻塞式)

分布式环境下,一个类似单进程队列的组件,用来实现跨进程、跨主机、跨网络的数据共享和数据传递,zookeeper可以通过顺序节点实现分布分布式队列.

qq_49150614的博客 556

万象RK3506-EG1800网关使用说明

摘要:HD-RK3506-EG1800是一款高性能工业物联网边缘计算网关,支持Buildroot和Ubuntu双系统。文档详细介绍了网关的网络配置(包括ETH0/ETH1的静态IP设置、WiFi连接)、时钟同步、HSL软件安装配置(含开机自启动服务)、系统日志优化以及刷机操作指南(Loader/Maskrom模式)。特别提供了基于lighttpd的网页管理方案,通过HTML界面实现网络参数可视化配置,包含身份验证、实时状态显示和表单提交功能。网关默认ETH0固定IP为192.168.1.10,提供完整的CL

tian_jiangnan的博客 174

随机变量序列 收敛 检验 matlab,利用MATLAB验证样条插值的收敛性

问题提出多项式插值是不收敛的,即插值的节点多,效果不一定就好。对样条函数插值又如何呢?理论上证明样条插值的收敛性是比较困难的,但通过本实验可以验证这一理论结果。.实验内容请按一定的规则分别选择等距或者非等距的插值节点,并不断增加插值节点的个数。考虑实验2.1中的函数或选择其他你有兴趣的函数。(中函数)。实验要求(1)随节点个数增加,比较被逼近函数和样条插值函数误差的变化情况。分析所得结果并与拉格朗...

weixin_30895121的博客 4735

Zookeeper实现分布式队列

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

jockerwu的博客 2291

STM32驱动WS2812B实现音乐频谱可视化系统

本文详细介绍了基于STM32驱动WS2812B灯带实现音乐频谱可视化系统的设计与实现。通过FFT算法实时分析音频信号,将频谱映射到炫彩灯光控制系统,结合PWM和DMA技术实现低延迟响应。系统支持多模式切换和动态亮度调节,适用于创意灯光秀和智能家居场景。

weixin_29171129的博客 302

基于zookeeper的分布式队列

本篇博客讨论如何基于zookeeper来设计一个分布式队列。 分布式队列一般需要考虑两点: - 任务如何进入队列 - 如何保证每个任务只能被一个消费者消费 首先,zookeeper本身就提供了对队列的支持,不过官方文档对这个的描述非常简单 Distributed queues are a common data structure. To implement a distr...

朱登凯的专栏 2485

图形学常见概念小结

前言:本文记录《unity shader入门精要》和openGL相关学习过程中一些学习要点; 文章目录PBR流程渲染管线细分着色器的底层实现,应用原理常见的色调映射算法openGl和Direct X的区别PBR流程和URP渲染管线Camera loop(剔除)MVP矩阵变换光线追踪前向渲染和延迟渲染shader和材质的区别bloom原理后处理的理解高斯模糊实现原理图像处理中的边缘检测算子 PBR流程 小结:一套基于自然界微平面理论、能量守恒、菲涅尔反射、线性空间等的科学理论所实现的基于物理的渲染系统,包含一

小谁的博客 1163

泰凌微8258入门教程 环境篇④——开发板+烧录器 8258mesh新手套件购买

工欲善其事,必先利其器。 淘宝链接:https://item.taobao.com/item.htm?

4128

Zookeeper教程:快速开始以及结合java实现分布式Barrier和Queue

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34223655的博客 100

网络攻防——kali操作系统基本使用

主要介绍如何搭建kali虚拟机,然后介绍了一个简单的攻击方法,切记,网络恶意攻击属于违法行为

weixin_46560512的博客 2万+
上一篇: DBCP连接池配置参数
下一篇: sed命令
zero__007
博客等级 码龄12年 326粉丝 247原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值