基於zookeeper的分散式佇列之FIFO佇列
阿新 • • 發佈:2018-11-02
2、FIFO佇列
fifo就是資料結構中的,first in first out的意思,就是先進先出,這是佇列的特點,那麼結合佇列的特點如何通過zookeeper來實現這個特點了,看圖:
1、入佇列,我們可以在/queue節點下,不同的客戶端建立臨時有序節點,通過zookeeper的znode的型別我們知道,有序節點建立時會帶編號的,且這個編號的有序遞增的,就是為佇列的先進建立的條件
2、出佇列,如何先出佇列呢,要獲取到/queue節點下的所有子節點,然後獲取子節點上的數字,對數字進行排序,然後取得到數字最小的節點,我們把這個節點pop出佇列就可以了。
OK,程式碼搞起~~~~~
核心程式碼:
public class FIFOQueue<T> { protected final ZkClient zkClient; protected final String root; // /queue/n_00000000010 protected static final String Node_name = "n_"; public FIFOQueue(ZkClient zkClient, String root) { this.zkClient = zkClient; this.root = root; } public int size() { return zkClient.getChildren(root).size(); } public boolean isEmpty() { return zkClient.getChildren(root).size() == 0; } public boolean push(T element) throws Exception { String path = root.concat("/").concat(Node_name); try { zkClient.createEphemeralSequential(path, element); }catch (ZkNoNodeException e) { zkClient.createPersistent(root); push(element); }catch (Exception e) { throw ExceptionUtil.convertToRuntimeException(e); } return true; } //拿到編號最小的,把最小資料刪除 public T poll() throws Exception { try { List<String> childrens = zkClient.getChildren(root); if(childrens.size() == 0) { return null; } Collections.sort(childrens, new Comparator<String>() { @Override public int compare(String o1, String o2) { return getNodeNumber(o1,Node_name).compareTo (getNodeNumber(o2,Node_name)); } }); //n_0000000001 String litterNode = childrens.get(0); String fullPath = root.concat("/").concat(litterNode); T data = (T)zkClient.readData(fullPath); zkClient.delete(fullPath); return data; } 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; } }
如是,zookeeper的FIFO佇列就完成了~~~