当前位置: 首页 > news >正文

Spring WebFlux 整合AI大模型实现流式输出

前言

最近赶上AI的热潮,很多业务都在接入AI大模型相关的接口去方便的实现一些功能,后端需要做的是接入AI模型接口,并整合成流式输出到前端,下面有一些经验和踩过的坑。

集成

Spring WebFlux是全新的Reactive Web技术栈,基于反应式编程,很适合处理我们需求的流式数据。

依赖

只需要下面这一个依赖即可,但是需要助力springboot父版本,不同的版本在相关的API实现上面有些许的差别。

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

代码

这边我在controller写了一个测试代码,意思是每秒产生一段json数据,一共10次,需要注意,响应头一定要设置text/event-stream 这个值,标志着是流式输出

@GetMapping(path = "/test/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> chatTest() {//chat交互测试return Flux.interval(Duration.ofSeconds(1)).take(10).map(sequence -> "{" + "    \"data\": \"33\"," + "    \"count\": \"" + sequence + "\"" + "}");}

postman 调用接口测试下,正常返回数据了
在这里插入图片描述

后端集成AI大模型

在实际业务中,基本上都是后端来调用 deepseek,再返回给前端,下面大概是集成

public Flux<ServerSentEvent<ObjectNode>> chat() {WebClient webClient = WebClient.create();
String url = "大模型url链接"return webClient.post().uri(url).header("Accept", "text/event-stream").body(BodyInserters.fromObject(reqNode))  // 注意高版本的API 可以直接用 bodyValue().retrieve().bodyToFlux(new ParameterizedTypeReference<ServerSentEvent<ObjectNode>>() {}).log().onBackpressureBuffer().doOnError(throwable -> {//错误处理log.error("chat request error -> {}", throwable.getMessage());throw new RuntimeException("request error -> " +throwable.getMessage());}).doOnNext(v -> {//每次输出流处理log.info("received chat message: {}", v);}).doOnComplete(() -> {//流输出完成处理});

一些错误解决

reactor.core.Exceptions$OverflowException: Could not emit buffer due to lack of requests

报错是由于发布者(Publisher)尝试以比订阅者(Subscriber)请求速率更快的速度推送数据时。这种情况违反了 Reactive Streams 的背压(Backpressure)机制,导致异常抛出。导致流异常终止。
在上面请求时加上了 .onBackpressureBuffer() 用缓冲机制解决

http://www.xdnf.cn/news/881425.html

相关文章:

  • PostgreSQL 的扩展pg_prewarm
  • Qt 5.12 上读取 .xlsx 文件(Windows 平台)
  • Vue.js 组件:深入理解与实践
  • opencv如何在仿射变换后保留完整图像内容并自动裁剪
  • uniapp+vue3实现CK通信协议(基于jjc-tcpTools)
  • 《如何使用MinGW-w64编译OpenCV和opencv_contrib》
  • JAVA开发工具——IntelliJ IDEA
  • Python Rio 【图像处理】库简介
  • 【图像处理3D】:点云图是怎么生成的
  • Unity VR/MR开发-VR设备与适用场景分析
  • Unity VR/MR开发-VR开发与传统3D开发的差异
  • 在 Vue 的template中使用 Pug 的完整教程
  • 高敏感应用如何保护自身不被逆向?iOS 安全加固策略与工具组合实战(含 Ipa Guard 等)
  • 从内核到应用层:Linux缓冲机制与语言缓冲区的协同解析
  • 数据集-目标检测系列- 猴子 数据集 monkey >> DataBall
  • 数字孪生在建设智慧城市中可以起到哪些作用或帮助?
  • Go语言底层(三): sync 锁 与 对象池
  • 结合Jenkins、Docker和Kubernetes等主流工具,部署Spring Boot自动化实战指南
  • 如何通过外网访问内网?哪个方案比较好用?跨网远程连接网络知识早知道
  • 在Docker里面运行Docker
  • Windows11:解决近期更新后无法上网的问题
  • .net ORM框架dapper批量插入
  • 案例分享--汽车制动卡钳DIC测量
  • PDF 转 HTML5 —— HTML5 填充图形不支持 Even-Odd 奇偶规则?(第二部分)
  • 智慧赋能:新能源汽车充电桩应用现状与管理升级方案
  • 矩阵分解相关知识点总结(二)
  • Playwright 测试框架 - Java
  • 【缺陷】温度对半导体缺陷电荷态跃迁能级的影响
  • React 样式方案与状态方案初探
  • AiPy实战:10分钟用AI造了个音乐游戏!