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

SpringBoot使用ResponseBodyEmitter處理流式日志和進度條

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

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

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

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

作用

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

需要注意的是,ResponseBodyEmitter 只是一個接口。

使用場景

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

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

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

實時日志流

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

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

創(chuàng)建控制器

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

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īng)用程序并訪問 /api/log/stream 路徑時,你會看到一個實時更新的日志流。每秒鐘,服務(wù)器會向客戶端推送一條新的日志條目,客戶端會將其顯示在頁面上。

ResponseBodyEmitter 的核心方法

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

ResponseBodyEmitter 工作原理

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

注意事項

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

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

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

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

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

與 Streaming 和 SSE 的對比

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

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

小結(jié)

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

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

相關(guān)文章

  • 關(guān)于slf4j_log4j2源碼學習心得

    關(guān)于slf4j_log4j2源碼學習心得

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

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

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

    Spring boot熱部署devtools過程解析

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

    eclipse啟動tomcat無法訪問的解決方法

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

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

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

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

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

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

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

    Java的StringBuilder在高性能場景下的正確用法

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

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

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

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

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

最新評論

衡阳县| 肇东市| 双城市| 台中县| 闸北区| 邳州市| 博爱县| 将乐县| 广安市| 潼南县| 巧家县| 成武县| 沙湾县| 丰镇市| 桑日县| 德兴市| 喀喇| 临泉县| 阿拉善盟| 洛南县| 乐陵市| 三门峡市| 新泰市| 海城市| 玉树县| 安丘市| 景泰县| 延津县| 西贡区| 伊吾县| 多伦县| 郸城县| 阳山县| 临江市| 奉节县| 屏边| 都昌县| 衡水市| 秦皇岛市| 嫩江县| 固安县|