上一篇基于zk集群实现了分布式的id生成器,本篇继续基于zk集群进行场景实践,分布式的FIFO队列怎么用zk去做呢?直接上代码。
一、创建队列需要用到的bean
package com.coderman.zookeeper.clusterdemo.queuefifodemo;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/20 17:33
* FIFO队列的bean模型
*/
public class FIFOQueueBean {
/**
* 集群节点目录一级分组
*/
private String group;
/**
* 集群中的应用名称
*/
private String appName;
/**
* 功能模块名称
*/
private String busName;
/**
* 队列数据内容对象
*/
private Object dataObject;
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getBusName() {
return busName;
}
public void setBusName(String busName) {
this.busName = busName;
}
public Object getDataObject() {
return dataObject;
}
public void setDataObject(Object dataObject) {
this.dataObject = dataObject;
}
}
二、FIFO队列的基本操作接口
package com.coderman.zookeeper.clusterdemo.queuefifodemo;
import com.coderman.zookeeper.clusterdemo.ZKClientUtils;
import org.I0Itec.zkclient.ZkClient;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/21 15:08
* 定义一个先进先出队列的基本操作接口类
*/
public abstract class AbstractFIFOQueue {
private ZKClientUtils zkClientUtils = new ZKClientUtils();
ZkClient zkClient = zkClientUtils.getZkClient();
public AbstractFIFOQueue(FIFOQueueBean queueFIFOBean){
String nodePath = "/"+queueFIFOBean.getGroup()+"/"+queueFIFOBean.getAppName();
if(!zkClient.exists(nodePath)){
zkClient.createPersistent(nodePath,true);
}
}
/**
* 向队列中增加元素
* @param queueFIFOBean
*/
public abstract void produce(FIFOQueueBean queueFIFOBean);
/**
* 从队列中取数据
* @return
*/
public abstract Object consume(FIFOQueueBean queueFIFOBean);
/**
* 获取队列数据
* @return
*/
public abstract int getSize(FIFOQueueBean queueFIFOBean);
/**
* 获取节点信息
* @param queueFIFOBean
* @return
*/
public String getPersisteSequenceNode(FIFOQueueBean queueFIFOBean){
return "/"+queueFIFOBean.getGroup()+"/"+queueFIFOBean.getAppName()+"/"+queueFIFOBean.getBusName();
}
}
三、FIFO队列的实现类
package com.coderman.zookeeper.clusterdemo.queuefifodemo;
import com.coderman.zookeeper.clusterdemo.ZKClientUtils;
import org.I0Itec.zkclient.ZkClient;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/21 15:08
* 定义一个先进先出队列的基本操作接口类
*/
public abstract class AbstractFIFOQueue {
private ZKClientUtils zkClientUtils = new ZKClientUtils();
ZkClient zkClient = zkClientUtils.getZkClient();
public AbstractFIFOQueue(FIFOQueueBean queueFIFOBean){
String nodePath = "/"+queueFIFOBean.getGroup()+"/"+queueFIFOBean.getAppName();
if(!zkClient.exists(nodePath)){
zkClient.createPersistent(nodePath,true);
}
}
/**
* 向队列中增加元素
* @param queueFIFOBean
*/
public abstract void produce(FIFOQueueBean queueFIFOBean);
/**
* 从队列中取数据
* @return
*/
public abstract Object consume(FIFOQueueBean queueFIFOBean);
/**
* 获取队列数据
* @return
*/
public abstract int getSize(FIFOQueueBean queueFIFOBean);
/**
* 获取节点信息
* @param queueFIFOBean
* @return
*/
public String getPersisteSequenceNode(FIFOQueueBean queueFIFOBean){
return "/"+queueFIFOBean.getGroup()+"/"+queueFIFOBean.getAppName()+"/"+queueFIFOBean.getBusName();
}
}
四、main方法实践
package com.coderman.zookeeper.clusterdemo.queuefifodemo;
/**
* @description:
* @author: Fanchunshuai
* @time: 2020/2/22 11:08
*/
public class FIFOQueueDemo {
public static void main(String[] args) {
FIFOQueueBean fifoBean = new FIFOQueueBean();
fifoBean.setBusName("system-function-a");
fifoBean.setAppName("company-a");
fifoBean.setGroup("zkfifo");
fifoBean.setDataObject(new Long(10000L));
AbstractFIFOQueue fifoQueue = new FIFOQueue(fifoBean);
fifoQueue.produce(fifoBean);
fifoBean.setDataObject(new Long(10010L));
fifoQueue.produce(fifoBean);
fifoBean.setDataObject(new Long(10020L));
fifoQueue.produce(fifoBean);
fifoBean.setDataObject(new Long(10030L));
fifoQueue.produce(fifoBean);
fifoBean.setDataObject(new Long(10040L));
fifoQueue.produce(fifoBean);
int size = fifoQueue.getSize(fifoBean);
System.out.println("size = "+size);
Long num = (Long) fifoQueue.consume(fifoBean);
System.out.println("num = "+num);
Long num2 = (Long) fifoQueue.consume(fifoBean);
System.out.println("num = "+num2);
int size2 = fifoQueue.getSize(fifoBean);
System.out.println("size2 = "+size2);
}
}
总结:
zookeeper实现分布式的FIFO队列总结
1.zookeeper可以通过顺序节点的方式进行消息的存储,目录结构的组织
2.但是如果需要实现队列的更多api则需要更多接口
3.如果采用zk实现的FIFO在高并发需求下需要进行严格的测试
4.其他方案如redis可以参考Redis List的数据结构