最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot使用ResponseBodyEmitter處理流式日志和進(jìn)度條

 更新時(shí)間:2025年02月14日 11:02:06   作者:碼猿技術(shù)專欄  
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何使用ResponseBodyEmitter處理流式日志和進(jìn)度條,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

自從 ChatGPT 火了之后,帶動(dòng)了大批量的流式輸出的使用。

在流式輸出火的那段時(shí)間,不少愛鉆研技術(shù)的小伙伴們,都學(xué)習(xí)并上手了 SSE 異步處理。我那時(shí)也寫了一篇文章,今天我們換一種更簡單的方式,來實(shí)現(xiàn)流式輸出。

它就是 ResponseBodyEmitter。它并不是一個(gè)新技術(shù),早在 Spring Framework 4.2 版本中就被引入了。直到最近我們需要做一個(gè)滾動(dòng)的日志輸出功能,才了解到它。

作用

相比 SSE 技術(shù),ResponseBodyEmitter 更簡單。它常用于處理異步的 HTTP 響應(yīng),允許逐步發(fā)送數(shù)據(jù)到客戶端,而不是一次性發(fā)送所有內(nèi)容。它適用于需要長時(shí)間處理或流式傳輸?shù)膱?chǎng)景。

需要注意的是,ResponseBodyEmitter 只是一個(gè)接口。

使用場(chǎng)景

  • 長輪詢:服務(wù)器在有數(shù)據(jù)時(shí)立即響應(yīng),否則保持連接開放。
  • 服務(wù)器推送事件 (SSE):服務(wù)器可以持續(xù)向客戶端推送事件。
  • 流式傳輸:逐步發(fā)送大量數(shù)據(jù),如文件下載或?qū)崟r(shí)數(shù)據(jù)流。
  • 異步處理:處理耗時(shí)任務(wù)時(shí),逐步返回結(jié)果,避免客戶端長時(shí)間等待。

業(yè)務(wù)舉例

進(jìn)度條、實(shí)時(shí)聊天、股票價(jià)格更新、系統(tǒng)日志流、AI 的流式輸出等。

實(shí)時(shí)日志流

實(shí)戰(zhàn)演練:實(shí)現(xiàn)一個(gè)簡單的實(shí)時(shí)日志流。

為了讓這個(gè)概念更加具體,我們來實(shí)現(xiàn)一個(gè)簡單的實(shí)時(shí)日志流功能。假設(shè)你有一個(gè)應(yīng)用程序,需要實(shí)時(shí)查看服務(wù)器的日志,以便快速定位和解決問題。

創(chuàng)建控制器

首先,我們?cè)?Spring Boot 應(yīng)用中創(chuàng)建一個(gè)控制器,使用 ResponseBodyEmitter 來實(shí)現(xiàn)實(shí)時(shí)日志流。

import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

@RestController
@RequestMapping("/api/log")
public class LogController {
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public ResponseBodyEmitter streamLogs() {
        ResponseBodyEmitter emitter = new ResponseBodyEmitter();

        // 異步處理數(shù)據(jù)并發(fā)送
        new Thread(() -> {
            try {
                while (true) {
                    String logEntry = getLatestLogEntry();
                    if (logEntry != null) {
                        emitter.send(logEntry);
                    }
                    Thread.sleep(1000); // 每秒檢查一次
                }
            } catch (Exception e) {
                emitter.completeWithError(e);
            }
        }).start();

        return emitter;
    }

    private String getLatestLogEntry() {
        // 模擬從日志文件中獲取最新日志條目
        return "2025-02-12 12:00:00 - INFO: User logged in successfully.";
    }
}

運(yùn)行效果

當(dāng)你運(yùn)行這個(gè)應(yīng)用程序并訪問 /api/log/stream 路徑時(shí),你會(huì)看到一個(gè)實(shí)時(shí)更新的日志流。每秒鐘,服務(wù)器會(huì)向客戶端推送一條新的日志條目,客戶端會(huì)將其顯示在頁面上。

ResponseBodyEmitter 的核心方法

  • send(Object data):向客戶端發(fā)送數(shù)據(jù),可以多次調(diào)用。
  • complete():結(jié)束響應(yīng)流,表示數(shù)據(jù)發(fā)送完畢。
  • onTimeout(Runnable callback):設(shè)置超時(shí)回調(diào)函數(shù)。
  • onCompletion(Runnable callback):設(shè)置完成回調(diào)函數(shù)。

ResponseBodyEmitter 工作原理

  • 服務(wù)端異步生成響應(yīng)數(shù)據(jù):任務(wù)執(zhí)行時(shí),調(diào)用 send() 方法將數(shù)據(jù)推送至客戶端。
  • 分塊傳輸:數(shù)據(jù)以 HTTP 的**分塊編碼(Chunked Encoding)**方式傳輸,不會(huì)提前設(shè)置Content-Length,而是分段發(fā)送數(shù)據(jù)塊。
  • 連接生命周期:通過complete()completeWithError()控制連接的關(guān)閉。

注意事項(xiàng)

支持的客戶端:大多數(shù)瀏覽器和 HTTP 客戶端庫支持分塊傳輸,但某些老舊的客戶端可能不支持。

超時(shí)設(shè)置:為了避免長連接占用資源,可以為ResponseBodyEmitter設(shè)置超時(shí)時(shí)間:

emitter.onTimeout(() -> emitter.complete());

線程安全:ResponseBodyEmitter 的 send() 方法是線程安全的,但需要注意控制任務(wù)線程的生命周期。

連接關(guān)閉:需要確保任務(wù)結(jié)束時(shí)調(diào)用 complete() 或 completeWithError(),否則可能導(dǎo)致資源泄露。

與 Streaming 和 SSE 的對(duì)比

  • Streaming:直接通過 OutputStream 向客戶端寫入數(shù)據(jù),靈活性高,但需手動(dòng)處理流的關(guān)閉。
  • Server-Sent Events (SSE):基于 text/event-stream,適用于服務(wù)端事件推送,客戶端需支持 SSE。
  • ResponseBodyEmitter:更通用,適用于任何支持 HTTP 的客戶端,且易于與 Spring 集成。

類似 AI 這樣的響應(yīng)式的、流式輸出,相比 SSE 而言,ResponseBodyEmitter 是 Spring 提供的輕量級(jí)流式傳輸解決方案,同時(shí) http 協(xié)議兼容性更好。

小結(jié)

ResponseBodyEmitter 是 Spring 提供的輕量級(jí)流式傳輸解決方案,能有效提升高并發(fā)和實(shí)時(shí)性場(chǎng)景的用戶體驗(yàn)。通過 ResponseBodyEmitter,我們可以輕松實(shí)現(xiàn)服務(wù)器向客戶端的實(shí)時(shí)數(shù)據(jù)推送。無論是進(jìn)度條、實(shí)時(shí)聊天、股票價(jià)格更新還是系統(tǒng)日志流,ResponseBodyEmitter 都能幫助我們構(gòu)建更加動(dòng)態(tài)和互動(dòng)的應(yīng)用程序。

到此這篇關(guān)于SpringBoot使用ResponseBodyEmitter處理流式日志和進(jìn)度條的文章就介紹到這了,更多相關(guān)SpringBoot ResponseBodyEmitter處理日志內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    關(guān)于slf4j_log4j2源碼學(xué)習(xí)心得

    這篇文章主要介紹了slf4j_log4j2源碼學(xué)習(xí)心得,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 解決Spring配置文件中bean的property屬性中的name出錯(cuò)問題

    解決Spring配置文件中bean的property屬性中的name出錯(cuò)問題

    這篇文章主要介紹了解決Spring配置文件中bean的property屬性中的name出錯(cuò)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Spring boot熱部署devtools過程解析

    Spring boot熱部署devtools過程解析

    這篇文章主要介紹了Spring boot熱部署devtools過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • eclipse啟動(dòng)tomcat無法訪問的解決方法

    eclipse啟動(dòng)tomcat無法訪問的解決方法

    這篇文章介紹了eclipse啟動(dòng)tomcat無法訪問的解決方法,有需要的朋友可以參考一下
    2013-10-10
  • RestTemplate使用之如何設(shè)置請(qǐng)求頭、請(qǐng)求體

    RestTemplate使用之如何設(shè)置請(qǐng)求頭、請(qǐng)求體

    這篇文章主要介紹了RestTemplate使用之如何設(shè)置請(qǐng)求頭、請(qǐng)求體問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • java 將一個(gè)數(shù)組逆序輸出的方法

    java 將一個(gè)數(shù)組逆序輸出的方法

    今天小編就為大家分享一篇java 將一個(gè)數(shù)組逆序輸出的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Java之BigDecimal實(shí)現(xiàn)詳解

    Java之BigDecimal實(shí)現(xiàn)詳解

    這篇文章主要介紹了Java之BigDecimal實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • Java的StringBuilder在高性能場(chǎng)景下的正確用法

    Java的StringBuilder在高性能場(chǎng)景下的正確用法

    StringBuilder?對(duì)字符串的操作是直接改變字符串對(duì)象本身,而不是生成新的對(duì)象,所以新能開銷小.與StringBuffer相比StringBuilder的性能略高,StringBuilder則沒有保證線程的安全,從而性能略高于StringBuffer,需要的朋友可以參考下
    2023-05-05
  • 使用synchronized實(shí)現(xiàn)一個(gè)Lock代碼詳解

    使用synchronized實(shí)現(xiàn)一個(gè)Lock代碼詳解

    這篇文章主要介紹了使用synchronized實(shí)現(xiàn)一個(gè)Lock代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Spring?Cloud實(shí)現(xiàn)遠(yuǎn)程調(diào)用OpenFeign組件的方法

    Spring?Cloud實(shí)現(xiàn)遠(yuǎn)程調(diào)用OpenFeign組件的方法

    本文主要介紹了SpringCloud中實(shí)現(xiàn)遠(yuǎn)程調(diào)用的組件OpenFeign的相關(guān)知識(shí)與操作,包括OpenFeign的介紹、快速上手、參數(shù)傳遞和最佳實(shí)踐,感興趣的朋友跟隨小編一起看看吧
    2026-02-02

最新評(píng)論

墨竹工卡县| 大城县| 新宁县| 新闻| 宁化县| 上蔡县| 资阳市| 平武县| 武夷山市| 赫章县| 嵊州市| 黎城县| 道孚县| 永定县| 元江| 息烽县| 蛟河市| 巴马| 宜良县| 西乌珠穆沁旗| 金寨县| 府谷县| 仙桃市| 喀喇沁旗| 大港区| 石台县| 宁陵县| 灵武市| 滨州市| 河间市| 达拉特旗| 永城市| 德保县| 馆陶县| 内丘县| 突泉县| 依兰县| 苏州市| 奉节县| 武城县| 万宁市|