亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Spring Boot實(shí)戰(zhàn):從零搭建AI對話服務(wù),SSE流式響應(yīng)與上下文管理全解析

Spring Boot實(shí)戰(zhàn):從零搭建AI對話服務(wù),SSE流式響應(yīng)與上下文管理全解析 坦白說我最早做AI對話服務(wù)的時(shí)候一度以為核心難點(diǎn)在怎么把請求發(fā)出去上。后來真正把代碼跑起來、把服務(wù)丟給真實(shí)用戶用了幾個(gè)月才意識到發(fā)請求只是最簡單的一步。真正的坑全在流式響應(yīng)處理、上下文存儲、超時(shí)控制、成本管理這些周邊工程上。這篇文章就把我從零搭建一個(gè)基于Spring Boot的AI對話服務(wù)的完整過程寫出來包括每一步為什么這么選型、哪個(gè)環(huán)節(jié)最容易出bug、以及我實(shí)際踩過的坑。需要先說明一點(diǎn)這篇文章不是給你貼一堆代碼就完事的教程。我會把核心鏈路拆開從HTTP客戶端選型講到SSE流式解析從上下文管理講到異常處理和成本控制。讀完你可以照著重現(xiàn)一個(gè)能用的AI對話服務(wù)也能理解背后每一個(gè)設(shè)計(jì)決策的理由。1. 這篇文章要解決什么問題1.1 現(xiàn)在的AI集成教程普遍存在什么問題市面上講Spring Boot接入OpenAI API的文章我看了很多大致分兩類。一類是Hello World型用官方SDK配一個(gè)RestTemplate請求把返回的JSON打個(gè)日志就結(jié)束了。這種代碼離能用的服務(wù)差了十萬八千里——沒有流式輸出、沒有上下文管理、沒有超時(shí)兜底、沒有成本控制前端用戶只能看到轉(zhuǎn)圈圈等兩三秒后一次性彈出一大段文字。另一類是痛苦封裝型一上來就給你搞一個(gè)抽象工廠、策略模式、多級緩存、消息隊(duì)列看得人頭皮發(fā)麻。這些代碼確實(shí)很工程化但你要真照著抄大概率會被一堆無關(guān)復(fù)雜性淹沒根本搞不清核心鏈路是哪條。你會發(fā)現(xiàn)真正缺的是那種從HTTP協(xié)議層面講清楚、不堆砌抽象、也不停留在玩具層面的中間態(tài)教程。我這篇文章想補(bǔ)的就是這個(gè)空檔。1.2 讀完這篇文章你能得到什么我會帶你完成一個(gè)完整的AI對話服務(wù)具體包括一個(gè)能獨(dú)立運(yùn)行的Spring Boot 3.x工程對外暴露POST /chat接口基于OkHttp的流式調(diào)用OpenAI Chat Completions接口的能力支持SSE增量輸出一套基于Redis的對話上下文存儲方案包含歷史裁剪和token成本控制完善的超時(shí)、錯(cuò)誤分類、重試和前端斷連處理策略前后端聯(lián)調(diào)時(shí)SSE數(shù)據(jù)的正確解析方式以及Nginx緩沖、中文亂碼這些真實(shí)環(huán)境問題。文章會以實(shí)戰(zhàn)代碼為主線所有代碼都是我實(shí)際跑通、能用、可上生產(chǎn)的版本。為了不讓文章變成純代碼搬運(yùn)我會在每個(gè)關(guān)鍵節(jié)點(diǎn)解釋為什么這么做以及如果不這么做會怎樣。1.3 我的技術(shù)背景與選型立場先交代一下我的技術(shù)背景免得大家對接下來的選型有疑問。我日常主力是Java開發(fā)Spring Boot從 2.x 用到 3.x服務(wù)端接口開發(fā)、中間件封裝這些做過不少。OpenAI接口這邊從最早的純文本補(bǔ)全text-davinci-003時(shí)代到現(xiàn)在的gpt-3.5-turbo、gpt-4o系列都在用也經(jīng)歷過官方SDK、第三方封裝、裸HTTP請求這三種方式來回切換的折騰。先說結(jié)論如果你要做的只是一個(gè)輕量級的AI對話服務(wù)直接用Spring Boot加一個(gè)OkHttp客戶端調(diào)HTTP流式接口是性價(jià)比最高、維護(hù)成本最低的方案。官方SDK雖然封裝好了DTO和流式解析但它在Spring生態(tài)下的線程模型、響應(yīng)式流處理上并沒有給你省太多事反而引入了一層黑盒。即便你說我用Spring的WebClient做流式請求我也建議你先搞清楚最原生的HTTP流式解析是怎么回事再去用高級封裝。理解了底層上層封裝都是紙老虎。整個(gè)項(xiàng)目下來核心就四件事一個(gè)足夠穩(wěn)定的HTTP客戶端選型對比我會聊一個(gè)能正確處理SSE流式數(shù)據(jù)的解析器這是最容易出bug的地方一套管理對話上下文的機(jī)制怎么控制token成本、怎么防止上下文無限膨脹一個(gè)合理的錯(cuò)誤處理與超時(shí)策略網(wǎng)絡(luò)請求永遠(yuǎn)要假設(shè)會失敗。下面開始動手。2. 項(xiàng)目初始化與依賴選型為什么我不用官方SDK2.1 最小工程結(jié)構(gòu)我建的是個(gè)標(biāo)準(zhǔn)的Spring Boot 3.x工程Java 17Maven構(gòu)建。項(xiàng)目結(jié)構(gòu)非常簡單ai-chat-service ├── pom.xml ├── src/main/java/com/example/aichat │ ├── AichatApplication.java // 啟動類 │ ├── controller │ │ └── ChatController.java // 對外HTTP接口 │ ├── service │ │ └── OpenAiChatService.java // 核心對話邏輯 │ ├── config │ │ └── OpenAiConfig.java // 讀取配置組裝HTTP客戶端 │ └── dto │ ├── ChatRequest.java │ └── ChatResponse.java └── src/main/resources └── application.yml // 密鑰、模型、超時(shí)等配置這里我把配置、控制層、服務(wù)層全部分離不是為了炫技而是因?yàn)楹罄m(xù)加鑒權(quán)、加會話管理、加日志時(shí)分層會省很多事。你如果只寫個(gè)Demo自然可以全塞一個(gè)類里但既然標(biāo)題說了從零搭建一個(gè)AI對話服務(wù)我默認(rèn)你是奔著能上生產(chǎn)的目標(biāo)去的所以結(jié)構(gòu)上提前打好底子。2.2 Maven依賴清單及理由pom.xml里我加的核心依賴就三個(gè)其他全是Spring Boot自帶的parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.2.4/version relativePath/ /parent dependencies !-- Web模塊提供Controller和Tomcat -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- OkHttpHTTP客戶端主力 -- dependency groupIdcom.squareup.okhttp3/groupId artifactIdokhttp/artifactId version4.12.0/version /dependency !-- Lombok簡化DTO樣板代碼 -- dependency groupIdorg.projectlombok/groupId artifactIdlombok/artifactId optionaltrue/optional /dependency /dependencies解釋一下為什么這么選為什么是OkHttp而不是Spring自帶的RestTemplate/WebClient先說RestTemplate。它同步阻塞對普通JSON接口夠用但對SSE流式響應(yīng)支持很差ResponseEntity會把整個(gè)響應(yīng)體全部讀進(jìn)內(nèi)存流式解析基本做不了。WebClient雖然支持流式但它基于Reactor響應(yīng)式模型會讓你的代碼從第一行開始就背上響應(yīng)式的復(fù)雜度——如果你整個(gè)項(xiàng)目不是全響應(yīng)式的為了一個(gè)接口引入WebClient非常不劃算。OkHttp的好處在于同步阻塞模型不搞花活、底層連接池成熟、支持超時(shí)精細(xì)控制、讀流式響應(yīng)時(shí)能給你一個(gè)干凈的BufferedSource。我們寫AI對話服務(wù)核心訴求是把流式響應(yīng)一段段實(shí)時(shí)讀出來再轉(zhuǎn)發(fā)給前端OkHttp的ResponseBody.byteStream()配合BufferedReader非常好使。為什么不用官方 openai-java SDK官方SDK包括OpenAI自己出的和社區(qū)維護(hù)的openai-java解決的問題是讓Java開發(fā)者快速調(diào)用OpenAI接口而不需要關(guān)心HTTP細(xì)節(jié)。但用下來有三個(gè)問題版本迭代快接口變動頻繁跟Spring的依賴管理經(jīng)常打架它內(nèi)部用了自己的JSON序列化和HTTP框架出了問題不好排查如果你想調(diào)底層參數(shù)比如自定義HTTP代理、更細(xì)粒度的超時(shí)、攔截器反而要繞很多彎。在我實(shí)踐過的方案里裸HTTP調(diào)用 自己解析是透明度和可控性最好的。OpenAI的接口本身非常干凈POST一個(gè)JSON拿到一個(gè)JSON或SSE流沒有任何必須依賴SDK才能用的高級特性。2.3 配置文件密鑰和參數(shù)都放這里application.yml里我放了以下配置server: port: 8080 openai: api-key: ${OPENAI_API_KEY:sk-your-key-here} # 強(qiáng)烈建議用環(huán)境變量別硬編碼 model: gpt-4o-mini base-url: https://api.openai.com/v1 temperature: 0.7 max-tokens: 1024 timeout-seconds: 60 connect-timeout-seconds: 10為什么把超時(shí)單獨(dú)拆出來因?yàn)檫@是集成OpenAI接口時(shí)最容易被忽視的坑之一。OpenAI接口的響應(yīng)時(shí)間波動很大普通JSON接口一般1-2秒返回但流式接口在輸出長文時(shí)可能要幾十秒如果你用默認(rèn)的5秒超時(shí)基本必掛。connect-timeout和read-timeout要分開設(shè)置前者負(fù)責(zé)建立連接后者負(fù)責(zé)等待每個(gè)數(shù)據(jù)塊。3. 核心HTTP調(diào)用層把SSE流式響應(yīng)的骨髓都啃明白3.1 從一次普通Chat Completion請求說起先明確一下OpenAI Chat Completions接口的基本協(xié)議。它有兩種response形式非流式一次性返回完整JSON里面包含choices[0].message.content這是最終結(jié)果。流式請求體里加stream: true服務(wù)端就會通過SSEServer-Sent Events一幀一幀地推送數(shù)據(jù)每幀是一段增量內(nèi)容格式長這樣data: {id:chatcmpl-xxx,object:chat.completion.chunk,choices:[{delta:{content:你},index:0}]} data: {id:chatcmpl-xxx,object:chat.completion.chunk,choices:[{delta:{content:好},index:0}]} data: [DONE]這個(gè)格式理解起來很簡單每一塊數(shù)據(jù)以data:開頭后面跟著JSON用兩個(gè)換行分隔每條數(shù)據(jù)最后用一個(gè)data: [DONE]標(biāo)記流結(jié)束。SSE的好處是用戶不需要等全部內(nèi)容生成完才能看到回復(fù)而是邊生成邊顯示體驗(yàn)上像打字機(jī)一樣。這也是ChatGPT網(wǎng)頁版的核心交互模式。我們把對話服務(wù)接入到自己的產(chǎn)品里時(shí)這個(gè)特性基本是必須的——讓用戶盯著空白頁面轉(zhuǎn)圈3秒和讓用戶看到文字一個(gè)個(gè)蹦出來體驗(yàn)完全兩個(gè)檔次。理解了協(xié)議實(shí)現(xiàn)起來就清晰了。我先把請求體構(gòu)造出來public MapString, Object buildRequestBody(String userMessage, ListMapString, String history) { MapString, Object body new HashMap(); ListMapString, String messages new ArrayList(); // 歷史上下文比如系統(tǒng)角色設(shè)定 之前的對話 messages.add(Map.of(role, system, content, 你是一個(gè)樂于助人的AI助手。)); if (history ! null) { messages.addAll(history); } // 當(dāng)前用戶消息 messages.add(Map.of(role, user, content, userMessage)); body.put(model, openAiConfig.getModel()); body.put(messages, messages); body.put(stream, true); body.put(temperature, openAiConfig.getTemperature()); body.put(max_tokens, openAiConfig.getMaxTokens()); return body; }這里有個(gè)容易搞錯(cuò)的點(diǎn)OpenAI接口要求messages必須有序順序就是對話的發(fā)生順序。如果你想做多輪對話服務(wù)端是無狀態(tài)的它不幫你記上下文你需要每次請求都把完整的歷史對話傳過去。這個(gè)設(shè)計(jì)讓很多人一開始很不習(xí)慣但只要理解了就明白后續(xù)我們用Redis存上下文時(shí)也會遵循每次請求拼全量歷史的原則。3.2 OkHttp發(fā)起請求并讀取流OkHttp發(fā)請求本身不復(fù)雜但要注意把連接超時(shí)和讀取超時(shí)都調(diào)大。我封裝了一個(gè)方法public Response callChatStream(MapString, Object requestBody, Request.Builder requestBuilder) throws IOException { Request request requestBuilder .url(baseUrl /chat/completions) .post(RequestBody.create(JSON, new JSONObject(requestBody).toString())) .header(Authorization, Bearer apiKey) .header(Content-Type, application/json) .build(); return httpClient.newCall(request).execute(); }注意execute()是同步調(diào)用會阻塞當(dāng)前線程直到響應(yīng)頭到達(dá)但不會阻塞到整個(gè)響應(yīng)體讀完。拿到Response后OpenAI會立刻返回200同時(shí)連接進(jìn)入流式傳輸狀態(tài)。這個(gè)時(shí)候我們才能開始逐行讀取響應(yīng)體。try (Response response callChatStream(...)) { if (!response.isSuccessful()) { log.error(OpenAI API error: {} - {}, response.code(), response.body().string()); throw new RuntimeException(OpenAI API request failed with code response.code()); } BufferedReader reader new BufferedReader( new InputStreamReader(response.body().byteStream(), StandardCharsets.UTF_8) ); String line; while ((line reader.readLine()) ! null) { if (line.startsWith(data:)) { String data line.substring(5).trim(); if ([DONE].equals(data)) { break; } // 解析delta內(nèi)容 JSONObject json new JSONObject(data); String delta extractDeltaContent(json); if (delta ! null !delta.isEmpty()) { // 把增量內(nèi)容通過回調(diào)傳給上層 callback.onDelta(delta); } } } }這段代碼就是這個(gè)服務(wù)的心臟。有幾個(gè)細(xì)節(jié)值得展開說第一try (Response response ...)的作用。OkHttp的Response實(shí)現(xiàn)了Closeable及時(shí)關(guān)閉能復(fù)用連接防止連接泄漏。你用try-with-resources包裝讀完流或拋異常都會自動釋放。第二為什么用readLine()而不是read()。SSE協(xié)議規(guī)定每條數(shù)據(jù)以換行符結(jié)束用readLine()天然切分。注意千萬不要用readLine()處理那種最后一條data: [DONE]沒有換行符的極端情況——有些網(wǎng)關(guān)會吞掉末尾的換行你用readLine()可能讀到的是data: [DONE]帶上之前內(nèi)容拼在一起的無換行文本。更穩(wěn)妥的做法是判斷如果這一行以data:開頭就處理否則跳過并且處理流結(jié)束時(shí)服務(wù)端沒發(fā)送[DONE]的情況后面異常處理章節(jié)會講。第三delta解析。choices[0].delta.content這個(gè)字段在不同模型下行為略有不同有的模型在第一次封包里會帶role: assistant后續(xù)封包才帶內(nèi)容content有的模型甚至在delta里直接沒有content字段。所以解析時(shí)要寫一個(gè)健壯的方法private String extractDeltaContent(JSONObject chunk) { if (!chunk.has(choices) || chunk.getJSONArray(choices).isEmpty()) { return ; } JSONObject choice chunk.getJSONArray(choices).getJSONObject(0); if (choice.isNull(delta)) { return ; } JSONObject delta choice.getJSONObject(delta); if (delta.has(content) !delta.isNull(content)) { return delta.getString(content); } return ; }這里我用了基本的JSONObject判斷而不是直接getString(content)就是因?yàn)榭罩岛妥侄稳笔菀撞瓤恿?。我見過不少人在這一步直接NPE或者拿到空字符串導(dǎo)致斷流。3.3 流式響應(yīng)轉(zhuǎn)發(fā)給前端ChunkedResponseBody后端拿到流式增量后下一步就是通過HTTP接口把增量轉(zhuǎn)發(fā)給前端。Spring MVC天然支持text/event-stream格式我們可以直接返回SseEmitter或者用response.getOutputStream()手動寫。我推薦后者原因在于SseEmitter雖然封裝好了但它在處理客戶端斷開、超時(shí)上不夠細(xì)。我自己用的方案是直接在Controller里拿到HttpServletResponse設(shè)置好響應(yīng)頭然后從服務(wù)層的回調(diào)里逐段寫出PostMapping(/chat) public void chat(RequestBody ChatRequest request, HttpServletResponse response) throws IOException { // 設(shè)置SSE響應(yīng)頭 response.setContentType(text/event-stream); response.setCharacterEncoding(UTF-8); response.setHeader(Cache-Control, no-cache); response.setHeader(X-Accel-Buffering, no); // 禁止Nginx緩沖保證實(shí)時(shí)性 PrintWriter writer response.getWriter(); openAiChatService.streamChat( request.getSessionId(), request.getMessage(), delta - { // 將增量封裝成SSE格式寫給前端 writer.write(data: delta \n\n); writer.flush(); } ); }X-Accel-Buffering這個(gè)頭默認(rèn)大家都不太注意但只要你把服務(wù)部署在Nginx后面就必須加。Nginx默認(rèn)會緩沖后端響應(yīng)如果后端是流式輸出沒有這個(gè)頭Nginx會把所有增量攢到一定量才轉(zhuǎn)發(fā)前端看到的依然是卡頓一次性出全。服務(wù)端的streamChat方法內(nèi)部就是我在3.2節(jié)那段讀流邏輯的殼子區(qū)別是把回調(diào)ConsumerString穿進(jìn)去讓Controller層去決定每段內(nèi)容怎么處理。這里有一個(gè)重要注意點(diǎn)流式對話的整個(gè)HTTP請求鏈路會持續(xù)幾十秒中間任何一環(huán)斷開都會導(dǎo)致整個(gè)流中斷。我們在寫回調(diào)時(shí)一定要處理寫入失敗的情況。比如前端用戶刷新頁面斷開了連接你還在往writer里寫數(shù)據(jù)這時(shí)會拋IOException。最穩(wěn)的寫法是給寫操作包一層try-catch捕獲IOException之后主動終止讀取OpenAI流的循環(huán)不然會白白消耗token還拿不到結(jié)果。3.4 非流式接口簡單但同樣有坑流式當(dāng)然是最優(yōu)體驗(yàn)但有些場景只用非流式就夠。比如內(nèi)部系統(tǒng)做一個(gè)批量評論分析功能不在乎實(shí)時(shí)性直接一次請求拿完整結(jié)果。非流式實(shí)現(xiàn)起來更簡單唯一要注意的是響應(yīng)體大小。有些模型輸出超長內(nèi)容時(shí)一次性返回的JSON可能很大如果你用ResponseBody.string()方法把整個(gè)響應(yīng)讀到內(nèi)存再交給JSON解析器內(nèi)存峰值會非常可觀。穩(wěn)妥做法是設(shè)置合理的max_tokens并為這種接口單獨(dú)調(diào)小超時(shí)因?yàn)榉橇魇揭馕吨惚仨毜热纳赏瓴拍玫綌?shù)據(jù)等待時(shí)間可能等于流式時(shí)間的總和。非流式接口的核心代碼public String chatSync(String userMessage) { MapString, Object body buildRequestBody(userMessage, null); body.put(stream, false); // 關(guān)閉流式 Request request buildRequest(body); try (Response response httpClient.newCall(request).execute()) { if (!response.isSuccessful()) { throw new RuntimeException(API error: response.code()); } String respBody response.body().string(); JSONObject json new JSONObject(respBody); return json.getJSONArray(choices) .getJSONObject(0) .getJSONObject(message) .getString(content); } }這個(gè)接口給不給前端都是次要的更多是給后端內(nèi)部邏輯調(diào)用的。我后來給運(yùn)營同事做周報(bào)自動生成工具就是走這個(gè)非流式接口簡單穩(wěn)定掛在定時(shí)任務(wù)里每天跑一次。4. 對話上下文管理為什么說AI對話服務(wù)最容易爛在這一層4.1 OpenAI接口本身不記上下文這是幾乎每個(gè)初次集成的人都會搞混的概念。你調(diào)用/chat/completions傳一段用戶消息OpenAI不會在服務(wù)器端保存任何這個(gè)人之前說過什么。它每次都是無狀態(tài)地根據(jù)你傳的messages數(shù)組決定回答什么。這意味著你想實(shí)現(xiàn)多輪對話就必須自己在服務(wù)端保存對話歷史每輪請求你都得把完整的對話歷史拼進(jìn)請求體對話歷史越長消耗的token越多費(fèi)用越高超出模型上下文窗口長度比如gpt-4o-mini是128k但實(shí)際請求體過大也會報(bào)錯(cuò)請求會直接失敗。很多半路出家的項(xiàng)目第一版能聊怎么做的把用戶每次說的話拼進(jìn)一個(gè)ArrayList永遠(yuǎn)不清理。聊到第50輪每次請求都帶300多輪歷史消息成本爆炸響應(yīng)速度也肉眼可見地變慢。這就是能跑和能用的分水嶺。4.2 會話存儲Redis還是內(nèi)存我們的設(shè)計(jì)里每個(gè)會話sessionId對應(yīng)一段獨(dú)立的歷史。存儲介質(zhì)的選擇取決于你的部署形態(tài)單機(jī)部署Demo演示用ConcurrentHashMapString, ListMapString, String夠了最簡單但服務(wù)重啟就丟上下文也不支持水平擴(kuò)展。多實(shí)例部署要扛真實(shí)流量直接把歷史丟Redis里用List結(jié)構(gòu)存消息序列。每次對話后把最新的用戶消息和助手回復(fù)推入列表請求前把整個(gè)列表讀出來。我建議你即使在Demo階段也盡量用Redis因?yàn)楹竺孢w移的成本很低而且能順便學(xué)會怎么在Spring Boot里操作Redis存取JSON列表。這里把用Redis存上下文的方案貼出來public ListMapString, String getHistory(String sessionId) { // 從Redis讀取列表每個(gè)元素是一條消息 ListString rawList redisTemplate.opsForList().range(chat:history: sessionId, 0, -1); if (rawList null || rawList.isEmpty()) { return new ArrayList(); } ListMapString, String messages new ArrayList(); for (String raw : rawList) { messages.add(JSON.parseObject(raw, new TypeReferenceMapString, String() {})); } return messages; } public void appendMessage(String sessionId, String role, String content) { MapString, String msg Map.of(role, role, content, content); redisTemplate.opsForList().rightPush(chat:history: sessionId, JSON.toJSONString(msg)); }這里有幾個(gè)要注意的設(shè)計(jì)點(diǎn)設(shè)置過期時(shí)間。會話列表一定要設(shè)置TTL比如30分鐘沒人聊就自動清理。不設(shè)TTL的Redis key會永久膨脹我見過生產(chǎn)環(huán)境一個(gè)月沒清理單個(gè)key里塞了幾萬條消息。別把系統(tǒng)提示詞存進(jìn)會話歷史。系統(tǒng)提示詞system role是每次都固定要傳的你應(yīng)該在構(gòu)建請求時(shí)單獨(dú)往最前面插入而不是跟著歷史一起存。否則歷史列表里會有很多條system消息的重復(fù)浪費(fèi)token。控制歷史長度。當(dāng)對話輪次很多時(shí)得有一個(gè)裁剪策略。常規(guī)做法是只保留最近N條對話我一般設(shè)20條也就是最近10輪。裁剪時(shí)先從頭部丟掉舊消息保證messages的開頭是system角色。4.3 Token成本控制與上下文截?cái)嗖呗粤牡缴舷挛木筒坏貌惶醫(yī)oken成本。OpenAI按token計(jì)費(fèi)gpt-4o-mini的輸入和輸出價(jià)格不一樣長聊天的token消耗幾乎是線性增長的。這里分享我常用的一個(gè)省錢技巧按字符估算token數(shù)。英文場景約1個(gè)token對應(yīng)4個(gè)字符中文場景1個(gè)漢字約等于1-2個(gè)token。粗算時(shí)直接記總字符數(shù)除以3或除以4即可。有了估算值就能在請求前做一次ensureTokenLimit檢查private static final int MAX_CONTEXT_TOKENS 8000; // 根據(jù)模型上下文窗口和預(yù)算設(shè)定 public void appendMessageWithTrimming(String sessionId, String role, String content) { appendMessage(sessionId, role, content); // 裁剪歷史 trimHistory(sessionId); } private void trimHistory(String sessionId) { ListMapString, String history getHistory(sessionId); int totalChars 0; int fromIndex 0; // 從最新消息往前數(shù)保留最近MAX_CONTEXT_TOKENS內(nèi)的消息 for (int i history.size() - 1; i 0; i--) { totalChars history.get(i).get(content).length(); if (totalChars MAX_CONTEXT_TOKENS * 4) { fromIndex i 1; break; } } if (fromIndex 0) { // 刪除fromIndex之前的消息 redisTemplate.opsForList().trim(chat:history: sessionId, fromIndex, -1); } }這里的邏輯是從最新的消息往前累加字符數(shù)一旦超過閾值就把更早的消息從Redis里trim掉。注意opsForList().trim(start, end)是保留區(qū)間內(nèi)的元素我們要保留的是[fromIndex, -1]到最后所以start傳fromIndexend傳-1。這個(gè)策略雖然粗糙但已經(jīng)能解決80%的問題文件存儲有上限就不會無限膨脹請求體不會過大成本可控。如果要更精細(xì)可以每次請求前調(diào)用OpenAI的tokenizer接口做精確計(jì)數(shù)但說實(shí)話在量上來之前那點(diǎn)精度不值得引入額外依賴和網(wǎng)絡(luò)請求。4.4 多輪對話鏈路打通一次完整請求的時(shí)序把前面所有零件拼起來一次完整的多輪對話請求時(shí)序是這樣的前端發(fā)送POST /chat請求體包含sessionId和messageController解析請求調(diào)用streamChat(sessionId, message, callback)Service從Redis讀取該會話的歷史消息列表在歷史列表最前面插入system角色消息再追加當(dāng)前用戶消息構(gòu)造HTTP請求體以stream: true方式調(diào)用OpenAI Chat Completions接口同步等待響應(yīng)后逐行解析SSE流每拿到一段增量就調(diào)用回調(diào)Controller的回調(diào)把增量寫入SSE響應(yīng)流并flush給前端流結(jié)束[DONE]后Service把本次用戶消息和助手完整回復(fù)保存回Redis并執(zhí)行上下文裁剪。第8步有個(gè)細(xì)節(jié)值得強(qiáng)調(diào)保存回復(fù)時(shí)存的是完整回復(fù)不是流式增量拼接的中間結(jié)果。你需要在Service內(nèi)部維護(hù)一個(gè)StringBuilder把每次onDelta拿到的內(nèi)容追加進(jìn)去流結(jié)束得到完整文本再寫入Redis。如果你圖省事在回調(diào)里直接存增量以后做上下文拼接時(shí)Redis里存的會是碎成渣的片段。5. 異常處理、超時(shí)與重試網(wǎng)絡(luò)請求永遠(yuǎn)要假設(shè)會失敗5.1 OpenAI接口會返回的幾種錯(cuò)誤我實(shí)際遇到過的OpenAI API錯(cuò)誤大致分四類每類的處理方式完全不同錯(cuò)誤類型典型場景HTTP狀態(tài)碼處理策略鑒權(quán)失敗API Key錯(cuò)誤、過期401直接報(bào)錯(cuò)提示檢查密鑰不要重試余額或配額不足賬戶余額為0、觸發(fā)速率限制429如果是收費(fèi)限制可稍后重試如果是余額不足則停止調(diào)用并告警請求參數(shù)錯(cuò)誤模型不存在、messages格式不對、context過長400記錄請求體日志人工排查服務(wù)端異常OpenAI內(nèi)部故障500/503指數(shù)退避重試2-3次注意429里的一個(gè)細(xì)節(jié)OpenAI返回的Retry-After頭會告訴你要等多久一定要尊重它。我見過有人寫死固定間隔3秒重試結(jié)果因?yàn)閷Ψ浇ㄗh等待60秒3秒重試毫無意義。5.2 超時(shí)參數(shù)調(diào)優(yōu)從5秒到60秒的踩坑記錄超時(shí)是流式接口最坑的環(huán)節(jié)。Spring Boot默認(rèn)的RestTemplate超時(shí)是無限等待OkHttp默認(rèn)沒有讀取超時(shí)。聽起來無限等待很安全不一旦OpenAI端連接建立后不傳數(shù)據(jù)這種情況在高峰期出現(xiàn)過你的線程就永久掛住連接池被占滿整個(gè)服務(wù)雪崩。我踩過一次很深的坑上線一周后某天下午大量用戶反饋轉(zhuǎn)圈很久沒反應(yīng)一查線程池幾十個(gè)線程全阻塞在readLine()上。原因就是OpenAI端某次升級時(shí)個(gè)別請求30秒不吐數(shù)據(jù)。后來我把讀取超時(shí)設(shè)置為60秒同時(shí)新增了看門狗機(jī)制——如果連續(xù)15秒沒有收到任何數(shù)據(jù)塊主動中斷這次請求并返回友好提示。實(shí)現(xiàn)看門狗的方法不復(fù)雜在流讀取循環(huán)里記錄lastDataTimelong lastDataTime System.currentTimeMillis(); while ((line reader.readLine()) ! null) { if (line.startsWith(data:)) { lastDataTime System.currentTimeMillis(); // 有數(shù)據(jù)就刷新 // ... 處理數(shù)據(jù) } // 每次循環(huán)檢查空閑時(shí)間 if (System.currentTimeMillis() - lastDataTime IDLE_TIMEOUT_MS) { log.warn(SSE stream idle timeout, aborting...); break; } }這個(gè)15秒空閑超時(shí)比整體60秒讀取超時(shí)更早觸發(fā)能更快暴露上游問題也不用等滿60秒。線程不會傻等用戶體驗(yàn)也更好。5.3 重試策略冪等與非冪等的區(qū)別對OpenAI接口做重試時(shí)必須區(qū)分兩次重試的場景請求發(fā)出后沒收到響應(yīng)連接級失敗這時(shí)候OpenAI可能已經(jīng)處理了請求并在返回結(jié)果只是你這邊連接斷了。如果盲目重試用戶可能收到兩次回答如果你是有狀態(tài)寫入的話或者被重復(fù)計(jì)費(fèi)。這種場景下重試要保守甚至不重試直接告訴用戶網(wǎng)絡(luò)波動請重試。請求發(fā)出前失敗鑒權(quán)、參數(shù)錯(cuò)誤這類不涉及計(jì)費(fèi)重試是安全的。我在代碼里的做法是只對建立連接失敗和5xx服務(wù)端錯(cuò)誤做最多一次重試對429要看Retry-After如果它要求等待的時(shí)間小于5秒就等完重試一次超過5秒就直接放棄。核心思路是寧可少做一次接口調(diào)用也不要讓用戶重復(fù)交費(fèi)。5.4 中斷與斷流前端斷開后如何止損流式場景里前端主動斷開是常態(tài)。用戶問了一個(gè)問題又不想等了直接關(guān)掉頁面或者瀏覽器網(wǎng)絡(luò)抖動SSE連接斷開。服務(wù)端如果沒感知到這個(gè)斷開會繼續(xù)從OpenAI拉流直到整段內(nèi)容全部生成完畢。這在token費(fèi)用上是實(shí)打?qū)嵉睦速M(fèi)。Spring的HttpServletResponse在客戶端斷開后再寫數(shù)據(jù)會拋IOException。所以正確的止損姿勢是在回調(diào)里捕獲IOException然后觸發(fā)一個(gè)取消令牌機(jī)制來終止后續(xù)的拉流。我的實(shí)現(xiàn)是在streamChat方法里傳入一個(gè)AtomicBoolean cancelled作為協(xié)作信號void streamChat(String sessionId, String message, ConsumerString callback) { AtomicBoolean cancelled new AtomicBoolean(false); // 包裝回調(diào)寫失敗就取消 ConsumerString wrappedCallback delta - { try { callback.accept(delta); } catch (IOException e) { log.warn(Client disconnected, cancelling stream); cancelled.set(true); } }; // 拉流循環(huán)里檢查cancelled while ((line reader.readLine()) ! null !cancelled.get()) { // ... } }這個(gè)模式很實(shí)用回調(diào)只負(fù)責(zé)寫數(shù)據(jù)通過異常信號傳遞客戶端已斷的狀態(tài)拉流循環(huán)看到狀態(tài)就主動break終止向OpenAI拉取后續(xù)數(shù)據(jù)。這樣既能止損又能保證線程不繼續(xù)空轉(zhuǎn)。6. 前后端聯(lián)調(diào)與真實(shí)體驗(yàn)一個(gè)能用的AI對話服務(wù)長什么樣6.1 前端SSE接入EventSource和POST的局限前端接入SSE最省事的API是EventSource。但有個(gè)天然限制EventSource只支持GET請求不支持自定義Headers。而我們的接口是POST /chat攜帶消息體還得在Authorization頭里加自定義信息如果有的話所以直接用EventSource不行。我實(shí)際用的方案是前端用fetch發(fā)起POST拿到ReadableStream響應(yīng)體再逐段解析流async function sendChat(message, sessionId) { const response await fetch(/chat, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify({sessionId, message}) }); const reader response.body.getReader(); const decoder new TextDecoder(utf-8); let buffer ; while (true) { const {value, done} await reader.read(); if (done) break; buffer decoder.decode(value, {stream: true}); // 按空行切分SSE數(shù)據(jù) const lines buffer.split(\n\n); buffer lines.pop(); // 最后一段可能不完整留到下次 for (const line of lines) { if (line.startsWith(data: )) { const data line.substring(6); if (data [DONE]) return; // 渲染到界面上 appendText(data); } } } }這段代碼在前端有一個(gè)很重要的點(diǎn)SSE數(shù)據(jù)是按\n\n分隔的但網(wǎng)絡(luò)包可能會把一個(gè)完整數(shù)據(jù)塊拆成兩半所以你必須維護(hù)一個(gè)buffer變量合并跨包的數(shù)據(jù)。我見過很多前端同學(xué)直接reader.read()一次就解析結(jié)果內(nèi)容經(jīng)常出現(xiàn)殘缺或亂碼原因就在這里。6.2 聯(lián)調(diào)中常見的三類問題把服務(wù)部署好、前端接好以后聯(lián)調(diào)階段會出現(xiàn)一些看起來很奇怪的問題我列三個(gè)最典型的第一Nginx緩沖導(dǎo)致假卡頓。前端明明看到后端日志里delta嘩嘩地出但頁面上就是不顯示過個(gè)十幾秒突然全出來了。前面提過加上X-Accel-Buffering: no響應(yīng)頭就能解決。如果你用的不是Nginx而是Apache或者云負(fù)載均衡也要查對應(yīng)平臺的緩沖設(shè)置。第二中文亂碼。這是一個(gè)非常常見但相對低級的問題。Spring Boot默認(rèn)的Content-Type在響應(yīng)SSE時(shí)可能不帶charsetUTF-8然后前端按UTF-8解析沒問題但某些代理服務(wù)器會自作聰明地轉(zhuǎn)成ISO-8859-1。我在代碼里強(qiáng)制設(shè)置了response.setCharacterEncoding(UTF-8)并且在拼SSE數(shù)據(jù)時(shí)注意不要用write(String)而是直接用write(String)其實(shí)在設(shè)置了字符編碼后這個(gè)是OK的。最關(guān)鍵的是POST請求體解析時(shí)RequestBody默認(rèn)的JSON解析器不會亂碼但如果你的服務(wù)用表單方式接收消息務(wù)必在Controller上加produces text/event-stream;charsetUTF-8。第三冪等重試導(dǎo)致重復(fù)內(nèi)容。這個(gè)聯(lián)調(diào)時(shí)很難發(fā)現(xiàn)但真實(shí)用戶一多就會暴露。比如用戶網(wǎng)絡(luò)抖動瀏覽器自動重發(fā)POST后端收到兩個(gè)相同的消息于是AI回答了兩遍。解決辦法是前端在發(fā)起請求時(shí)加一個(gè)requestId后端用Redis的SETNX做冪等去重——同一個(gè)requestId的請求只處理一次。這個(gè)機(jī)制我在生產(chǎn)環(huán)境里是必須的。6.3 成品展示與性能觀察功能調(diào)通之后我在本地壓了一輪。用JMeter模擬20個(gè)并發(fā)用戶同時(shí)聊天每個(gè)請求都會持續(xù)5-10秒的流式輸出觀察了幾個(gè)關(guān)鍵指標(biāo)Tomcat線程池占用配置了server.tomcat.threads.max20020并發(fā)下線程池很穩(wěn)但如果是100并發(fā)你需要考慮用虛擬線程JDK21 Spring Boot 3.2支持的spring.threads.virtual.enabledtrue來提升吞吐因?yàn)槊總€(gè)流式請求會占一個(gè)線程很長時(shí)間。連接池健康OkHttp默認(rèn)的連接池最大空閑連接是5個(gè)長連接復(fù)用做得不錯(cuò)。但注意到如果超時(shí)設(shè)置過大連接池里通到OpenAI的空閑連接會堆積建議加一個(gè)空閑連接清理的ConnectionPool配置。內(nèi)存增長因?yàn)槊總€(gè)流式請求都維護(hù)一個(gè)StringBuilder如果并發(fā)高且回復(fù)長瞬時(shí)內(nèi)存會漲得比較快。我后來把StringBuilder改成有上限的——當(dāng)累計(jì)超過設(shè)定的maxTokens * 2字符數(shù)時(shí)就不再向OpenAI拉流強(qiáng)制截?cái)喈?dāng)前回復(fù)并返回內(nèi)容過長已截?cái)?。這輪壓測正好印證了一開始的判斷流式對話服務(wù)瓶頸不在OpenAI的接口能力而在你自己的線程模型和連接管理。7. 進(jìn)階優(yōu)化緩存、限流、敏感詞過濾與可觀測性7.1 請求級緩存同樣的問法第二條路更快AI回答不是每次都要問OpenAI的。實(shí)際業(yè)務(wù)里有很多高頻相似問題——比如產(chǎn)品官網(wǎng)的FAQ用戶翻來覆去問那幾個(gè)問題。這些完全可以用緩存打掉。我的緩存設(shè)計(jì)是以用戶消息的哈希值模型名作為key結(jié)果緩存到Redis里TTL設(shè)24小時(shí)。但AI問答和普通接口不太一樣很多問題雖然字面上不同語義卻相似所以單純哈希緩存命中率有限。更實(shí)用的一層是對話結(jié)果緩存——同一sessionId下如果用戶連續(xù)問相同或幾乎相同的問題編輯距離小于閾值直接返回上一次的緩存結(jié)果不重復(fù)請求API。當(dāng)然做了緩存就要小心一個(gè)副作用緩存會讓AI看起來死板用戶換了措辭但本質(zhì)相同的時(shí)候會得到上一輪答案。這個(gè)在客服場景其實(shí)是優(yōu)點(diǎn)但在創(chuàng)作類場景就是災(zāi)難了。所以緩存開關(guān)做成配置項(xiàng)按場景決定開不開。7.2 限流防止一個(gè)用戶把預(yù)算打光一個(gè)AI對話服務(wù)的成本大頭是token費(fèi)用而用戶是無底洞。不做限流的話某個(gè)用戶連續(xù)瘋狂提問一分鐘調(diào)用幾十次你的賬單會以肉眼可見的速度上漲。我做的限流策略有三個(gè)維度單會話維度一個(gè)sessionId每分鐘最多10次請求超過就返回操作太頻繁請稍后再試。實(shí)現(xiàn)上用Redis INCR EXPIRE計(jì)數(shù)非常簡單可靠。單用戶維度如果是登錄系統(tǒng)按userId限流比如每小時(shí)最多60次。服務(wù)整體維度控制同一時(shí)刻發(fā)往OpenAI的并發(fā)請求數(shù)。注意剛才說的流式請求每個(gè)都占線程幾十秒所以單純的接口并發(fā)限流不夠還要限制連接數(shù)。我用了一個(gè)Semaphore許可數(shù)為連接池maxIdle / 2拿不到許可就排隊(duì)等待。限流觸發(fā)后的返回體驗(yàn)也很重要。限流不等于直接報(bào)錯(cuò)前端應(yīng)該看到AI有點(diǎn)忙請稍后再試這類友好提示。我在Controller里捕獲RateLimitException統(tǒng)一返回429狀態(tài)碼和JSON錯(cuò)誤體前端對這個(gè)狀態(tài)碼做了單獨(dú)處理。7.3 敏感詞過濾AI服務(wù)上線前的必經(jīng)之路AI對話服務(wù)接上真實(shí)用戶之后敏感詞過濾不是可選項(xiàng)是必選項(xiàng)。OpenAI自己的moderation接口可以檢測文本內(nèi)容但它是異步的、返回結(jié)果也有一定延遲不適合在流式輸出中逐段檢測。我采用了兩層方案輸入側(cè)用戶發(fā)送消息后在調(diào)用OpenAI之前先用本地維護(hù)的敏感詞庫做一次匹配過濾。命中就直接拒絕不浪費(fèi)token。詞庫要支持增量更新我用的是一個(gè)SetString從數(shù)據(jù)庫加載服務(wù)器每天刷新一次。輸出側(cè)流式輸出的每一段增量都會經(jīng)過一個(gè)SensitiveWordFilter.filter(delta)方法。命中敏感詞的增量會被打碼替換成***或直接丟棄。這個(gè)方法要足夠快因?yàn)樗诿看蝑elta回調(diào)里都會執(zhí)行不能在熱點(diǎn)路徑上做正則、做慢循環(huán)。說實(shí)話純靠本地詞庫過濾肯定有漏網(wǎng)之魚但作為一道前置防線配合OpenAI的moderation接口做異步復(fù)核已經(jīng)能滿足大多數(shù)國內(nèi)中小團(tuán)隊(duì)的業(yè)務(wù)要求。7.4 可觀測性流式服務(wù)的日志怎么打才有用流式服務(wù)有個(gè)特性響應(yīng)是邊生成邊輸出的所以傳統(tǒng)的開始時(shí)間結(jié)束時(shí)間日志記錄模式在這一場景里價(jià)值不大。想看問題出在哪必須打鏈路日志。我建議至少打這幾類日志請求入口日志sessionId、消息前50個(gè)字符、請求耗時(shí)。這里注意前端拿到的總耗時(shí)應(yīng)該從請求進(jìn)入Controller到最后一個(gè)delta寫出為止。OpenAI服務(wù)耗時(shí)分解日志DNS解析連接建立耗時(shí)、首字節(jié)耗時(shí)TTFB、每1000字符的平均生成耗時(shí)。這些能幫你定位慢到底慢在網(wǎng)絡(luò)還是慢在模型生成。異常鏈路日志流中斷時(shí)記錄中斷前最后輸出的上下文比如中斷發(fā)生在第幾個(gè)字符、模型回答到哪里了。這對排查OpenAI側(cè)問題非常有幫助。打完日志的下一步是接入監(jiān)控告警。我用過Spring Boot Actuator加Prometheus的組合暴露幾個(gè)自定義指標(biāo)openai_requests_total請求總數(shù)區(qū)分結(jié)果標(biāo)簽success/erroropenai_stream_duration_seconds流式響應(yīng)耗時(shí)分布o(jì)penai_tokens_estimate_total估算token消耗總量用于成本監(jiān)控這幾個(gè)指標(biāo)一上賬單和性能就能對上號。我后來給團(tuán)隊(duì)做的成本看板就是直接拉這個(gè)openai_tokens_estimate_total指標(biāo)再乘上單價(jià)每天自動算一個(gè)預(yù)估費(fèi)用比月底看賬單再心疼強(qiáng)多了。8. 寫在最后的實(shí)戰(zhàn)建議8.1 代碼庫演進(jìn)從單體Demo到可擴(kuò)展的服務(wù)這篇文章寫的雖然是個(gè)單體項(xiàng)目但結(jié)構(gòu)上已經(jīng)為演進(jìn)留了接口。如果你后面要支持多個(gè)模型供應(yīng)商比如接入國產(chǎn)模型、開源本地部署模型不要改動OpenAiChatService的核心邏輯而是把調(diào)用哪個(gè)API、如何解析返回抽象成一個(gè)ChatProvider接口。每個(gè)供應(yīng)商實(shí)現(xiàn)一個(gè)ChatProvider通過Spring的Qualifier或策略模式切換。我實(shí)際在公司就是這么設(shè)計(jì)的目前維護(hù)了OpenAI、Anthropic、以及一個(gè)私有化部署模型三個(gè)Provider核心對話鏈路完全沒動過。8.2 成本核算一個(gè)AI對話服務(wù)的月度賬單長什么樣寫到最后分享一個(gè)實(shí)際運(yùn)營數(shù)據(jù)。我之前做過一個(gè)客服智能助手日均調(diào)用約5000次平均每次消耗約1200個(gè)token輸入輸出合計(jì)。以gpt-4o-mini的定價(jià)估算輸入0.15美元/百萬token輸出0.6美元/百萬token假設(shè)輸入輸出各半一個(gè)月token總量約1.8億費(fèi)用大概在70美元上下。如果換用gpt-4o這個(gè)數(shù)字直接翻好幾倍。我的建議是上線初期別迷信最強(qiáng)模型用mini級別的模型把流程跑通、把產(chǎn)品驗(yàn)證完再根據(jù)用戶反饋逐步升級模型。省下來的錢比你在代碼里調(diào)優(yōu)省的那點(diǎn)token多幾個(gè)數(shù)量級。8.3 我踩過最后悔的一個(gè)坑聊到最后分享一個(gè)我記憶最深刻的教訓(xùn)。有一陣子我為了追求極致實(shí)時(shí)體驗(yàn)把整個(gè)對話鏈路全部改成了流式包括內(nèi)部系統(tǒng)之間的調(diào)用也用了流式。結(jié)果某次上游服務(wù)因?yàn)榇abugSSE流一直不發(fā)送[DONE]結(jié)束標(biāo)記我的下游服務(wù)readLine()一直阻塞在等待狀態(tài)連接池被打滿整個(gè)應(yīng)用OOM。那次事故教育我流式協(xié)議雖然體驗(yàn)好但它把請求何時(shí)結(jié)束的控制權(quán)交給了上游如果上游不按規(guī)范結(jié)束流你沒有兜底機(jī)制就會掛掉。所以后來我在所有流式讀取循環(huán)里都強(qiáng)制加了最大持續(xù)時(shí)間限制比如最晚90秒必須斷開管你上游有沒有發(fā)[DONE]到點(diǎn)就斷。這跟TCP連接也有Keep-Alive超時(shí)是一個(gè)道理——不要無限等待任何東西。集成OpenAI API這件事說穿了并不難難的是把網(wǎng)絡(luò)波動、上下文膨脹、成本失控這些真實(shí)的工程問題一一處理掉。希望這篇文章能幫你少走幾個(gè)彎路。接下來你唯一要做的就是打開IDE建一個(gè)項(xiàng)目把第一個(gè)流式對話跑通然后你會發(fā)現(xiàn)后面的一切都順理成章。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
中文字幕丰满子伦无码专区在线视频最新| 欧美性暴力猛交XXXX | 五月婷婷丁香| 亚洲中文字幕av | 麻豆人妻少妇在线免费观看| 浓厚中出中文字幕在线| 欧美人妻中出| 九色在线熟女国产黑人| 精品一二三区女同| 欧美日韩在线国产在线| 亚洲极品| 天堂岛av| www.91理论| 色麻豆AV| 桃色五月天| 青青在线视频日韩欧美| 9久久美女首页| 在线观看高清AV| 欧美日本视频一区| 色老汉色| 亚洲中文日韩欧美大香蕉视频| 综合网天天| 亚洲色9| 男男H黄动漫啪啪无遮挡网站| 天天日天天干天天摸天天操| 69精品少妇一区二区三区蜜桃| 97视频在线观看免费高清| 亚洲美乱| 国产女人91精品嗷嗷嗷嗷| 97干在线| 91精片| 国产久久天堂资源| 超碰精品| 99RE在线视频精品,这里只有精品| 五月天偷拍| 强奸乱伦大香蕉网| 国产成久久综合片| 欧亚揄拍偷拍精品视频| 9久超碰| 久久久成人国产精品无码| 啊啊啊啊啊舒服| 人妻天天夜夜爽一区二区| 天天操天天舔| 99自拍视频在线观看| 久久欲| 精品美女少妇一区二区| 色天堂综合| 1024香蕉视频| 使劲用力艹少妇视频一区二区| 国产亲戚伦亲在线| 久综合国内精品自在自线| 狠狠躁伊人中文字幕| 久久女女| 大香蕉2017| 日韩欧美蜜桃精品久久中文字幕久久| 99999亚洲另类| 99青青草国产视频| 在线黄色污污网站| 伊人久大| 男人的天堂 在线一区| 亚洲高清视频在线免费观看| 超碰超碰超碰超碰的大鸡吧操黑丝袜 | 亚洲激情天堂网| 久久超碰、| 狠狠综合网| 男人的天堂亚洲| 国产高潮AA片免费看| 91午夜无码| 眼镜人妻101.com| 国产综合永久精品日韩鬼片| 歐美一級亂黃99在綫精品| 日韩成人免费电影| av九九| 一本一道vs波多野结衣| 狠狠干狠狠干| 欧美中文狠| 超碰 国产熟女精品一区| 欧美操逼录像国产黄色国产| 一区操逼日比视频| 亚洲av在线免费观看| 美女97超碰| 黑人精品久久97| 成人性交午夜免费片| 98超碰日本| 伊人网在线观看| 精品美女少妇一区二区三区| 国产97色在线 | 亚洲| 久久久亚洲| 浪人综合网| 蜜桃视频精品一区二区| 91精品婷婷国产综合久久| 97天天| 亚洲欧美骚| 波多野结衣一级视频| 狠狠狠狠狠狠| 狠狠爱AV| 免费伦费视频在线观看| 亚洲综合影片| 中国人高清www色视频免费| 嫩草影院在线观看精品| 91/欧美| 丁香色色网| 超硑97精品| 国产精品电| 亚洲天堂精品日韩电影| 国产成人精品日本亚洲语言| 亚洲污一污二| 囯戸精品高潮呻吟旡码| 成人在线视频一区| 多毛小伙内射老太婆| 中文久久久| 国产精品视频自拍在线| 九九热免费国产视频婷婷伊人五月 | 少妇高潮99p| 天天在线91| 亚洲色图尤物视频| 日日干夜夜操视频h| 国产三级片在线观看| 一级A啪啪啪啪| 亚洲天堂区| 久久久成人免费av电影| aⅴ日韩成人电影av在线免费看av大全| 午夜无码精品免费看性色| 99r九九| 208天天久久九九九| 伊人一区二区在线播放| 亚洲天堂自拍| 粉嫩av久久一区二区三区| 青青草亚洲一区| 美欧色综合| 久99久视频精选| 黄久久| 日本性爱网址| 久久精品区| 大香蕉伊人色偷偷在线| 在线人成亚洲视频免费观看| 日本欧美国内在线| 老熟女天天操| 欧美综合第一| 国产日韩精品人妻久久久久色欲网站 | 国产精品视频播放| 美国aaaaa一级黄片| 国产视频小说| 欧美黑人XXXⅩ高潮交| 神马久久久久久久| 色婷婷久久综合超碰| 1级午夜影院费免区| 先锋音影AV| 免费一级视频特黄色大片| 婷婷人妻激情| 久久久久ab| 簧片免费看视频| 国产免费内射视频| 99re69综合| 福利操逼| 亚洲色人| 超碰综合97在线| 欧美亚洲玖玖玖| a片久久久久久久久久久久| 亚洲熟女乱综合一区二区三区| 亚洲欧美自拍偷拍| 亚洲色图91| 狠狠干精品一二三四五六2022| 丰满高潮18xxxx| 91精品久久久久| 有码人妻系列| 免费毛片在线播放| 一区二区三区免费岛国片| 欧美天天干| 精品一区二区三区四区女| 欧美丰满熟妇XXXX性ppX人交| 嗯嗯啊好爽| 91高跟美女在线播放| 日韩一级片| 欧美日韩午夜精品一区二区三区 | 成人av在线播放| 91久久国产精品| 激情终合网| 国产伦精品一区二区三区视频女| 人人干人人搞人人摸| 91被操| 97免费视频在线| 风月影院男女十八禁| 免费观看国产小粉嫩喷水精品午| 天美91| 亚洲第一页综合在线| 日本岛国黄色网址| a级成人毛片免费视频高清| 国产高清自拍| 农村妇女精品一区二区| 欧美色偷拍 | 国色天香av| 久久久免费一级黄片| 成人a v在线播放免费| 亚洲自拍小说| 97 国产精品| 熟女91网| 97ai亚洲| 大香蕉中文在线| 久久亚洲天天做| 久久久婷婷| 国模少妇一区二区三区| 日韩AV熟女乱伦| 亚洲欧美综合区自拍另类| 中国熟女老妇仑乱一区二区三区| 亚洲国产亚洲天堂| 舔人妻中文免费视频| 黄色十八禁| 精品999日本| 男生女生啊啊啊啊| 97这里只精品| 人妻少妇久久| 黄页av| 淫荡网址| Av手机版天堂网| av网站免费线看| 亚洲 欧美 日韩 国产一区二区| 久久精品熟妇丰满人妻99| 国产精品久久久久久久久久久久久久吹 | 六月婷婷综合| 神马精品视频| 大香伊人在线一区| 裸体美女久久久| 天天激色| 偷拍99| 校园春色五月天| AV麻豆免费一区| 天堂а√在线最新版在线| 国产午夜无码片在线观看影视 | 老色鬼成人精品视频下载大在线观看| 亚洲综人网| 日韩一卡二卡三卡| 国产高清免费不卡av| 日本大香蕉| 欧美久久人妻少妇一区二区| 51一区二区三区| 一区二区影视| 翔田千里无码中出中文字幕| 翔田千里av一区二区三区| 五月激情综合网| 爱射综合| 在线另类| 久久久久久91香蕉国产| 后入福利视频| 翔田千里Av在线| 肉嘟嘟www视频在线观看高清| 国产福利第一视频| 亚洲av总站| 无码操逼天堂| 97精| AV 少妇 人妻 偷拍| 裸体女人草逼视频播放一区,二区,三区,四区,五区 | 嫩草美女久久| 天天综合网国产| 中日韩久久人妻一区二区| 91网站在线播放| 91欧美综合| 久久综合国产精品国产| 亚洲美欧999| 国产视频97| 国产精品爱欲| 亚洲精品丝袜-不卡成人免费……| 亚洲美欧999| 日韩成人人妻网站| 欧美1区二区三区公司| 国产精品视频精品一二| 天天摸夜夜操视频| 啪啪视频免费在线观看| 五月综合久久| 国产福利在线视频网站| 国产精品国产自产拍高清AV| 中文视频在线观看| 1024人妻| 成年人免费观看网站| 国产欧美在线观看免费观看| 色婷婷色99国产综合精品| 神马久久中文字幕| 国产精品九九九| 国产激情av女片自拍| 麻豆黄四叶草网站| CCYY草草影院地址入口| 婷婷色一区| 中文字幕第2页| 天天躁日日躁AAA片李宗瑞| 超碰 av 女人天堂| 日韩 国产 欧美自拍| 噜噜在线| 97国产|免费| 国产美女高潮叫床视频| 亚洲图片 激情小说| 成人小说另类在线| 成人五月天色网| 久久精品国产亚洲AV清纯| 亚洲日韩AV视色| 亚洲欧洲激情卡通另类文学四射小说网站 | 岛国毛片手机在线观看| 九九九九九九成人| 日本精品网站在线中文| 夜夜人妻爽| 精品一区二区成人| 亚洲国产精品久久久久婷婷老年| 色九色久| 日本色色网| 变态综合色| 婷婷五月天AV| 乱伦熟女论坛| 久久免费精品视频免一| 久久久少妇诱惑精品视频| 国产色呦呦| 久热网| 91久久久久久久| 国产综合久久久麻桃个| 日本999精品视频| 亚洲无码国产探花在线观看| 999九九精品| 韩国一级做A片免费的| 亚洲天在线| 色老汉玖玖爱| 一级毛片久久久久久久女人18| 国产精品网站免费| 手机在线看片免费人成视频| 唯美清纯 妖精视频| 天天摸,夜夜摸| 五月丁香激情四射| 中文字幕欧美日本乱码一线二线| 亚洲成人性| 粉嫩国产精品久久久| 中国少妇XXXX做受| 美女诱惑一区| www.acm成人黄色毛片| 亚洲中文一区二区三区视频| 黄骗免费网站| 欧美综合 站| 97干在线| 亚洲小电影免费涩涩成人在线高清| 亚洲色情在线影视| 日韩精品一区二区三区四虎影视| 久热影视| 久久久久久久9| 欧洲精品一二三在线| 91丨九色丨大屁股| 日韩欧美大力操| 欧美亚州综合网图片| 欧美视频一| 日本黄色XXX| 欧美熟妇精品黑人巨大一二三区| 久青草影院| 色综合久久av| 人妻一区二区三区四区视频| 91无码精品| AV99热18这里只有精品| 国模限制级电影| 欧美色性爱| 2019天天干| 久久久久久中文| 久久亚洲人妻| 麻豆久久久久久久久丝袜| 性色av婷婷久久一区二区点复制| 国产精品亚洲天堂网址| 97亚洲综合影院| 九九九不卡| 伊人亚洲综合| 2019午夜福利视频| 久久av色| 97香蕉人人乳| 久久伊人网视频一区二区三区| 欧洲熟妇xxXx欧美老妇裸体| 日韩欧美午夜视频在线| 天天躁日日躁成人字幕aⅴ| 蜜臀久久99精品久久久久久酒店 | 激情内射| 国产不卡的视频| 久久超碰大香蕉| 亚洲欧美天堂在线| 蜜臀久久99精品久久久老,,| 丁香九月婷婷| 夂久色| 色婷婷综合网站| 多乙久久久久久| 欧美午夜一区二区三区| 新版天堂中文资源8在线| 免费的很黄很污的全部视频| 国产精品自拍xxxx| 你想操日本小逼吗| 黄色av片三级三级三级免费看| 香蕉热人人精品| 国产日韩手机视频在线| 老司机深夜影院18未满| 亚洲综合一| 蜜臀久久久国产| 伦理弟一页| 性交一区二区在线播放| 亚洲。天堂。日本在线观看| 超碰综合97在线| 超碰9 7女人| 97国产中文| 大香蕉中文201| 91一区二匹| 91被操| 思思热国产在线视频| 欧美日本国产日韩激情视频| 色综合婷婷| 99国产人成精品| 熟妇熟女一区二三区| 超硑97精品| 碰超人人在线一区二区三区| 久久精品国产97欧美精品亚洲| 国产精品禁久久久精品| 亚州一区二区| AV和黑人在线播放| 亚洲欧美成人在线| 色好看av| 久久久精品,3| 国产极品精品美女视频| 欧美日韩99| 中文字幕乱碼在线| 亚洲一区制服诱惑| 中文字幕丰满子伦无码专区在线视频最新 | 视频一区二区三区精品| 激情综合网五月婷婷五月天| 大香交伊人网| 九七毛片九九毛片| 青青在线视频日韩欧美| 91快色色色色色| 五月香婷婷| 欧美日韩国产电影| 日日摸天天爽夜夜欢| 青青草十区九区爱夜| 啊灬啊灬啊灬啊灬高潮奶出了免费视 | 老鸭窝亚洲毛片| 青草视频人妻在线观看| 日本精品五区| 亚洲图片偷拍视频区| 性色高清在线| 欧美亚洲丝袜人妻制服中文99| 色综合V| AA丁香综合激情| 九九国产热| 国产精品人妻无码久久久互動交流 | 久草网站免费在线观看| 一道本东京热加勒比一区二区三区| 成人精品视频| 国产三级在线现体验区| 亚洲天堂中文字幕无码男同| 黄色十八禁| 九九综合九九综合| 99热精品在线| 密臀成人视频久久久| 天天色黄色影院天天操| 亚洲人在线| 欧美色网络| 日本人人操人人操| 人妻酒店出差被中出免费在线播放| 91麻豆天美传媒在线| 五月天黄色激情视频| 躁躁日曰躁2020| 精品国产Av无码久久久伦古装| 六月婷婷色综合| 国产少妇内射| 中文字幕av乱伦| 青青草久久| 人人摸人人添人人操| 中文字幕88av在线| 一级@啪啪视频| 色女综合| 天天躁日日躁AAAAXXXX国产| 99.色网| 天天激色| 99久久精品无码一区二区| 日韩啪啪啪视频| 最新亚洲人成网站在线影院| 亚洲自拍欧美色综合| 老司机天天操| 亚州色图片在线色| 自慰白浆在线观看| 啊啊啊慢点| 亚洲激情av| 激情一区二区| 强上我不卡卡| 性videos欧美熟妇hdx| 大吊色| 超碰在线香蕉| 亚洲影视高清第一页| 无码自拍SM| 九色黄站| 九九热视频这里只有精品| 黄色视频60分钟| 好爽免费视频,| 国产热RE99久久6国产精品首| 久久岛国| 日韩av无码网站| Aa东京男人的天堂| 奇米狠999| 精品乱码在线观看| 爱我干综合| 色欧美亚洲| 国产精品 午夜福利| 色在线亚洲视频www| 人澡逼| 亚洲综合激情五月久久| 亚洲 暴爽 AV人人爽日日碰| 亚洲综合另类色图| 国产不卡精品91| 免费的黄片有限公司| 蜜臀久久精品久久久久视频| A V少妇特黄三级| 成人麻豆av电影网站| 久久9精品| 欧美精品丝袜久久久中文字幕| 操逼www.| 校园春色五月天| 97欧美日韩中文| 婷婷五月天小说| av无线看| 欧美精品宗合| 另类图片五月天| 少妇天堂网络| 久久女婷| 久久精品国产亚洲AV片多多| 人人操欧美风骚| 蜜桃狠狠色伊人亚洲综合 | www.99中文字幕| 好爽视频在线观看视频 | 亚洲春色欧美激情自拍| 久久老熟女| 欧美影音在线| 久久一留热品黄| 色综合五月天| 无码国产精品久久久久| 亚洲国产av中文字幕久久| 夜夜欧美 | 成人影院永久免费观看网址| 人妻久久一区二区三区| 久久蜜桃一区二区| 久久9精品网站| 国产精品网站免费| 久久久影院| 婷婷综合激情| 美女被艹尤物视频| 啪啪资源网| AV天堂国产| 91少妇人妻| 无码二级三级| 女人香蕉久久毛毛片精品| 欧美亚洲宗合色性图| 亚洲综合113页| 亚洲AV无码天美传媒一区| 久久精品99| 久久久久国产一区二| 免费看黄视频亚洲网站| 久久首页| 亚洲91在线播放影院| 中文字幕一区二区三区四区在线视频| 亚洲图片激情小说| 极品销魂美女一区二区| 亚洲色狠| 成年人网站在线免费观看| 粉嫩av平台| 日本韩国国产精品一区| 一级性爱视频免费在线| 天天狠操| 天天干夜夜操网| 色综合久久88色综合久久天天| 伊人久久大香线蕉无码| 亚洲操逼无码| 欧美色婷婷| 天天干少妇| 97香焦色区| 欧美性爱一内片一区二区三区| 女一区二区| 99精品伊人| 98福利在线视频| 99精品丰满人妻无码| 国产熟女自拍| 97干在线视频| 精品人妻一区二区三区四区石在线| 97超碰人人模人人拍人人| 久久亚洲中文字幕视频| 久久国产免费激情视频| 色综合久久88色综合久久天天| 欧美精品1区2区3区| 亚洲综合五月天| 男人天堂.AB| 久久久久亚洲精品| 极品出轨视频网站| 中文AV制服乱伦| 国产AV毛片| 国产成人+综合亚洲+天堂| 亚洲色图久久成人| 亚洲熟久久| 高清无码学生妹高潮| 91天天| 十八岁啪啪视频免费看| 涩五月婷婷| 美女大乳久久久久久久女人18| 午夜无码熟妇丰满人妻| 国产精品剧情| 伦伦成年午夜免费视频| 丰满人妻一区二区三区| 亚州综合图片| 91丨人妻丨国产丨丝袜| 一区二区三区免费岛国片| 中文字暮97| 国产精品久久久久久久免牛肉蒲团| 日韩在线观看AV| 一中国女人毛片水真多| 这里都是精品在线观看| 欧美日韩人人早| 国产91美女视频| 天天干天天燥| 玖玖爱综合| 日日躁夜夜躁狠狠躁超爽| 天天弄天天操| 五月天色图| 夜夜欧美 | 91美女在线视频| 97超碰色情| 美国一区二区免费视频| 久久久久9999妇女| 91熟女视频| 日本三级大片| 夜夜骑日日| 强奸乱伦AV网站| 天天摸夜夜摸| 国产熟女精品一区二区| www.夜夜操| 91 亚欧| 一区二区三区免费岛国片| 国产污视频麻豆传媒一区二区| 伊香蕉综合久久久久久久噜噜噜| 综合欧美日韩在线观看| 欧美色日| 大香蕉久| 综合av影片| 正在播放国产精品一区| 九九热五区| 热思思免费视频| 热久久精品| 97亚洲综合| 情色日播放AV| 久久AV无码AV| 精品无码一区二区| 久久精品国产精品一区| 69AV女优男人的天堂| 插入逼91| 久久夜夜夜夜| 中国一级操逼视频| 天天拍天| · —级AA伦aa坐爱午夜极速ⅴA一区天天噪天天噪天天噪 | 美女网站91| 嗯啊不要在线观看嗯啊| 夜夜爽夜夜| 澳门人妻久久| 日小BB小视频| 人妻黑丝袜电影| 亚洲精品亚洲人成在线麻豆| 欧美在线|亚洲| 99久视频| 人妻少妇久久中文字幕一区二区 麻豆| 啊啊啊好爽快点啊啊啊嗯嗯| 亚洲毛片基地专区| 亚洲av热热色| www国产天美久久久| 色99久草| 九九热精品免费视频| 69XX一中文字幕人妻91| 校园春色亚洲无码| 亚洲国产日韩欧美熟妇在线| 夜夜躁狠狠躁日日躁av| 97 国产一区| 亚洲一欧洲中文字幕在线| 偷拍新久久| 91人人爽人人爽人人人,gav福利视频导航,日韩欧美亚洲国产字幕四区 | 亚州 综合 色图| 亚欧韩av| 午夜精品久久一区二区| 大香蕉欧美国产日韩高潮| 手机看av网站在线看| 91九色丨风韵犹存| 欧美韩国你懂得在线| 思思热免费视频观看| 偷拍亚洲| 蜜桃臀AV在线| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 超碰在线国产| 思思视频免费看网站| 加勒比久久av| 宅男91视频在线播放| 视频黄色国产一级| 天天噜| 欧洲精品久久| 91爱综合| 丁香婷婷九月| 少妇一区二区三区高速| 久久精品电影在线| 91精品婷婷国产综合久久竹菊| 国产成人精品日本亚洲语言| 亚洲人成网站7777| 亚洲双插| 久久大精品乱码视频人妻熟女| 婷婷色色网| 午夜一区二区三区国产| 久久六六| 久夜操| 蜜桃丰满熟妇av无码区不卡| 一牛影视久久久一区二区三区| 亚洲欧美日韩精品久| 日本操逼视频在线| 丰满人妻-区二区三区免费看| 成人五月天色网| 91久久久久免| 丁香五月激情综合国产| 少妇无码av专区线| 超碰色综合| 五月天婷婷社区| 欧美日韩人妻少妇 一区二区三区| 欧美三级不卡| 啊啊啊操一区| 亚洲1区| 强免费黄色网址| 亚洲高清无码在线桃色| 美国黄片aaa| 97久久精品| 亚洲图片第一页| 欧美色97| 亚洲,欧美,综合网| 一区二区三区在线日韩影院观看| 97国产天堂岛| 99RE在线视频精品,这里只有精品| 天堂av2019| 国产女人高潮视频| 欧美亚洲综合色| 综合色久| 色色无码| 精品久久久久久亚洲| 九月丁香| 天天干天天爽| 久7色| 天美传媒国产原创中文字幕亚洲欧美另类 | 亚洲综合电影| 九九碰九九爱97超| 国产高清自拍视频| 一区AV| 亚洲人成网站7777| 日韩性爱免费观看视频| 中文字幕AV乱伦| 99久久久无码精品国产人| 亚洲无码成人精品| 欧美成人A天堂片在线观看| 免费精品人妻一区二区三| 午夜无码精品免费看性色| 欧美亚洲日本视频久久久| 丁香六月东京热| 操婷婷逼| 亚洲 欧美 91| 超碰天天久久79| 久久夜精品一区二区三区| 激情情色五月天| 阿姨一区二区免费视频-高清正片西瓜视频下载app-T450AV | 熟妇艹鸡八| 中文字幕久久亚州无码| 国产青青综合伊人| 欧美少妇人妻| 樱花蜜乳av| 欧美顶级黄片AAAAA在线免费看| 狠狠爱综合网| 人妻插插人妻人| 97超碰超欧美。| 国产又粗又长视频| 国内精品嫩模A∨私拍小视频| 久思思热视频在线观看| 激情久久av一区av二区av| 综合熟女| 欧美视频激情久久久久久| 蜜桃香蕉久草精品在线| 亚洲高清自拍| 五十路三级片| 中文字幕av色| 2019午夜福利视频| 麻豆久久一区二区三区| 综合免费无码中文| 久久久九97| 亚洲国产亚洲天堂| 清纯唯美亚洲| 玖玖资源综合在线视频| 欧美天天拍| 国产麻豆一区二三区| 97综合国产| 国产精品久久久久久久毛片1| 91国产精品在线看| 啊啊啊啊啊啊啊网址在线观看| 日韩精品午夜操呦呦不卡影院| 亚洲国产一级黄色视频| 午夜男女爽爽爽在线视频 | 久久性爱视频免费看| 岛园激情| 情色五月天久久久| 96久久久久| 一区二区三区 日韩欧美| 97国产色图| 加勒比99999| 萌白酱自拍视频| 强上我不卡卡| 91色婷婷综合久久中文字幕二区| 中国一级操逼视频| 日本天天吊| 天天欧美97| 日韩Va亚洲va欧美Ⅴa久久| AV一二区| 日韩小电影| 久久色情| 亚洲色天堂九9| 久操网视频| 精品国产一区二区三区久久久蜜臀| 精品人妻一区二区三区四区| 人妻日日干| 日韩中文字幕av在线播放| 九七超碰| 亚洲色图激情小说| 啊啊啊水好多| 国产99 中文字幕日韩小视频| 性性久久| 亚洲无码太久| 久久亚洲人妻| 内射老妇BBWX0C0CK| 成年男人的天堂| 国产精品久久久| 日夜啪电影| 男人的天堂va在线| 亚洲一区二区麻豆影院| 97伊人| AA丁香综合激情| 天美传媒麻豆一区二区三区国产精| 亚洲乱码国产乱码精网站| 在线观看午夜婷婷久久久久清性观看| 无码人妻精品一区二区三区99不卡| 超碰亚洲欧美日韩无| 亚洲色狠| 欧美高清性猛交| 国产精品人妻一区二区| 色婷婷婷五月天激情四射| 欧美伊人久久综合网| 亚洲色图国产另类| 97精品熟女少妇一区| 色男人色天堂东京热| 精品偷拍13p欧美dodk视频| 欧美伦乱爱| 多乙久久久久久| 日韩视频啪啪| 精品国产乱码久久久影院| 在线另类| 天天干天天操天天操夜夜操天天操| 美女露胸露尿口| 成人小说视频在线精品欧美| 久久久久久久久久久久久久久久9| 日本一级婬片试看三分钟| 99re在线视频| 发朗少妇买婬全视频中文| 超碰97中文| 加勒比AV网| 中文字幕成人理论在线| 人人妻人人爽| 第四色色综合91| 免费啪啪一级视频| 唯美清纯 妖精视频| 亚洲一二三精品久久网| 亚洲第一精品在线视频| 美女爽到高潮91| 1024亚洲中文字幕久在线看片你懂的 | 亚洲日韩美国人妻| 国产日韩美女小穴视频网站不卡| 欧美 亚洲 综合 制服| 亚洲h片在线免费观看| 亚洲,欧美,综合网| 精品久一区免费| 亚洲黄色a级片| 亚洲超碰97| 天天日天天屌天天操| 亚洲激情综合| 天天弄天天操| 蜜臀一区二区三区亚洲最新章节在线观看 - 高清蜜臀一区二区三区亚洲全集播放 | 九九九国产| 麻豆天美制片厂网站视频| 亚洲aV无码成人在线观看| 亚洲在线网站| 性高潮久久久久久久久久久| 97超碰色屌| 久久98| 国产精品无码久久久久2025| 另类小说欧美激情校园春色| 60秒免费小视频| 久久久久成人蜜桃精品| 首页中文字幕中文字幕免费| 欧洲特黄毛片免费看欧洲毛片| 久久久久久裸体| 欧美丝袜激情| 中亚精品极乱| av天堂手机版追回| 日韩av免费一级电影| 玖玖久久久| 久久久9 9 9精品| 久久AV无码1区2区3区| 天天日天天色| 日本性爱少妇| 日韩性爱人人爱人人操| 国产偷人伦激情在线观看| 性欧美999| 91精品人妻啪啪间| 九九亚洲精品| 极品粉嫩一区二区| 99国产人成精品| 极品色www影院| 日韩性爱免费视频在线网站| 91东京热男人的天堂| aa片毛片| 啊啊啊无码| 欧成人精品一区二区三区| 伊人久大| 超碰色美女| 超碰在线综合97| 尤物视频一区| 久久性爱视频免费看| 好色综合| 男人的天堂2018| 美女网站91| 久久伊人东京热| 超碰97综合网| 欧美色图99| 伊人性在线视频| 亚州,欧美在线| 久久久草草精品| 精久久久| 久久久九| 精品无av| 国产精品久久久亚洲第一牛牛_在线观看| 97爱啪| 干妹子| 欧美 日韩第一性色| 性欧美| 超碰吊日色| 日韩内| 欧美天天射| 日韩精品资源专区二区| 玖玖爱在线视频免费观看| 九九九精品成人免费视频小说| 国产精品美女久久久久久网站| 欧洲在线性爱视频| 性饥渴少妇av无码毛片| 超碰色男人操熟女| 人妻系列无码专区中文有码| 国产又粗又长又爽又色| 五月色网| 久久大香蕉手机高清| 久久一二区四| 久久久久久久久久久999| 久久夜夜夜| 精品大全99999| 亚洲高清91| 成 人 A V免费视频在线观看| AV天堂国产| 精品性爱一二三区| 丁香婷婷久久 | 国产超碰欧美| 麻豆成人影音在线| 色波多| 日韩乱中文| 91九色网| 黄总AV色图| 日韩中文字幕精品一二三事国产精品 | 天天日天天搞天天干| 久久鲁干| 欧亚乱色熟一区二区三四区| 妇女视频网站| 91精品国产91久久久久久久久久久久| 免费视频97| 18禁免费视频| 婷婷五月天丁香花| 91精品成人| 欧美激情 一区| 国产狂喷潮在线精品| 玖玖资源综合在线视频| 日韩人体偷拍| 手机av亚洲丝袜美腿日韩第一页二页| 久九九九九九九九热| 超碰在线欧美性爱激情| www.av在线观看| 青苹果影院男人的天堂| 九久久精品| 国产精品一二三区18| 国产女人91精品嗷嗷嗷嗷| 国产精品熟女AV中文字幕在线播放| 亚拍在线| 日本操逼aaaaa| www.久久久久| 九九九九九用不成了| 丰满人妻一区二区三区免费 | 中出789在线视频| 男人综合网| 3028国产精品| 美女97超碰| 九九九精品美女| 日韩乱伦影音先锋| 日韩AV色图| 丰满人妻-区二区三区免费看| 国产精品美女久久久久AⅤ国产馆| 骚逼高潮久久精品| q2午夜理论片夜色av| 极品综合| 精品无码久久久| 亚洲午夜精品久久久中文影院| 一区操逼日比视频| 啊嗯好大视频在线观看| 久久啊啊啊| 少妇精品久久久八区九区| 26uuu国产亚洲综合| 人妻天天夜夜爽一区二区| 91精品国产长腿丝袜美女| 中文字幕乱在线伦视频中文字幕乱码在线| 91 手机在线播放 绯色| 天天躁日日躁狠狠狠躁| 91小视频| k频道色撸撸| 熟女五十路一区二区三| 中出789在线视频| 午夜男女爽爽爽影院视频| 99国产精品人妻人伦| 91高潮| 人妻熟女一区在| 欧美激情高清性猛交| 日韩成人电影AV| 国产97av| 五月婷婷无码| 天天亚洲| 很很干很很操| 老妇女91| 熟女日韩| 亚洲国产一级黄色视频| 顶级少妇BT天堂| 无码操逼视频一下| 青青草手机在线免费观看| 欧美午夜视频免费观看| 美女主播色欲91抠b在线播放| 国产精品不卡一区二区电影| 色月天AV导航| 高清国产无码av| 99www.bibizy香蕉资源国产一区二区三区高清 | 97精品97| 91人妻中文| 久久久久久无码人妻中文字幕| 久精品无码av一区二免费国产在线观看 | 校园激情狠狠四射| 极品色社| 中文字幕精品探花视频| 亚洲综合码| 亚洲小电影免费涩涩成人在线高清 | 97国产精品久久久久| 成人性爱高清视频免费看| 中文熟女五十乱码在线| 欧美成人一区二区三区在线播放| 性色高清..……| 六月丁香啪啪啪| 人人摸人人入| 黄色不卡视频| 日韩去日本高清在| se..亚洲欧美| 超碰在线人妻不卡| caoni国产亚洲av| 91色欧美| 免费农村成人少妇人妻Aa一区二区视频| 亚洲电影中字一区二区| 青草园大香蕉| 天天干,天天日| 丝袜人妻av一区二区| 欧美激色| 日产狠狠干| 中字幕人妻一区二区三区| 色女免费在线观看视频网址| 天天爱天天操| 日韩无码操逼片| 亚洲色图8| 中文字幕片| 成人三级片无码| 日本一级特级毛片视频| 加勒比人妻综合| 久草成人福利导航| 波多野结衣先锋影音| 欧美激情高清性猛交| 久操大香蕉超碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰碰 | 欧美亚洲AN| 激情六月婷婷| 亚洲 自拍偷拍 欧美| 91麻豆天美传媒在线| 成熟熟女国产精品一区二区| 99日韩| 男人天堂黄片| 久久69| 精品国产乱码久久久久久日本公司| 国产亚洲人妻综合日韩 久久| 久久亚洲欧美中文字幕国语| 精精品人妻一区二区三区| 999综合色| 无码91| 色人久久| A V视频日本| 欧美性爽xyxOOOO| 亚洲欧洲综合| 熟女91网| 91久久国产综合精品| 插入综合网| 91日本在线观看| 欧洲成人性爱视频| 青娱乐国产剧情av一区| 丝袜美腿操av| 乱码人妻一区二区三区| 色婷婷综合久久久久中文一区二区| 不卡啪啪视频| 国产男人又猛又粗又爽| 一个国产在线综合网站| 国产女大学生AV| 欧美九九九九九| 自拍第一页| 亚欧美综合网。| 精品一区二区麻豆| 高树玛利亚无码流出| 五月婷在线| 免费视频a级毛片免费视频| 懂色av色欲av蜜臀av| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 人妻密肉在线观看| 亚洲国产中文字幕| 熟女自慰久久久| 日韩精品高清资源在线| 久久黄黄| 操操AV电影| 99爱视频| 中文字幕在线观看丝袜| 69精品人人人人| 亚洲AV成人在线| 色五月婷婷色| 亚洲人妻AV| 99在线精品视频| 欧美操逼一二三区| 欧美综合站| 欧美激情视频在线一区| 欧美综合网1| 95精品在线| 亚洲1区2区三区高清中文字幕| 亚洲日精品| 婷婷精品国产欧美精品亚洲人人爽| 欧美少妇高潮久久91| 青青草成人视频在线观看二区| 岛国人妻少妇av在线观看| 97超碰热线| 60秒免费小视频| 欧洲亚洲人人爽爽视频| 天欧美在线| 一卡二卡在线播放| 97chaopengongkai| 国产色产精品在线观看| 三级日本一区二区三区|