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的原子操作
以上純屬個人見解,如有問題請聯本人!