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
英文地址,請注明出處:http://en.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 …