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

SpringBoot實現(xiàn)大模型流式Streaming響應(yīng)的示例代碼

 更新時間:2026年01月19日 08:30:04   作者:風象南  
這篇文章主要為大家詳細介紹了SpringBoot實現(xiàn)大模型流式Streaming響應(yīng)的相關(guān)知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

一、為什么需要流式響應(yīng)

同樣的 HTTP 請求,為什么像 Deepseek這類模型的回答能像打字機一樣逐字輸出,而我們平時寫的接口卻要等全部處理完才返回?

問題的核心在于 響應(yīng)模式

傳統(tǒng)模式流式模式
服務(wù)器處理完成 → 一次性返回生成一部分 → 立即推送
客戶端等待總時長 = 服務(wù)器處理時間客戶端首字等待時間通常很短
適合快速查詢適合耗時生成

對于大模型這種 生成式 AI,一個響應(yīng)可能需要幾秒甚至幾十秒。如果用傳統(tǒng)模式,用戶體驗就是:提問 → (10秒空白) → 答案全部出現(xiàn)

而流式響應(yīng)的體驗是:提問 → 0.1秒后 → "我" → "認" → "為" → ... → 逐字呈現(xiàn)

實現(xiàn)這種效果有多種技術(shù)方案,本文將介紹基于 Spring Boot WebFlux + SSE 的實現(xiàn)方式。

二、核心技術(shù)選型

實現(xiàn)流式響應(yīng)主要有以下幾種方案:

方案優(yōu)點缺點適用場景
SSE單向推送、HTTP協(xié)議、實現(xiàn)簡單不支持雙向通信服務(wù)端主動推送
WebSocket雙向通信、實時性強實現(xiàn)復(fù)雜、需要額外協(xié)議聊天、游戲
長輪詢兼容性好資源消耗大低頻數(shù)據(jù)更新

本文選擇 SSE 方案,原因如下:

  • Spring Boot 原生支持 ResponseEntity<Flux<String>>
  • 基于標準 HTTP,無需額外協(xié)議協(xié)商
  • 代碼簡潔,易于理解和維護

三、項目依賴配置

3.1 Maven 依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>springboot-chat-stream</artifactId>
    <version>1.0.0</version>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Spring Boot WebFlux:響應(yīng)式編程支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

        <!-- Lombok:簡化代碼 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
</project>

3.2 關(guān)鍵依賴說明

spring-boot-starter-webflux:提供響應(yīng)式 Web 支持,核心是 Reactor 的 Flux 類型

Reactor:響應(yīng)式編程庫,Flux<T> 表示 0-N 個元素的異步序列

四、核心代碼實現(xiàn)

4.1 Controller 層:流式響應(yīng)入口

package com.example.chat.controller;

import com.example.chat.service.StreamChatService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;

@RestController
@RequestMapping("/api/chat")
@RequiredArgsConstructor
@CrossOrigin(origins = "*") // 開發(fā)環(huán)境允許跨域
public class StreamChatController {

    private final StreamChatService chatService;

    /**
     * 流式聊天接口
     * @param prompt 用戶輸入的問題
     * @return 流式響應(yīng),text/event-stream 格式
     */
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public ResponseEntity<Flux<String>> streamChat(@RequestParam String prompt) {
        return ResponseEntity.ok()
                .header("Cache-Control", "no-cache")
                .header("Connection", "keep-alive")
                .body(chatService.streamResponse(prompt));
    }
}

關(guān)鍵點解析:

  • produces = MediaType.TEXT_EVENT_STREAM_VALUE:聲明返回 SSE 格式
  • Flux<String>:響應(yīng)式流,可以發(fā)送多個數(shù)據(jù)塊
  • Cache-Control: no-cache:禁用緩存,確保實時推送

4.2 Service 層:模擬大模型流式生成

package com.example.chat.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.time.Duration;

@Slf4j
@Service
public class StreamChatService {

    /**
     * 模擬大模型流式生成響應(yīng)
     * @param prompt 用戶問題
     * @return 按字符/詞匯流式輸出的響應(yīng)
     */
    public Flux<String> streamResponse(String prompt) {
        log.info("收到用戶提問: {}", prompt);

        // 模擬大模型生成的回復(fù)內(nèi)容
        String response = mockLLMResponse(prompt);

        // 將響應(yīng)拆分為字符流,每 50ms 發(fā)送一個字符
        return Flux.fromArray(response.split(""))
                .delayElements(Duration.ofMillis(50))
                .doOnNext(chunk -> log.debug("發(fā)送數(shù)據(jù)塊: {}", chunk))
                .doOnComplete(() -> log.info("流式響應(yīng)完成"))
                .doOnError(e -> log.error("流式響應(yīng)異常", e));
    }

    /**
     * 模擬大模型生成內(nèi)容(實際項目可接入 OpenAI/通義千問等)
     */
    private String mockLLMResponse(String prompt) {
        return """
                【Spring Boot 流式響應(yīng)】
                您的問題是:%s

                這是一個模擬大模型流式輸出的示例。
                在實際應(yīng)用中,你可以:
                1. 接入 OpenAI API 使用 GPT-4
                2. 接入阿里云通義千問 API
                3. 接入本地部署的大模型

                流式響應(yīng)的核心是:
                - 使用 Spring WebFlux 的 Flux
                - 返回 text/event-stream 格式
                - 前端使用 EventSource 或 fetch 接收

                這樣就能實現(xiàn)像 Deepseek 一樣的絲滑體驗!
                """.formatted(prompt);
    }
}

核心邏輯:

  • Flux.fromArray(response.split("")):將字符串拆分為字符數(shù)組轉(zhuǎn)為流
  • .delayElements(Duration.ofMillis(50)):每個字符延遲 50ms 發(fā)送
  • .doOnNext()/.doOnComplete()/.doOnError():生命周期鉤子,用于日志記錄

4.3 接入真實大模型 API(擴展)

// 接入 OpenAI Streaming API 的示例(偽代碼)
public Flux<String> streamOpenAI(String prompt) {
    WebClient webClient = WebClient.builder()
            .baseUrl("https://api.openai.com/v1")
            .defaultHeader(HttpHeaders.AUTHORIZATION, "Bearer YOUR_API_KEY")
            .build();

    return webClient.post()
            .uri("/chat/completions")
            .bodyValue(Map.of(
                "model", "gpt-4",
                "messages", List.of(Map.of("role", "user", "content", prompt)),
                "stream", true
            ))
            .retrieve()
            .bodyToFlux(String.class)
            .map(this::extractContentFromSSE); // 解析 SSE 格式提取 content
}

4.4 啟動類

package com.example.chat;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ChatStreamApplication {
    public static void main(String[] args) {
        SpringApplication.run(ChatStreamApplication.class, args);
    }
}

4.5 配置文件

server:
  port: 8080

spring:
  application:
    name: chat-stream-demo

# 日志配置
logging:
  level:
    com.example.chat: DEBUG

五、前端對接示例

5.1 使用 EventSource 接收流

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Spring Boot 流式響應(yīng)示例</title>
    <style>
        body { font-family: Arial; max-width: 800px; margin: 50px auto; padding: 20px; }
        #output { border: 1px solid #ddd; padding: 20px; min-height: 100px; background: #f9f9f9; }
        input { width: 70%; padding: 10px; }
        button { padding: 10px 20px; cursor: pointer; }
    </style>
</head>
<body>
    <h1>Spring Boot 流式聊天</h1>
    <input type="text" id="prompt" placeholder="輸入問題...">
    <button onclick="sendQuestion()">發(fā)送</button>
    <div id="output"></div>

    <script>
        function sendQuestion() {
            const prompt = document.getElementById('prompt').value;
            const output = document.getElementById('output');
            output.innerHTML = '等待響應(yīng)...';

            // 使用 EventSource 接收 SSE 流
            const eventSource = new EventSource(
                `/api/chat/stream?prompt=${encodeURIComponent(prompt)}`
            );

            eventSource.onmessage = (event) => {
                output.innerHTML += event.data;
            };

            eventSource.onerror = () => {
                eventSource.close();
                output.innerHTML += '

[連接關(guān)閉]';
            };

            // 30秒后自動關(guān)閉(演示用)
            setTimeout(() => eventSource.close(), 30000);
        }
    </script>
</body>
</html>

5.2 使用 Fetch API(推薦)

async function streamChat(prompt) {
    const response = await fetch(`/api/chat/stream?prompt=${encodeURIComponent(prompt)}`);
    const reader = response.body.getReader();
    const decoder = new TextDecoder();

    while (true) {
        const { done, value } = await reader.read();
        if (done) break;

        const chunk = decoder.decode(value);
        console.log('收到數(shù)據(jù):', chunk);
        // 更新 UI
    }
}

六、運行效果

啟動項目后,訪問 http://localhost:8080(需添加靜態(tài)頁面支持),輸入問題,你會看到:

【Spring Boot 流式響應(yīng)】
您的問題是:如何學習 Spring Boot?

這是一個模擬大模型流式輸出的示例。
...

文字像打字機一樣逐字出現(xiàn),體驗絲滑!

七、總結(jié)

本文介紹了如何使用 Spring Boot WebFlux 實現(xiàn) SSE 流式響應(yīng)。核心是通過 Flux<String> + TEXT_EVENT_STREAM_VALUE 將數(shù)據(jù)分塊推送,配合前端 EventSource 實現(xiàn)逐字顯示效果。相比傳統(tǒng)一次性返回,流式響應(yīng)能顯著降低用戶等待感知,特別適合大模型對話等耗時生成場景。

以上就是SpringBoot實現(xiàn)大模型流式Streaming響應(yīng)的示例代碼的詳細內(nèi)容,更多關(guān)于SpringBoot流式響應(yīng)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring中的異步方法@Async失效的原因詳解

    Spring中的異步方法@Async失效的原因詳解

    這篇文章主要介紹了Spring中的異步方法@Async失效的原因詳解,@Async屬于異步注解,@Async放在方法上標識該方法為異步方法,異步是指進程不需要一直等待下去,而是繼續(xù)執(zhí)行下面的操作,不管其他進程的狀態(tài),需要的朋友可以參考下
    2024-01-01
  • SpringBoot項目解決跨域的5種實現(xiàn)過程

    SpringBoot項目解決跨域的5種實現(xiàn)過程

    本文介紹了SpringBoot項目中解決跨域問題的5種方式,包括使用@CrossOrigin注解、全局配置WebMvcConfigurer、使用CorsFilter過濾器、WebFlux配置和手動配置過濾器,推薦使用全局配置WebMvcConfigurer,因為它既統(tǒng)一又靈活,適合大多數(shù)項目場景
    2026-05-05
  • 基于Java實現(xiàn)的圖的廣度優(yōu)先遍歷算法

    基于Java實現(xiàn)的圖的廣度優(yōu)先遍歷算法

    這篇文章主要介紹了基于Java實現(xiàn)的圖的廣度優(yōu)先遍歷算法,需要的朋友可以參考下
    2014-07-07
  • Java JDK安裝、環(huán)境配置圖文教程

    Java JDK安裝、環(huán)境配置圖文教程

    JDK 是Java程序開發(fā)的核心工具包,包含了開發(fā)Java應(yīng)用程序所需的所有資源,本文給大家介紹Java JDK安裝、環(huán)境配置圖文教程,感興趣的朋友跟隨小編一起看看吧
    2025-10-10
  • 加速spring/springboot應(yīng)用啟動速度詳解

    加速spring/springboot應(yīng)用啟動速度詳解

    這篇文章主要介紹了加速spring/springboot應(yīng)用啟動速度詳解,本文通過實例代碼給大家介紹的非常詳細對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • Maven默認中央倉庫(settings.xml 配置詳解)

    Maven默認中央倉庫(settings.xml 配置詳解)

    這篇文章主要介紹了Maven默認中央倉庫(settings.xml 配置詳解),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • springboot 日志實現(xiàn)過程

    springboot 日志實現(xiàn)過程

    Spring Boot 使用 SLF4J 作為日志門面,Logback 或 Log4j2 作為日志實現(xiàn),日志門面提供統(tǒng)一接口,簡化日志記錄,實現(xiàn)負責具體功能,Spring Boot 默認使用 SLF4J 和 Logback,可以通過配置文件或注解進行日志記錄和控制,感興趣的朋友一起看看吧
    2025-01-01
  • mybatis call存儲過程調(diào)用及out的參數(shù)問題

    mybatis call存儲過程調(diào)用及out的參數(shù)問題

    在 MyBatis 中調(diào)用存儲過程并獲取 OUT 參數(shù),需通過 XML 映射文件或注解方式實現(xiàn),下面通過本文給大家介紹mybatis call存儲過程調(diào)用及out的參數(shù)問題,感興趣的朋友一起看看吧
    2025-10-10
  • IntelliJ IDEA 中配置 Spring MVC 環(huán)境的詳細步驟及問題解決

    IntelliJ IDEA 中配置 Spring MVC 環(huán)境的詳細步

    這篇文章主要介紹了IntelliJ IDEA 中配置 Spring MVC 環(huán)境的詳細步驟及問題解決,本文分步驟結(jié)合實例給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2025-04-04
  • java中的轉(zhuǎn)義字符介紹

    java中的轉(zhuǎn)義字符介紹

    普通的轉(zhuǎn)義字符序列和八進制轉(zhuǎn)義字符都比Unicode轉(zhuǎn)義字符要好得多,因為與Unicode轉(zhuǎn)義字符不同,轉(zhuǎn)義字符序列是在程序被解析為各種符號之后被處理的
    2013-09-09

最新評論

赣州市| 双峰县| 广汉市| 莱西市| 绥滨县| 无锡市| 常州市| 涿鹿县| 伊宁县| 莫力| 新竹县| 府谷县| 红原县| 将乐县| 孝义市| 高安市| 莫力| 唐河县| 柳林县| 沙河市| 铜梁县| 涿鹿县| 汨罗市| 乐山市| 西乌珠穆沁旗| 台江县| 凤城市| 凤山市| 青铜峡市| 阳谷县| 贵南县| 南汇区| 五指山市| 阿勒泰市| 洪湖市| 水城县| 涿鹿县| 闸北区| 涟源市| 隆昌县| 天水市|