使用 Reactor 進行反應式編程進行數據分批處理

一、前言

最近在做一個項目,獲取JDK8 Stream對象後,想要批量消費,不想自己寫個集合來做批量處理。而反應式編程實現比如rxjava或者reactor是有豐富的流操作符,所以調研了下如何把JDK8 Stream轉換爲反應式流。

 

二、批量消費

有時候場景需要我們批量消費以便提高執行效率,比如對應同一個表的插入操作,批量插入的效率比單條逐個插入效率要好很多。那麼對應給定的一個數據源,如何聚合數據爲批量那?當數據源是一個內存list時候,最簡單方法如下:

	public static void main(String[] args) {
        // 模擬數據, 創建list
        List<Integer> personList = new ArrayList<>();
        for (int i = 0; i < 98; ++i) {
            personList.add(i);
        }

        // 切分處理
        List<List<Integer>> list = Lists.partition(personList, 20);
        list.stream().forEach(
            tempList -> System.out.println(JSON.toJSONString(tempList))
        );
	}

使用Google guava包裏面的Lists.partition函數把list切分爲一個個最多包含20個元素的list列表,並打印輸出。

如果我們想要的是從這些流中每次讀取limit條記錄,然後批量處理這limit條記錄,這樣內存中每次只會存在limit條記錄。這時由於JDK Stream不支持Buffer操作,我們需要自己實現,實現代碼大概如下:

    public static void main(String[] args) {
        // 模擬數據, 創建list
        List<Integer> personList = new ArrayList<>();
        for (int i = 0; i < 98; ++i) {
            personList.add(i);
        }

        // 緩存列表
        List<Integer> mergeList = new ArrayList<>();

        int limit = 20;
        // 循環獲取元素並緩存
        personList.stream().forEach(e -> {
            if (mergeList.size() >= limit) {
                System.out.println(JSON.toJSONString(mergeList));
                mergeList.clear();
            }
            mergeList.add(e);
        });
        // 退出後,補漏處理
        if (mergeList.size() > 0) {
            System.out.println(JSON.toJSONString(mergeList));
        }
    }

如上代碼在Stream中迭代元素時,我們把元素緩存到mergeList列表,每當mergeList有了20個元素,則處理一次。最後等流結束後,如果mergeList還有元素則需要補漏處理下。

如果不想實現上面繁瑣代碼,我們可以考慮吧JDK8 Stream切換到反應式實現框架比如Reactor或者Rxjava,因爲後者有豐富的流操作符。其中Reactor的一個實現是:

	public static void main(String[] args) {
        // 模擬數據, 創建list
        List<Integer> personList = new ArrayList<>();
        for (int i = 0; i < 98; ++i) {
            personList.add(i);
        }

        // 爲了使用buffer功能,轉換爲Reactor的流對象Flux
        Flux flux = Flux.fromStream(personList.stream());
        // 聚合消費
        flux.buffer(20).subscribe(e -> System.out.println(JSON.toJSONString(e)));
    }

如上代碼,我們使用Reactor框架的Flux.fromStream方法把JDKStream轉換爲Flux流對象,然後調用其buffer方法設置緩存20個元素消費一次,然後調用subscribe訂閱緩存流,並打印。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章