1. 程式人生 > >基於zookeeper的分散式佇列之FIFO佇列

基於zookeeper的分散式佇列之FIFO佇列

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佇列就完成了~~~