AI编程:[体验]存量微服务架构下植入WebSocket的“踩坑”与“填坑”

一、核心需求

  1. 功能需求:用户可以通过语音与AI对话,并实现类似ChatGPT的实时交互(流式响应,打字机效果)
  2. 技术需求:在现有微服务架构中进行扩展(SpringCloud)

二、技术盲点

  1. 陌生领域
  • 语音录入
  • 语音流传输
  • Java对接大模型API
  1. 技术选型难点
  • WebSocket框架选择
    • Spring WebSocket、t-io、Java-WebSocket、Socket.io等
  • 流式编程 or 响应式编程 (本质是分块传输)
    • Rxjava:UnicastProcessor、Flowable
    • Spring WebFlux:Flux、Mono、WebClient
    • Java9 Reactive Stream API:Publisher、Subscriber、Subscription、Processor
    • Spring MVC:StreamingResponseBody、SseEmitter 、Servlet3.0

三、技术选型与验证

  1. 第一步,技术选型
  • 已验证:Spring WebSocket、t-io、spring-ai-alibaba、百炼灵积等等
  • 未验证:Java-WebSocket、Socket.io
  1. 第二步,验证流程
  • 单点功能验证:
    • 第三方大模型API对接
    • WebSocket服务端与客户端通信
  • 功能集成验证:
    • 语音录入 + WebSocket传输 + 服务端 + 第三方大模型API对接
    • 整合现有微服务架构(语音录入 → 网关 → WebSocket链路验证

四、AI编程中的卡点问题与解决

  1. 问题1:消息大小限制的坑:WebSocket 消息未处理(二进制流)
  • 现象:
    • 服务端无日志、自定义处理器未触发(该问题最大的坑是,无从下手的感觉)
  • 分析:
    • AI解决:先问AI,效果不佳
    • 百度解决:再查百度,效果仍然不佳(有找到正确的解决方案,由于并未真正理解,仍然卡点了很久)
    • Debug源码:此时已无从下手,因此只能Debug源码,逐步排查(逐步理解WebSocket协议的实现原理)
    • Debug源码+AI提示:随着了解的越深,逐步建立手感,对问题原因有了大致的判断(验证判断是否正确)
  • 根因:
    • 消息大小超过限制
  • 解决:
    • 最终方案:调整消息大小,避免超出websocket server端的消息大小限制
# application.yml
spring:servlet:multipart:# 整个请求大小限制max-request-size: 10MB# 上传单个文件大小限制max-file-size: 20MB
  1. 问题2:网关Filter劫持WebSocket的101响应:网关转发WebSocket请求,导致消息未处理的异常
  • 现象:该问题最大的坑是,无从下手的感觉
    • 客户端:报错 “java.io.IOException: 你的主机中的软件中止了一个已建立的连接”
    • 服务端:握手请求成功,有打印握手日志(但数据请求的处理器没有执行)
    • 网关:有打印请求日志,但没有打印响应日志
  • 分析:由于无从下手,只能逐步排除各个环节的问题
    • 限制排查:下意识的认为还是消息大小超过限制的问题(未触发消息大小限制)
    • 网关配置检查:确认网关配置与请求转发的正确性(请求转发正常)
    • 握手请求检查:确认握手请求是否正常被执行(自定义拦截器,握手请求正常执行)
    • 网关请求头检查:检查握手请求头是否正常透传(websocket请求header正常透传)
    • 握手请求的响应检查:到这一步基本确定是response未被正确处理
    • 定位到根因:此处结合AI提示,定位到是网关中的过滤器,未正确处理握手请求的response
    • AI修复问题:定位到问题根因,此时让AI给出方案,但效果不佳,借助该思路,手动修正代码,解决问题
  • 根因:
    • 网关过滤器对Response进行了包装,导致握手请求的101状态码未被正确处理,最终导致WebSocket连接建立失败。
  • 解决:
    • 最终方案:优化网关AccessLogFilter过滤器代码,对websocket请求直接放行
public class AccessLogGlobalFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {StopWatch stopWatch = new StopWatch();stopWatch.start();ServerHttpRequest httpRequest = exchange.getRequest();ServerHttpResponse httpResponse = exchange.getResponse();// WebSocket 握手请求,直接进入下一个Filter,并返回原始response,确保 WebSocket 握手正常处理101状态码// 说明:WebSocket Client 通过Http请求与WebSocket Server握手建立长连接,后续的通信都是该长连接进行通信,不会再被filter拦截if (checkWebSocketHandShake(httpRequest)) {return filter("websocket handshake", exchange, chain, stopWatch, httpResponse, httpRequest);}// 网关:判断是否为流式请求,支持ResponseBodyEmitter、SseEmitter的流式响应String acceptHeader = httpRequest.getHeaders().getFirst(HttpHeaders.ACCEPT);boolean isStreamingRequest = acceptHeader != null && acceptHeader.contains(MediaType.TEXT_EVENT_STREAM_VALUE);if (isStreamingRequest) {return filter("stream request", exchange, chain, stopWatch, httpResponse, httpRequest);}// 省略相关代码 ... ...}/*** 执行拦截器链(不包装request和response)*/private Mono<Void> filter(String logPrefix, ServerWebExchange exchange, GatewayFilterChain chain, StopWatch stopWatch, ServerHttpResponse httpResponse, ServerHttpRequest httpRequest) {if (log.isInfoEnabled() && configProperties.isLogEnabled()) {log.info("请求参数 {} [{}] [{}] query:{}, header:{}", logPrefix, httpRequest.getURI().getPath(), httpRequest.getMethod(), httpRequest.getURI().getRawQuery(), exchange.getRequest().getHeaders());}return chain.filter(exchange).doFinally(s -> MdcUtil.removeTraceId())// 清除MDC.then(Mono.fromRunnable(() -> {stopWatch.stop();// 为了方便排查问题,还是打印一个简单的日志if (log.isInfoEnabled()) {log.info("响应参数 {} {} time: {} ms", logPrefix, httpResponse.getRawStatusCode(), stopWatch.getTotalTimeMillis());}}));}/*** 检查是否为WebSocket握手请求** @return true 表示是WebSocket握手请求*/public boolean checkWebSocketHandShake(ServerHttpRequest httpRequest) {// 从请求头中获取 Upgrade 标志,若为websocket,则表示将普通http请求,升级为websocket请求String upgradeHeader = httpRequest.getHeaders().getFirst(HttpHeaders.UPGRADE);if ("websocket".equalsIgnoreCase(upgradeHeader)) {return true;}return false;}
}

五、实践总结

仅针对上述场景的实践总结

  1. 技术实践经验
  • 需深入理解WebSocket协议原理(消息限制、握手流程)
  • 网关需特殊处理WebSocket协议(避免过滤器干扰)
  1. AI工具定位
  • 搜索引擎:替代传统搜索,大部分时候,AI的搜索效果,比百度的效果要好
  • 辅助神器:明确的问题,AI效果好;未知或复杂的问题,AI效果差,但用AI辅助理解技术原理效果好,可将未知或复杂的问题,转换为明确的问题,再让AI解决
  1. AI工具效果
  • 通义灵码(Chat模式):生成代码效果一般,解决问题效果一般
  • Trae(Builder模式):效果较好(有时也会抽疯,需要多轮对话)
  1. AI工具局限性
  • 生成代码需人工校验(无法直接投产)
  • 复杂问题需多轮对话(效率较低,很容易放弃)
  1. AI开发心得
  • 复杂场景,需分步拆解验证,再集成整合
  • 顽固问题,目前AI无法替代人工,需手动介入处理(给AI明确的问题点,AI才会有更好的效果)
  • 陌生领域,对于不了解的技术,上手变得容易很多(如流式编程)
  • 开发习惯,过往的开发习惯较难改变,存在习惯性忽略使用AI的情况(需多用多练)

六、开放性思考

  • 普通人,使用AI编程,对代码的要求是什么?
    • 生成简单的验证性代码,保证功能实现即可,不关注代码质量
  • 程序员,使用AI编程,对代码的要求是什么?
    • 生成可投产的生产级别代码,保证功能实现的同时,也关注代码质量和测试质量(要求完全自主可控)
  • 面对AI编程效果不佳,尤其经过多轮对话,问题还未解决时,你是否萌生退意??
    • 期望过高:通过一次性的需求描述,AI就能自动生成完整的代码或解决问题。
    • 实际拉垮:AI生成的代码,或用AI解决问题时,困难重重,始终无法达到预期。
    • 扪心自问:使用过程中,面对AI也解决不了的问题时,你有产生过,被劝退的感觉吗?

七、WebSocket相关原理

WebSocket握手请求与数据请求的区别

一、握手请求(Handshake Request):

  • 本质:握手请求是HTTP协议的升级请求,用于建立WebSocket连接
  • 说明:服务器需响应HTTP 101状态码,确认协议升级,并返回Sec-WebSocket-Accept验证字段

二、数据请求(Message Frame)

  • 本质:WebSocket连接建立后,客户端和服务端通过数据帧(Frame)进行双向通信。
  • 数据以帧格式传输,包含操作码(Opcode)、掩码(Mask)、载荷长度(Payload Length)等信息
  • 常见帧类型:文本帧(Opcode=1)、二进制帧(Opcode=2)、控制帧(如Ping/Pong)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/911903.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/911903.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp事件onLoad区分大小写

区分大小写。不然会不起作用。onLoad方法中的功能均不会被执行。 除了功能逻辑要检查外。大小写是要认真检查的一部分

《打破微前端困局:样式冲突与资源隔离破局指南》

微前端架构凭借其独特优势&#xff0c;正逐渐成为众多大型项目的首选架构模式。它将一个庞大的前端应用拆解为多个相对独立的子应用&#xff0c;每个子应用可以独立开发、部署和维护&#xff0c;极大地提升了开发效率与团队协作的灵活性。然而&#xff0c;随着微前端架构的广泛…

OpenCV——边缘检测

边缘检测 一、边缘检测二、边缘检测算子2.1、Sobel算子2.2、Scharr算子2.3、Laplacian算子 三、Canny边缘检测3.1、Canny边缘检测的步骤3.2、Canny算法的实现 一、边缘检测 边缘是指图像中像素的灰度值发生剧烈变化的区域&#xff1a; 图像中的边缘主要有以下几种成因&#x…

2506认证资讯|工信部出手整治多品牌充电宝,WMC上海稍逊往年,RED修订Common Charger,WiFi7 FCC测试

01 — 中国 工信部拟制定移动电源强制性国家标准 该标准将从以下方面全面提升移动电源安全性&#xff1a; 1. 拟在GB 31241、GB 4943.1基础上&#xff0c;新增或加严过充电、针刺等试验要求。 2. 拟提出影响电池安全的正负极材料、隔膜等关键材料要求。 3. 拟规范锂离子电池…

Linux Regulator 子系统核心逻辑与关键问题全解析

Linux Regulator 子系统核心逻辑与关键问题全解析 一、什么是 regulator 子系统&#xff1f;核心作用&#xff1f; regulator 子系统是 Linux 内核为板级/SoC 多路可控电源设计的统一电源管理框架。它的主要作用是&#xff1a; 为每一路可控电源&#xff08;Buck、LDO、DCDC …

制造业官网3D应用,让产品会“说话”

在当今数字化时代&#xff0c;装备制造业正经历着前所未有的变革。随着消费升级和国内经济的蓬勃发展&#xff0c;中国社会的经济格局从传统的“工业经济”向多元化的“服务经济”转型。装备制造业作为制造业与服务业融合的核心领域&#xff0c;积极探索全新的“服务化”发展模…

SCAU15--气球狂欢节

15 气球狂欢节 Time Limit:1000MS Memory Limit:65535K 题型: 编程题 语言: G;GCC 描述&#xff1a; 一个充满魔法的国度中&#xff0c;存在一场年度的节日&#xff0c;名为“气球狂欢节”。在这个节日中&#xff0c;有一个传统的比赛&#xff0c;那就是“气球挑战赛”…

python打卡day56@浙大疏锦行

知识点回顾&#xff1a; 假设检验基础知识 原假设与备择假设P值、统计量、显著水平、置信区间 白噪声 白噪声的定义自相关性检验&#xff1a;ACF检验和Ljung-Box 检验偏自相关性检验&#xff1a;PACF检验 平稳性 平稳性的定义单位根ADF检验: 越小越平稳 季节性检验 ACF检验序列…

采集文章+原创AI处理+发布网站详细教程

简数采集器是新一代的网站文章采集和发布平台&#xff0c;完全在线配置和使用云采集&#xff0c;功能强大&#xff0c;操作简单&#xff0c;配置快捷高效。 简数不仅提供网页文章采集、数据批量处理、定时采集、定时定量自动发布等基本功能&#xff0c;还集成强大的SEO工具与接…

Hystrix超时降级机制全解析

Hystrix的超时降级实现主要通过以下核心机制完成&#xff0c;结合配置、注解和Fallback逻辑实现服务容错&#xff1a; 1. 超时触发条件 默认超时时间&#xff1a;Hystrix默认超时阈值为1秒&#xff0c;超过该时间未响应则触发降级。自定义配置&#xff1a;可通过HystrixComman…

6月份最新代发考试战报:思科华为HCIP HCSE 考试通过

6月份最新代发考试战报&#xff1a;思科华为HCIP HCSE 考试通过 H19-423 HCSA-Presales-IP Network 数通考试通过&#xff0c; H12-725 HCIP-Security安全 考试通过&#xff0c;H13-121 HCIP-Kunpeng Application Developer鲲鹏计算 考试通过&#xff0c;CCNP 350-401考试通过…

谈谈我的软考经历

我 2020 年高考进入大学&#xff0c;软件工程专业&#xff0c;去年&#xff08;24年7月&#xff09;毕业开始工作。我实习是在一家云计算公司&#xff0c;公司内部对软考的证书没有什么激励或补助之类的&#xff0c;我也一直认为计算机嘛&#xff0c;“talk is cheap&#xff0…

CVPR 2025革命性突破!可变形Mamba,刷新SOTA记录!

CVPR 2025上&#xff0c;众多创新研究展示了Mamba在图像分类、目标检测、语义分割等多个任务中的卓越表现。其中&#xff0c;可变形Mamba的最新研究成果正在不断刷新我们对视觉任务性能的认知。大连理工大学发布的DefMamba通过可变形扫描策略动态调整扫描路径&#xff0c;优先关…

蜂鸟代理IP+云手机:跨境电商多账号运营的“隐形风控引擎”

在亚马逊、TikTok Shop等平台的严苛风控下&#xff0c;跨境电商多账号运营长期面临“设备关联封号”“IP污染限流”“地域画像矛盾”三大痛点。传统方案账号存活率不足35%&#xff0c;而蜂鸟代理IP与云手机技术的协同&#xff0c;通过IP层隔离设备层虚拟化行为层仿真三重防护&a…

Boss:组件

能帮到你的话&#xff0c;就给个赞吧 &#x1f618; 文章目录 组件Event Begin Play获取 Owner&#xff1a;不会报错吗&#xff0c;组件初始化的时候 Owner还不存在吧 Attack General&#xff1a;Boss普通攻击不可以连续触发&#xff1a;只有在当前动作为NoAction时才可以攻击 …

供应链数据可视化大屏

在全球化与数字化转型的双重浪潮下&#xff0c;供应链管理正面临前所未有的挑战&#xff1a;黑天鹅事件频发、多环节协同效率低下、库存与成本难以平衡……如何让供应链更透明、更敏捷、更具韧性&#xff1f;供应链数据可视化大屏应运而生&#xff0c;成为企业破解管理痛点的关…

XML读写数据-XPATH用法,快速定位元素

在XPath查询效率对比中&#xff0c;两种方式的性能差异如下&#xff1a; ‌绝对路径方案‌ /configuration/system.applicationHost/sites/site[nameWebSite1] 直接通过文档层级导航&#xff0c;避免全局扫描适合已知完整路径结构的场景&#xff0c;解析速度最快13 ‌相对路径…

Python 多版本与开发环境治理架构设计

Python 多版本治理理念&#xff08;Windows 平台 零基础友好&#xff09;-CSDN博客 Python 多版本开发环境治理&#xff1a;理论架构与实践-CSDN博客 Python 开发环境全栈隔离架构&#xff1a;从 Anaconda 到 PyCharm 的四级防护体系-CSDN博客 【零基础】Python 多版本虚拟环境…

IDE如何快速切换JLINK版本

JLINK是比较常用的调试器&#xff0c;因为产品维护&#xff0c;我们的电脑上可是装了好几个版本的JLINK&#xff0c;怎么进行快速的切换呢&#xff1f;方法如下&#xff1a; 1、使用Everything工具搜索JLinkDLLUpdater.exe&#xff0c;找到当前需要使用的JLINK版本安装目录下的…

WebSocket单例模式实现与使用

提示&#xff1a;记录工作中遇到的需求及解决办法 文章目录 前言一、代码二、功能说明三、使用场景 前言 前端通过WebSocket的单例模式实现实时通信效果 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、代码 export default class SocketService …