AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

一起聊聊基于隊列實現多人同時導出 Excel

來源: 責編: 時間:2024-05-07 09:08:35 137觀看
導讀前言業務訴求:考慮到數據庫數據日漸增多,導出會有全量數據的導出,多人同時導出可以會對服務性能造成影響,導出涉及到mysql查詢的io操作,還涉及文件輸入、輸出流的io操作,所以對服務器的性能會影響比較大;結合以上原因,對導出

前言

業務訴求:考慮到數據庫數據日漸增多,導出會有全量數據的導出,多人同時導出可以會對服務性能造成影響,導出涉及到mysql查詢的io操作,還涉及文件輸入、輸出流的io操作,所以對服務器的性能會影響比較大;結合以上原因,對導出操作進行排隊;
剛開始拿到這個需求,第一時間想到就是需要維護一個FIFO先進先出的隊列,給定隊列一個固定size,在隊列里面的人進行排隊進行數據導出,導出完成后立馬出隊列,下一個排隊的人進行操作;還考慮到異步,可能還需要建個文件導出表,主要記錄文件的導出情況,文件的存放地址,用戶根據文件列表情況下載導出文件。

業務關系定義

分別是用戶、導出隊列、導出執行方法

  • ExportQueue: 維護一條定長隊列,可以獲取隊列里前后排隊的用戶,提供查詢,隊列如果已經滿了,其余的人需要進行等待
  • User信息: 排隊執行導出方法對應用戶;
  • Export類: 定義導出方法,異步執行,用戶可以通過導出頁面查看、下載,導出的文件;

圖片圖片95a28資訊網——每日最新資訊28at.com

具體代碼實現

ExportQueue隊列

package com.example.system.config;import com.example.system.api.domain.ExportUser;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Component;import java.util.LinkedList;@Slf4j@Componentpublic class ExportQueue {    private final int MAX_CAPACITY = 10; // 隊列最大容量    private LinkedList<ExportUser> queue; // 用戶隊列    public ExportQueue(LinkedList<ExportUser> queue) {        this.queue = new LinkedList<>();    }    /**     * 排隊隊列添加     * @param sysUser     */    public synchronized LinkedList<ExportUser> add(ExportUser sysUser) {        while (queue.size() >= MAX_CAPACITY) {            try {                log.info("當前排隊人已滿,請等待");                wait();            } catch (InterruptedException e) {                e.getMessage();            }        }        queue.add(sysUser);        log.info("目前導出隊列排隊人數:" + queue.size());        notifyAll();        return queue;    }    /**     * 獲取排隊隊列下一個人     * @return     */    public synchronized ExportUser getNextSysUser() {        while (queue.isEmpty()) {            try {                wait();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        ExportUser sysUser = queue.remove();        notifyAll(); //喚醒        return sysUser;    }}

AbstractExport導出類

引入EasyExcel百萬級別的導出功能95a28資訊網——每日最新資訊28at.com

package com.example.system.config;import cn.hutool.core.bean.BeanUtil;import cn.hutool.core.util.PageUtil;import com.alibaba.excel.EasyExcel;import com.alibaba.excel.ExcelWriter;import com.alibaba.excel.write.metadata.WriteSheet;import com.example.system.api.domain.ExportUser;import lombok.extern.slf4j.Slf4j;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.net.URLEncoder;import java.util.List;@Slf4jpublic abstract class AbstractExport<T, K> {    public abstract void export(ExportUser sysUser) throws InterruptedException;    /**     * 導出     *     * @param response 輸出流     * @param pageSize 每頁大小     * @param t        導出條件     * @param k        Excel內容實體類     * @param fileName 文件名稱     */    public void export(HttpServletResponse response, int pageSize, T t, Class<K> k, String fileName) throws Exception {        ExcelWriter writer = null;        try {            writer = getExcelWriter(response, fileName);            //查詢導出總條數            int total = this.countExport(t);            //頁數            int loopCount = PageUtil.totalPage(total, pageSize);            BeanUtil.setProperty(t, "pageSize", pageSize);            for (int i = 0; i < loopCount; i++) {                //開始頁                BeanUtil.setProperty(t, "pageNum", PageUtil.getStart(i + 1, pageSize));                //獲取Excel導出信息                List<K> kList = this.getExportDetail(t);                WriteSheet writeSheet = EasyExcel.writerSheet(fileName).head(k).build();                writer.write(kList, writeSheet);            }        } catch (Exception e) {            String msg = "導出" + fileName + "異常";            log.error(msg, e);            throw new Exception(msg + e);        } finally {            if (writer != null) {                writer.finish();            }        }    }    public com.alibaba.excel.ExcelWriter getExcelWriter(HttpServletResponse response, String fileName) throws IOException {        response.setContentType("application/vnd.ms-excel");        response.setCharacterEncoding("utf-8");        // 這里URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關系        String fileNameUtf = URLEncoder.encode(fileName, "UTF-8").replaceAll("http://+", "%20");        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameUtf + ".xlsx");        return EasyExcel.write(response.getOutputStream()).build();    }    /**     * (模版導出)     *     * @param t     * @param fileName     * @param response     */    public abstract void complexFillWithTable(T t, String fileName, HttpServletResponse response);    /**     * 查詢導出總條數     *     * @param t     * @return     */    public abstract int countExport(T t);    /**     * 查詢導出數據     *     * @param t     * @return     */    public abstract List<K> getExportDetail(T t);}

ExportImpl導出實現方法

package com.example.system.service.impl;import com.alibaba.excel.ExcelWriter;import com.example.system.api.domain.ExportUser;import com.example.system.config.AbstractExport;import com.example.system.config.ExportQueue;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.LinkedList;import java.util.List;@Service@Slf4jpublic class ExportImpl extends AbstractExport {    @Autowired    private ExportQueue exportQueue;    @Override    public void export(ExportUser sysUser) throws InterruptedException {        //導出        log.info("導出文件方法執行~~~~~~~~~");//        export(response,pageSize,t,k,fileName);        LinkedList<ExportUser> queue = exportQueue.add(sysUser);        log.info("導出隊列:" + queue);        //休眠時間稍微設置大點,模擬導出處理時間        Thread.sleep(20000);        //導出成功后移除當前導出用戶        ExportUser nextSysUser = exportQueue.getNextSysUser();        log.info("移除后獲取下一個排隊的用戶: " + nextSysUser.getUserName());    }    @Override    public void export(HttpServletResponse response, int pageSize, Object o, Class k, String fileName) throws Exception {        super.export(response, pageSize, o, k, fileName);    }    @Override    public ExcelWriter getExcelWriter(HttpServletResponse response, String fileName) throws IOException {        return super.getExcelWriter(response, fileName);    }    @Override    public void complexFillWithTable(Object o, String fileName, HttpServletResponse response) {    }    @Override    public int countExport(Object o) {        return 0;    }    @Override    public List getExportDetail(Object o) {        return null;    }}

測試controller

package com.example.system.controller;import com.example.system.api.domain.ExportUser;import com.example.system.api.domain.SysUser;import com.example.system.service.impl.ExportImpl;import lombok.SneakyThrows;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/export")@Slf4jpublic class ExportController {    @Autowired    private ExportImpl export;    @PostMapping("/exportFile")    public void exportFile() {            new Thread(new Runnable() {                @SneakyThrows                @Override                public void run() {                    Thread thread1 = Thread.currentThread();                    ExportUser sysUser =new ExportUser();                    sysUser.setUserName(thread1.getName());                    export.export(sysUser);                }            }).start();        }}

測試結果

通過請求測試方法,限制了我們導出隊列最大限制10次,隊列場長度超過10次則無法進行繼續提交;95a28資訊網——每日最新資訊28at.com

圖片圖片95a28資訊網——每日最新資訊28at.com

第一次請求和第二次請求,間隔10秒,第一個用戶導出完成后出列,下一個排隊用戶在隊列首位,再進行導出請求排在上一個用戶后面;95a28資訊網——每日最新資訊28at.com

圖片圖片95a28資訊網——每日最新資訊28at.com

總結

其余的還未實現,導出文件的表的設計、oss文件上傳、用戶導出文件下載,還有高并發的場景下會不會出現什么問題,這些都還沒有太考慮進去; 實現的方式應該挺多的,Redis的隊列應該也是可以的,這里僅僅提供一個實現思路;


95a28資訊網——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-86985-0.html一起聊聊基于隊列實現多人同時導出 Excel

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 新鮮出爐,截止到2024年5月最火爆的幾個前端開源庫

下一篇: 幻方發布全球最強MOE大模型! DeepSeek-V2

標簽:
  • 熱門焦點
  • 消息稱迪士尼要拍真人版《魔發奇緣》:女主可能也找黑人演員

    8月5日消息,迪士尼確實有點忙,忙著將不少動畫改成真人版,繼《美人魚》后,真人版《白雪公主》、《魔發奇緣》也在路上了。據外媒消息稱,迪士尼將打造真人版
  • Automa-通過連接塊來自動化你的瀏覽器

    1、前言通過瀏覽器插件可實現自動化腳本的錄制與編寫,具有代表性的工具就是:Selenium IDE、Katalon Recorder,對于簡單的業務來說可快速實現自動化的上手工作。Selenium IDEKat
  • JavaScript學習 -AES加密算法

    引言在當今數字化時代,前端應用程序扮演著重要角色,用戶的敏感數據經常在前端進行加密和解密操作。然而,這樣的操作在網絡傳輸和存儲中可能會受到惡意攻擊的威脅。為了確保數據
  • JVM優化:實戰OutOfMemoryError異常

    一、Java堆溢出堆內存中主要存放對象、數組等,只要不斷地創建這些對象,并且保證 GC Roots 到對象之間有可達路徑來避免垃 圾收集回收機制清除這些對象,當這些對象所占空間超過
  • 新電商三兄弟,“抖快紅”成團!

    來源:價值研究所作 者:Hernanderz 隨著內容電商的概念興起,抖音、快手、小紅書組成的&ldquo;新電商三兄弟&rdquo;成為業內一股不可忽視的勢力,給阿里、京東、拼多多帶去了巨大壓
  • 首發天璣9200+ iQOO Neo8系列發布首銷售價2299元起

    2023年5月23日晚,iQOO Neo8系列正式發布。其中,Neo系列首款Pro之作——iQOO Neo8 Pro強悍登場,限時售價3099元起;價位段最強性能手機iQOO Neo8同期上市
  • iQOO Neo8 Pro搶先上架:首發天璣9200+ 安卓性能之王

    經過了一段時間的密集爆料,昨日iQOO官方如期對外宣布:將于5月23日推出全新的iQOO Neo8系列新品,官方稱這是一款擁有旗艦級性能調校的作品。隨著發布時
  • 英特爾Xe-HP項目終止,將專注Xe-HPC/HPG系列顯卡

    據10 月 31 日消息報道,英特爾高級副總裁兼加速計算系統和圖形事業部總經理 表示,Xe-HP“ Arctic Sound” 系列服務器 GPU 已經應用于 oneAPI devcloud 云服
  • 親歷馬斯克血洗Twitter,硅谷的苦日子在后頭

    文/劉哲銘  編輯/李薇  馬斯克再次揮下裁員大刀。  美國時間11月14日,Twitter約4400名外包員工遭解雇,此次被解雇的員工的主要工作為內容審核等。此前,T
Top