1.声明
当前内容主要用于本人学习和复习,当前内容为使用Zookeeper实现队列
当前内容思想来源:Queue
2.分析成图像
- 所谓的分布式队列,使用zookeeper来实现
- 就是在queues下面创建一个临时的序列的queue-节点
- 然后向其中放入数即可
- 队列消息拉取者,拉取第一队列的第一消息,消费完毕后删除掉
3.使用代码实现
/**
* @description 利用zookeeper实现分布式队列
* @author hy
* @date 2020-06-07
*/
public class ZookeeperQueue {
// 1. 首先创建队列节点
// 2.然后创建queue-开头的序列的临时的节点
// 3.每次获取第一个节点数据进行消费
static Object monitor =new Object();
public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
ZooKeeper zk =new ZooKeeper("192.168.1.105:2181", 10000, null);
String queuesNode="/queues";
Stat exists = zk.exists(queuesNode,null);
if(exists==null) {
zk.create(queuesNode, new byte[0], ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
exists = zk.exists(queuesNode,null);
}
while(true) {
synchronized (monitor) {
// 判断当前的节点队列是否具有子节点
List<String> queues = zk.getChildren(queuesNode, false);
// 如果没有数据则需要等待并监视队列
if(queues.isEmpty()) {
System.out.println("queues节点中没有数据进入等待。。。。");
// 没有数据就开始监控当前的节点数据
queues = zk.getChildren(queuesNode,new DefaultQueueWatcher());
monitor.wait();
}else{
// 否则认为具有数据并开始执行开始消费
String que = queues.get(0);
String que_node = queuesNode+"/"+que;
Stat stat = zk.exists(que_node, null);
String data = new String (zk.getData(que_node, null,stat),"utf-8");
System.out.println("开始消费数据===>"+data);
System.out.println("消费数据====>【完毕】");
zk.delete(que_node, stat.getVersion());
Thread.sleep(1000l);// 模拟网络延迟
}
}
}
}
static class DefaultQueueWatcher implements Watcher{
@Override
public void process(WatchedEvent event) {
System.out.println("触发监控。。。。");
synchronized (monitor) {
// 说明当前的queues节点发生变化了
monitor.notify();
}
}
}
}
这里只给出消费者
4.测试启动
1.启动队列消费者
2.在linux中使用zkCli来发布数据
测试成功
5.总结
1.使用分布式队列的时候,就是通过监控来实现的,利用zookeeper的原子操作
以上纯属个人见解,如有问题请联本人!