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

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

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

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

前言

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

業務關系定義

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

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

圖片圖片J9W28資訊網——每日最新資訊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百萬級別的導出功能J9W28資訊網——每日最新資訊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次則無法進行繼續提交;J9W28資訊網——每日最新資訊28at.com

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

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

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

總結

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


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

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

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

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

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

標簽:
  • 熱門焦點
  • vivo TWS Air開箱體驗:真輕 臻好聽

    在vivo S15系列新機的發布會上,vivo的最新款真無線藍牙耳機vivo TWS Air也一同發布,本次就這款耳機新品給大家帶來一個簡單的分享。外包裝盒上,vivo TWS Air保持了vivo自家產
  • 8月總票房已突破10億!《封神》第一:口碑已經成了

    8月5日消息,據燈塔專業版數據,截至8月5日9時35分,8月總票房(含預售)已突破10億。其中,《封神》以大比分的優勢領先。根據官方消息,目前該片總票房已經超過14.
  • 線程通訊的三種方法!通俗易懂

    線程通信是指多個線程之間通過某種機制進行協調和交互,例如,線程等待和通知機制就是線程通訊的主要手段之一。 在 Java 中,線程等待和通知的實現手段有以下幾種方式:Object 類下
  • 企業采用CRM系統的11個好處

    客戶關系管理(CRM)軟件可以為企業提供很多的好處,從客戶保留到提高生產力。  CRM軟件用于企業收集客戶互動,以改善客戶體驗和滿意度。  CRM軟件市場規模如今超過580
  • 谷歌KDD'23工作:如何提升推薦系統Ranking模型訓練穩定性

    谷歌在KDD 2023發表了一篇工作,探索了推薦系統ranking模型的訓練穩定性問題,分析了造成訓練穩定性存在問題的潛在原因,以及現有的一些提升模型穩定性方法的不足,并提出了一種新
  • 一篇文章帶你了解 CSS 屬性選擇器

    屬性選擇器對帶有指定屬性的 HTML 元素設置樣式。可以為擁有指定屬性的 HTML 元素設置樣式,而不僅限于 class 和 id 屬性。一、了解屬性選擇器CSS屬性選擇器提供了一種簡單而
  • 雅柏威士忌多款單品價格大跌,泥煤頂流也不香了?

    來源 | 烈酒商業觀察編 | 肖海林今年以來,威士忌市場開始出現了降溫跡象,越來越多不斷暴漲的網紅威士忌也開始悄然回歸市場理性。近日,LVMH集團旗下蘇格蘭威士忌品牌雅柏(Ardbeg
  • 三翼鳥智能家居亮相電博會,讓用戶體驗更真實

    2021電博會在青島國際會展中心開幕中,三翼鳥直接把“家”搬到了現場,成為了展會的一大看點。這也是三翼鳥繼9月9日發布了行業首個一站式定制智慧家平臺后的
  • 北京:科技教育體驗基地開始登記

      北京“科技館之城”科技教育體驗基地登記和認證工作日前啟動。首批北京科技教育體驗基地擬于2023年全國科普日期間掛牌,后續還將開展常態化登記。  北京科技教育體驗基
Top