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

使用Spring Boot輕松實(shí)現(xiàn)流式AI輸出的步驟

 更新時(shí)間:2025年02月26日 10:37:10   作者:夜闌臥聽風(fēng)吹雨,鐵馬冰河入夢來  
本文介紹了如何使用Spring Boot和WebFlux實(shí)現(xiàn)流式AI輸出,通過非阻塞I/O、反應(yīng)式編程和函數(shù)式路由等技術(shù),優(yōu)化了AI應(yīng)用的響應(yīng)速度,提升了用戶體驗(yàn),感興趣的朋友一起看看吧

1、背景

隨著AI的快速發(fā)展,越來越多的AI應(yīng)用誕生了,但是AI也有響應(yīng)慢的問題,一般不能夠即時(shí)響應(yīng),為了優(yōu)化用戶體驗(yàn),現(xiàn)在大部分AI應(yīng)用都是實(shí)現(xiàn)了打字機(jī)的效果,那么這種效果是如何實(shí)現(xiàn)的呢?今天我們先看一下后端的實(shí)現(xiàn)邏輯。

代碼流程是后端發(fā)出請求,請求智能體或AI模型暴露的流式接口,然后返回一個流式接口。

為什么不直接前端請求AI接口,因?yàn)橛械腁I接口在前端直接請求,可能會出現(xiàn)跨域問題。因?yàn)锳I接口返回的響應(yīng)中沒有包含跨域的Access-Control-Allow-Origin。

2、實(shí)現(xiàn)步驟

1、引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

2、使用webClient發(fā)起對AI接口請求

代碼中的URL,請求頭、請求體或者請求方法都可以按照對應(yīng)的AI接口文檔進(jìn)行替換。

WebClient webClient = WebClient.create();
        Flux<String> resultFlux = webClient.post()
                .uri(URL)  //請求url
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .header(HttpHeaders.AUTHORIZATION, "Bearer "+ API_KEY) // 添加認(rèn)證頭部
                .bodyValue(requestBody)//請求體
                .retrieve()
                .bodyToFlux(String.class);  //返回流式結(jié)果

3、啟動類需要添加@EnableAsync注解

4、如果工程中有過濾器,需要進(jìn)行配置

我的工程啟動后報(bào)錯

Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml.

大概意思是異步支持必須在servlet和所有的過濾器中被標(biāo)注成是enabled

Servlet和Filter聲明:如果您使用的是基于XML的配置,可以在web.xml文件中的servlet和filter聲明中添加<async-supported>true</async-supported>元素來啟用異步支持

<servlet>
    <servlet-name>myServlet</servlet-name>
    <servlet-class>com.example.MyAsyncServlet</servlet-class>
    <async-supported>true</async-supported>
</servlet>
<filter>
    <filter-name>myFilter</filter-name>
    <filter-class>com.example.MyAsyncFilter</filter-class>
    <async-supported>true</async-supported>
</filter>

如果您使用的是基于注解的配置或Java配置類,可以通過實(shí)現(xiàn)javax.servlet.Servlet接口并覆蓋isAsyncSupported()方法返回true,或者通過@WebServlet和@WebFilter注解的asyncSupported屬性來設(shè)置。我使用的是這種方式

@WebServlet(urlPatterns = "/async", asyncSupported = true)
public class MyAsyncServlet extends HttpServlet {
    // ...
}
@WebFilter(urlPatterns = "/*", asyncSupported = true)
public class MyAsyncFilter implements Filter {
    // ...
}

5、postman發(fā)送請求后結(jié)果

controller類接口

 @RequestMapping(method = RequestMethod.POST, value = "/getAIResult",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    Flux<String> getAIResult(@RequestBody String content){
        // 構(gòu)建請求體
        HashMap<String, Object> requestBody = new HashMap<>();
        requestBody.put("model", "6bbdf08d55244bd9be24052ded2a58ef");
        requestBody.put("context",0);
        requestBody.put("stream", true);
        List<HashMap<String, String>> messages = new ArrayList<>();
        HashMap<String, String> message = new HashMap<>();
        message.put("role", "user");
        message.put("content", content);
        messages.add(message);
        requestBody.put("messages", messages);
        WebClient webClient = WebClient.create();
        Flux<String> resultFlux = webClient.post()
                .uri(URL)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .header(HttpHeaders.AUTHORIZATION, "Bearer "+ API_KEY) // 添加認(rèn)證頭部
                .bodyValue(requestBody)
                .retrieve()
                .bodyToFlux(String.class);
        // 輸出響應(yīng)結(jié)果
        // // 訂閱響應(yīng)以觸發(fā)實(shí)際的 HTTP 請求
        // resultFlux.subscribe(
        //         response -> System.out.println("Response received: " + response),
        //         error -> System.err.println("Error occurred: " + error.getMessage())
        // );
        return resultFlux;
    }

3、使用技術(shù)介紹

WebFlux

WebFlux模塊是Spring 5引入的一部分,旨在提供一種新的方式來構(gòu)建響應(yīng)式的Web應(yīng)用程序。它允許你以異步和非阻塞的方式處理HTTP請求,這在處理高并發(fā)場景時(shí)可以顯著提高性能。

WebFlux的特點(diǎn)

  • 非阻塞I/O:與傳統(tǒng)的Servlet API不同,WebFlux使用的是非阻塞I/O模型,這意味著它可以更有效地利用線程資源。
  • 反應(yīng)式編程:WebFlux內(nèi)置了對反應(yīng)式編程的支持,主要通過Reactor庫實(shí)現(xiàn),使得編寫和處理異步代碼更加容易。
  • 函數(shù)式路由:除了注解驅(qū)動的控制器,WebFlux還提供了函數(shù)式路由API,讓你能夠以聲明性的方式定義路由規(guī)則。

以上來自AI內(nèi)容生成,看完一頭霧水,下方給出介紹

非阻塞I/O

含義:非阻塞I/O(Non-blocking I/O)是一種編程模型,它允許應(yīng)用程序在等待某些操作完成時(shí)不會被阻塞。與傳統(tǒng)的Servlet API(如Spring MVC)相比,WebFlux采用了基于事件和回調(diào)的非阻塞I/O模型。

  • 傳統(tǒng)Servlet API (阻塞I/O):在傳統(tǒng)的Servlet環(huán)境中,每個HTTP請求都會分配一個線程來處理。如果這個處理過程包含了一個長時(shí)間運(yùn)行的操作(例如數(shù)據(jù)庫查詢或網(wǎng)絡(luò)調(diào)用),那么該線程會被阻塞直到操作完成。這意味著線程不能用來處理其他請求,從而降低了服務(wù)器的效率。
  • WebFlux (非阻塞I/O):WebFlux使用了Netty這樣的異步網(wǎng)絡(luò)框架,它們可以在不阻塞線程的情況下執(zhí)行I/O操作。當(dāng)一個請求涉及到耗時(shí)的任務(wù)時(shí),它不會阻塞當(dāng)前的線程;相反,任務(wù)完成后會觸發(fā)相應(yīng)的回調(diào)函數(shù)繼續(xù)處理。這種方式使得單個線程可以處理多個并發(fā)請求,極大地提高了資源利用率和服務(wù)的吞吐量。

反應(yīng)式編程

含義:反應(yīng)式編程(Reactive Programming)是一種面向數(shù)據(jù)流和變化傳播的編程范式。它強(qiáng)調(diào)的是通過聲明式的代碼來描述數(shù)據(jù)流的變化,并能夠?qū)@些變化做出響應(yīng)。WebFlux內(nèi)置了對反應(yīng)式編程的支持,主要通過Project Reactor庫實(shí)現(xiàn),這是Spring 5引入的一個核心特性。

  • Reactor庫:Reactor提供了兩個核心類型——MonoFlux,分別表示0到1個元素的異步序列和0到N個元素的異步序列。開發(fā)者可以使用這些類型來構(gòu)建復(fù)雜的異步邏輯,而不需要顯式地管理線程或同步問題。
  • 好處
    • 簡化異步編程:通過組合操作符(如map, flatMap, filter等),你可以輕松地創(chuàng)建復(fù)雜的異步工作流,同時(shí)保持代碼的簡潔性和可讀性。
    • 錯誤處理:Reactor還提供了一套強(qiáng)大的錯誤處理機(jī)制,比如onErrorResume、retry等,使得處理異常情況更加直觀。
    • 背壓支持:對于生產(chǎn)者-消費(fèi)者模式中的流量控制,Reactor實(shí)現(xiàn)了背壓(Backpressure),確保系統(tǒng)不會因?yàn)檫^載而崩潰。

函數(shù)式路由

含義:函數(shù)式路由是WebFlux提供的另一種定義HTTP端點(diǎn)的方式,除了傳統(tǒng)的注解驅(qū)動控制器之外。它允許你以一種聲明性的、函數(shù)式的方式來配置路由規(guī)則,這在某些情況下可能比注解更靈活、更具表達(dá)力。

  • RouterFunction和HandlerFunction:在函數(shù)式路由中,RouterFunction用于定義路由匹配邏輯,而HandlerFunction則負(fù)責(zé)處理實(shí)際的請求。兩者結(jié)合在一起,可以非常清晰地表達(dá)出“如果路徑匹配,則執(zhí)行某個處理器”的意圖。

到此這篇關(guān)于用Spring Boot輕松實(shí)現(xiàn)流式AI輸出的文章就介紹到這了,更多相關(guān)Spring Boot流式AI輸出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringCloud @RefreshScope刷新機(jī)制深入探究

    SpringCloud @RefreshScope刷新機(jī)制深入探究

    RefeshScope這個注解想必大家都用過,在微服務(wù)配置中心的場景下經(jīng)常出現(xiàn),他可以用來刷新Bean中的屬性配置,那大家對他的實(shí)現(xiàn)原理了解嗎?它為什么可以做到動態(tài)刷新呢
    2023-03-03
  • 將應(yīng)用程序進(jìn)行Spring6遷移的最佳使用方式

    將應(yīng)用程序進(jìn)行Spring6遷移的最佳使用方式

    這篇文章主要介紹了將應(yīng)用程序進(jìn)行Spring6遷移的最佳方式,以及如何充分利用此升級,需要的朋友可以參考下,如有錯誤的地方還請指正
    2023-03-03
  • Spring中@Configuration注解和@Component注解的區(qū)別詳解

    Spring中@Configuration注解和@Component注解的區(qū)別詳解

    這篇文章主要介紹了Spring中@Configuration注解和@Component注解的區(qū)別詳解,@Configuration 和 @Component 到底有何區(qū)別呢?我先通過如下一個案例,在不分析源碼的情況下,小伙伴們先來直觀感受一下這兩個之間的區(qū)別,需要的朋友可以參考下
    2023-09-09
  • SpringBoot中接口安全的5種訪問控制方法詳解

    SpringBoot中接口安全的5種訪問控制方法詳解

    在項(xiàng)目開發(fā)種,API接口安全已成為系統(tǒng)設(shè)計(jì)中不可忽視的關(guān)鍵環(huán)節(jié),本文將介紹SpringBoot應(yīng)用中實(shí)現(xiàn)接口安全的5種訪問控制方法,有需要的小伙伴可以了解下
    2025-05-05
  • Java基礎(chǔ)之堆內(nèi)存溢出的解決

    Java基礎(chǔ)之堆內(nèi)存溢出的解決

    這篇文章主要介紹了Java基礎(chǔ)之堆內(nèi)存溢出的解決,文中有非常詳細(xì)的圖文示例及代碼示例,對正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java中實(shí)現(xiàn)WebSocket方法詳解

    Java中實(shí)現(xiàn)WebSocket方法詳解

    這篇文章主要介紹了Java中實(shí)現(xiàn)WebSocket方法詳解,WebSocket?是一種新型的網(wǎng)絡(luò)協(xié)議,它允許客戶端和服務(wù)器之間進(jìn)行雙向通信,可以實(shí)現(xiàn)實(shí)時(shí)數(shù)據(jù)交互,需要的朋友可以參考下
    2023-07-07
  • java后端請求兌現(xiàn)request的中文亂碼問題解決

    java后端請求兌現(xiàn)request的中文亂碼問題解決

    文章主要講述了在處理處理方案工作中遇到中文亂碼問題的解決過程,通過復(fù)現(xiàn)和分析亂碼問題,發(fā)現(xiàn)是由于解碼規(guī)則和后端服務(wù)編碼不一致導(dǎo)致的,最終通過修改過濾器中的編碼設(shè)置解決了問題
    2025-02-02
  • java 使用poi動態(tài)導(dǎo)出的操作

    java 使用poi動態(tài)導(dǎo)出的操作

    這篇文章主要介紹了java 使用poi動態(tài)導(dǎo)出的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 手把手搭建Java共享網(wǎng)盤的方法步驟

    手把手搭建Java共享網(wǎng)盤的方法步驟

    這篇文章主要介紹了手把手搭建Java共享網(wǎng)盤,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 深入理解Java String.replace()原理

    深入理解Java String.replace()原理

    String.replace()是我們?nèi)粘i_發(fā)中經(jīng)常用到的一個方法,那么,你有看過其底層的源碼實(shí)現(xiàn)嗎,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-03-03

最新評論

绥中县| 赫章县| 蒙自县| 马山县| 东宁县| 腾冲县| 桑日县| 兴安县| 宜宾市| 遂溪县| 武清区| 武宁县| 中阳县| 龙州县| 黄浦区| 陇南市| 井冈山市| 揭西县| 抚州市| 开原市| 康马县| 故城县| 万源市| 武川县| 航空| 广平县| 盐边县| 新晃| 延川县| 麻江县| 托里县| 手机| 云和县| 靖宇县| 长子县| 双鸭山市| 崇州市| 老河口市| 阿坝县| 仙居县| 西安市|