精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

什么是好的錯誤消息? 討論一下Java系統中的錯誤碼設計

原創
開發 前端
有了錯誤碼和message的規范,接下來我們應該如何保存這些信息呢?如果是Java,是不是要創建對應的ErrorEnum,然后是一些POJO?

一、什么是好的錯誤信息(Error Message)?

一個好的Error Message主要包含三個部分:

  • Context: 什么導致了錯誤?發生錯誤的時候代碼想做什么?
  • The error itself: 到底是什么導致了失敗?具體的原因和當時的數據是什么?
  • Mitigation: 有什么解決方案來克服這個錯誤,也可以理解為 Solutions。

聽起來還是有點抽象,能否給點代碼? 剛好有一個 jdoctor 的項目,作者來自Oracle Labs[1] 樣例代碼如下:

ProblemBuilder.newBuilder(TestProblemId.ERROR1, StandardSeverity.ERROR, "Hawaiian pizza")
.withLongDescription("Pineapple on pizza would put your relationship with folks you respect at risk.")
.withShortDescription("pineapple on pizza isn't allowed")
.because("the Italian cuisine should be respected")
.documentedAt("https://www.bbc.co.uk/bitesize/articles/z2vftrd")
.addSolution(s -> s.withShortDescription("eat pineapple for desert"))
.addSolution(s -> s.withShortDescription("stop adding pineapple to pizza"));

這里的Problem理解為Error沒有問題,核心主要包括以下幾個字段:

  • context: such as app name, component, status code,使用一個字符串描述當時的上下文,如應用名稱 + 組件名稱 +具體的錯誤狀態碼等,這個由你自己決定,當然JSON字符串也可以,如 {"app":"uic", "component": "login", "code":"111"}
  • description: Long(Short) to describe error 錯誤描述,有Long和Short兩者
  • because/reason: explain the reason with data 詳細解釋錯誤的原因,當然必須包含相應的數據
  • documentedAt: error link 錯誤對應的HTTP連接,更詳細地介紹該錯誤
  • solutions: possible solutions 可能的解決方案,如提示訪問者檢查email拼寫是否正確,短信的Pass Code是否輸入正確等。

有了這些具體的字段后,我們理解起來就方便多啦。

二、錯誤碼(Error Code)的設計

各種錯誤處理上都建議使用錯誤碼,錯誤碼有非常多的優勢:唯一性、搜索/統計更方便等,所以我們還是要討論一下錯誤碼的設計。網上也有不少錯誤碼的設計規范,當然這篇文章也少不了重復造輪子,該設計提供給大家參考,大家自行判斷啊,當然也非常歡迎留言指正。

一個錯誤碼通常包含三個部分:

  • System/App short name: 系統或者應用的名稱,如 RST, OSS等。如果你熟悉Jira的話,基本也是這個規范,Java程序員應該都知道HHH和SPR代表什么吧?
  • Component short name or code: 系統內部的組件名稱或者編碼,如LOGIN, AUDIT,001 這些都可以,方便更快地定位錯誤。
  • Status code: 錯誤的狀態碼,這個是一個三位數字的狀態碼,如200,404,500,主要是借鑒自 HTTP Status Code,畢竟絕大多數開發者都了解HTTP狀態碼,我們沒有必要再重新設計。

有了上述的規范后,讓我們看一下典型的錯誤編碼長什么樣子:

  • OSS-001-404: 你應該知道是OSS的某一組件報告資源沒有找到吧;
  • RST-002-500:這個是一個組件的內部錯誤;
  • UIC-LOGIN-404:這個應該是會員登錄時查找不到指定的賬號。

我們采用應用名縮寫, 組件名或者編碼, 狀態值,然后以中劃線連接起來。中劃線比較方便閱讀,下劃線有時候在顯示的時候理解為空格。同時有了標準的HTTP Status Code支持,不用參考文檔,你都能猜一個八九不離十。 錯誤碼設計千萬不要太復雜,試圖將所有的信息都添加進去,當然信息非常全,但是也增加了開發者理解和使用成本,這個可能要做一個取舍,當然我也不是說目前這種一鍵三連(打賞、點贊加轉發)的結構就最合理,你也可以自行調整。有沒有做心里研究的同學來說一下,這種三部分組成的方式,是不是最符合人們的認知習慣?如果超過三部分,如4和5,人們能記住和使用的概率是不是就下降的非常多?

還記得前面說的error的context嗎?這里error code其實就是啟動context的作用,如 UIC-LOGIN-404,錯誤發生在哪里?錯誤碼幫你定位啦。當時代碼想干什么?錯誤碼也說明啦。雖然說錯誤碼不能完全代表錯誤的上下文,但是其承載的信息已經足夠我們幫我們了解當時的上下文啦,所以這里error code就是起著context的作用。目前看來至少error code要比ProblemBuilder.newBuilder(TestProblemId.ERROR1, StandardSeverity.ERROR, "Hawaiian pizza") 中的Hawaiian pizza 作為context更具有說服力,也規范一些。

三、錯誤消息的編寫格式

錯誤碼設計完畢后,我們還不能用錯誤碼+簡短消息方式輸出錯誤,不然就出現類似 ORA-00942: table or view does not exist這種情況,你一定會吐槽:"你為何不告訴哪個表或者view?"。所以我們還需要設計一個message格式,能夠將錯誤的context, description, reason, document link, solutions全部包含進來,這樣對開發者會比較友好。這里我擬定了一個Message的規范,當然大家可以發表自己的意見啊,如下:

long description(short desc): because/reason --- document link -- solutions

解釋一下:

  • 錯誤的長描述直接書寫,短描述使用括弧進行包含。這種寫法在合同中非常常見,如阿里云計算有限公司(阿里云) ,你簽署勞動合同時,公司的稱謂基本也是全名(代稱) 這種方式。好多同學會在錯誤日志中書寫登錄失敗,但是登錄系統中有多種登錄方式,所以遠不如Failed to log in with email and password(Login Failed), Failed to log in with phone and passcode(Login Failed), Failed to log in with oauth2(Login Failed) 更清晰。
  • 錯誤具體原因: 接下來是冒號,然后書寫詳細的原因,如 email user@example.com not found ,gender field is not allowed in package.json 一定要包含具體的數據信息,包括輸入的,還是和勞動合同一樣,抬頭之后就是你的具體崗位和薪水,雖然合同是格式化的,但是每一個人具體的崗位和薪水是不同的,這些參數都是從外部獲取的。此處有安全同學發問,如何數據脫敏?這個是另外的問題,大多數開發者應該了解如何進行mask,這里我們就跳過。當出現勞動糾紛這個錯誤時,具體原因中的數據,如崗位和薪水等,這樣勞動仲裁局就可以快速定位并解決該"錯誤"。
  • document link: 接下來我們使用三種劃線---進行分隔,輸入對應的error link。三劃線作為分隔符在很多的場景中多有使用,如mdx, yaml等,大家不會太陌生。 如果沒有link那就忽略就可以。
  • solutions:自然的文本表述即可,能說明清楚就可以,也是放在三中劃線后。

看一個具體的消息格式例子:

APP-100-400=Failed to log in system with email and password(Email login failed): can not find account with email {} --- please refer https://example.com/login/byemail  --- Solutions: 1. check your email  2. check your password

上述的APP-100-400的錯誤碼對應的描述基本覆蓋到jdoctor中需要的信息,可以說對一個錯誤的描述應該非常全啦,而且有一定的格式,也方便后續的日志分析。

四、組裝和保存錯誤碼 + Message

有了錯誤碼和message的規范,接下來我們應該如何保存這些信息呢?如果是Java,是不是要創建對應的ErrorEnum,然后是一些POJO?這里個人建議使用properties文件來保存錯誤碼和message的信息。文件名可以直接為ErrorMessages.properties,當然是在某一package下,文件樣例如下:

### error messages for your App
APP-100-400=Failed to log in system with email and password(Email login failed): can not find account with email {0} --- please refer https://example.com/login/byemail --- Solutions: 1. check your email 2. check your password
APP-100-401=Failed to log in system with phone and pass(Phone login failed): can not find account with phone {0} --- please refer https://example.com/login/byphone --- Solutions: 1. check your phone 2. check your pass code in SMS

為何要選擇properties文件來保存error code和message信息,主要有以下幾個原因:

  • 國際化支持:Java的同學都知道,如果你的錯誤消息想調整為中文,創建一個ErrorMessages-zh_CN.properties 即可。原文中的建議是Don’t localize error messages,但是考慮到國內大多數程序員未必能用英文表達清楚,所以中文也是可以的。題外話:如果中國的程序員都能用英文清晰地閱讀文章和表達自己的思想和觀點,我們在計算機方面的水平可能會提升到更高的臺階。
  • 各種語言對properties的文件解析都有支持,不只是Java,其他語言也有,而且properties文件本身也不復雜,所以該properties文件可以給Node.js, Rust等其他語言使用,如果是Java enum和POJO基本就不可能啦。
  • properties文件格式豐富:支持注釋,換行符,多行轉義等也都沒有問題。

最后最關鍵的是IDE支持非常友好 , 以Java開發者使用的IntelliJ IDEA來說,對Properties文件的支持可以說是到了極致,如下:

  • error code的自動提示

快速查看:鼠標移上去就可以,按下CMD鼠標移上去也可以, Alt+Space也可以,當然點擊直接定位就更不用說啦。

  • 重構和查找支持:雖然Error Code是字符串,但是也是properties的key,所以rename這個error code,所有引用的地方都會rename。還支持find usage,那些地方引用了該error code等,都非常方便。當然如果Error Code在系統中沒有被使用,也會灰色標識。
  • 折疊自動顯示功能:當你的代碼處于折疊狀態時,IDEA直接將message拿過來進行顯示,你在code review的時候方便多啦,也便于你理解代碼。

直接修改message的值:

總之IntellIJ IDEA對properties文件的支持到了極致,我們也沒有理由不考慮開發者體驗的問題,到處跳來跳去地找錯誤碼,這種傷害程序員開發體驗的事情不能做。 當然JetBrains的其他IDE,WebStorm等都有對proproperties文件編輯支持。

五、代碼實現

看起來功能挺酷炫的,是不是這種方式錯誤管理要介入一個開發包啊?不需要,你只需要10行代碼就搞定,如下:

import org.slf4j.helpers.MessageFormatter;

public class AppErrorMessages {
private static final String BUNDLE_FQN = "app.ErrorMessages";
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_FQN, new Locale("en", "US"));
public static String message(@PropertyKey(resourceBundle = BUNDLE_FQN) String key, Object... params) {
if (RESOURCE_BUNDLE.containsKey(key)) {
String value = RESOURCE_BUNDLE.getString(key);
final FormattingTuple tuple = MessageFormatter.arrayFormat(value, params);
return key + " - " + tuple.getMessage();
} else {
return MessageFormatter.arrayFormat(key, params).getMessage();
}
}
}

這樣在任何地方如果你要打印錯誤消息的時候,這樣log.info(AppErrorMessages.message("APP-100-400","xxx"));就可以。如果你還有想法和log進行一下Wrapper,如 log.info("APP-100-400","xxx"); ,也沒有問題,樣例代碼如下:

public class ErrorCodeLogger implements Logger {
private Logger delegate;
private static final String BUNDLE_FQN = "app.ErrorMessages";
private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_FQN, new Locale("en", "US"));

public ErrorCodeLogger(Logger delegate) {
this.delegate = delegate;
}

@Override
public void trace(@PropertyKey(resourceBundle = BUNDLE_FQN) String msg) {
delegate.trace(RESOURCE_BUNDLE.getString(msg));
}
}

接下來你就可以在log中直接整合error code,非常便捷。上述代碼我已經寫好,你參考文章末尾的項目地址即可。

最終的日志輸出如下:

提醒:這里我們使用了slf4j的MessageFormatter,主要是方便后續的Slf4j的整合,而且slf4j的MessageFormatter比Java的MessageFormat容錯和性能上更好一些。

六、FAQ

1. 為何選擇3位的HTTP Status Code作為Error的Status Code?

大多數開發者對HTTP Status Code都比較熟悉,所以看到這些code就大致明白什么意思,當然對應用開發者也有嚴格的要求,你千萬別將404解釋為內部錯誤,如數據庫連接失敗這樣的,逆正常思維的事情不要做。HTTP status code歸類如下,當然你也可以參考一下 HTTP Status Codes Cheat Sheet[2]。

  • Informational responses (100–199)
  • Successful responses (200–299)
  • Redirection messages (300–399)
  • Client error responses (400–499)
  • Server error responses (500–599)

但是Error Status Code不局限在HTTP Status Code,你也可以參考SMTP, POP3等Status Code,此外你也自行可以選擇諸如007,777這樣的編碼,只要能解釋的合理就可以啦。

在日常的生活中,我們會使用一些特殊意義的數字或者和數字諧音,以下是一些友情提醒:

  • UIC-LOGIN-666: 太順利啦,完美登錄。但是你團隊中有歐美老外的話,他可能理解為理解為惡意登錄,登錄失敗;
  • APP-LOGIN-062: 如果你團隊有杭州土著的話,不要使用62這個數字;
  • APP-001-013: 如果該error code要透傳給最終用戶,請不要使用13這個數字,會引發不適。

這種有特殊意義的數字或者數字諧音,如520,886,999,95等,如果能使用的恰當非常方便理解或更友好,如透傳給用戶UIC-REG-200(注冊成功),如果調整為UIC-REG-520可能更溫馨一些。總的來說使用這些數字要注意場景,當然比較保險的做法就是參考HTTP,SMTP等設計的status code。

2. properties文件存儲error code和message,真的比enum和POJO好嗎?

就Java和IntelliJ IDEA的支持來看,目前的配合還是比較好的,如i18n,維護成本等,而且這些ErrorMessages.properties也可以提交到中心倉庫進行Error Code集中管理,如果是Java Enum+POJO對i18n和集中管理都比較麻煩,而且代碼量也比較大,你從上述的jdoctor的problem builder的就可以看出。當然在不同的語言中也未必是絕對的,如在Rust中,由于enum的特性比較豐富,所以在Rust下使用enum來實現error code可能是比較好的選擇。

#[derive(Debug)]
enum ErrorMessages {
AppLogin404 {
email: String,
},
AppLogin405(String),
}

impl fmt::Display for ErrorMessages {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// extract enum name parameter
// output message from java-properties
write!(f, "{:?}", self)
}
}

3. 為何不在Error Code中提供錯誤級別

不少錯誤碼設計中會添加錯誤級別,如 RS-001-404-9 這樣,最后一位表示錯誤的嚴重級別。這樣做沒有問題,但是也要考慮現實因素,如下:

  • 錯誤的級別會動態調整的:如隨著時空的變化,之前非常嚴重的錯誤級別,現在并不那么嚴重啦。如果資源找不到可能之前非常嚴重,但是現在添加了備份方案,可以從備份服務器中再查找一次,所以這個錯誤出現在主服務上可能現在就不是那么嚴重啦。
  • 不同團隊對錯誤級別的認知不一樣:如OSS-404在OSS團隊的data server上找不到,元信息都是有的,結果在data server上沒有找到對應的數據,這個是非常嚴重的錯誤。雷卷在業務團隊,如負責Serverless Jamstack,其中的一個文件缺失,如html, css, image,可能并不是一個大問題,等一會重試下,不行就再上傳一下。我想表達的是同樣的錯誤,在不同團隊中的重要性并不一樣。

如果將錯誤的基本固化到error code中,這個后續你就沒法調整啦,你如果調整了錯誤級別,那就是可能就是另外一個錯誤碼,給統計和理解都會造成問題。我個人是建議錯誤碼中不要包括嚴重級別這些信息,而是通過外圍的文檔和描述進行說明,當然你也可以通過諸如 log.info , log.error來確定錯誤的級別。

4. 能否提供共享庫?

由于IntelliJ IDEA并不支持動態的properties文件名稱,如果你用動態的properties文件名稱,就不能進行代碼提示,查找等功能也都不能使用,所以必須是這種 @PropertyKey(resourceBundle = BUNDLE_FQN) 靜態的properties文件名方式。就一個Java類,你就受累Copy一下這個Java類,畢竟是一次性的工作,當然你想個性化調整代碼也更方便,如和Log4j 2.x或自定也的logging框架整合也簡單些。 日志是項目最基本的需求,所以你創建的項目的時候,就把Error Code對應的代碼添加到項目模板中,這樣項目創建后就自動包含logging和error code的功能。

5. 其他的考量

原文和Reddit上相關的討論也進行了一些整理和說明:

  • 內外有別:如內部開發者的錯誤中可能會包括服務器的具體信息,當然給最終消費者,如平臺的FaaS開發者,可能就不能輸出這樣的信息,有一定的安全風險。
  • 小心在錯誤中暴露敏感數據:輸出到錯誤日志的數據一定要進行mask,當然也不要影響你定位錯誤,這個要看具體的場景。
  • 不要將錯誤消息作為 API 契約:在API的場景中,響應錯誤有兩種方式:根據錯誤碼做響應,如REST API;另外一種是根據消息做出響應,如GraphQL,所以這個你自行選擇。
  • Error Code的一致性:錯誤消息會輸出給不同的消費者,如REST API,界面等,可能錯誤的提示消息有所不同,如國際化、脫敏等,但是最好都是相同的error code,也就是front end + backend 共享相同的error code,方便定位錯誤和統計。

七、總結

采用error code + 基于properties文件存儲error message,這個設計其實就是一個綜合的取舍。如果IDEA不能很好地支持properties文件,你看到一個Error Code,不能直接定位到錯誤的消息,相反還需要跳轉來跳轉去找對應的消息,那么Enum + POJO可能就是好的選擇。此外error code的設計也非常偏向http status code方案,這個也是主要基于大家對HTTP都非常熟悉,基本上就能猜出大概的意思,相反隨機編碼的數字就沒有這方法的優勢,要去error code中心再去查找一下,無形中也是浪費開發人員的時間。

最后項目的Demo地址:http://gitlab.alibaba-inc.com/leijuan/java-error-messages-wizard

[1]https://github.com/melix/jdoctor

[2]https://cheatography.com/kstep/cheat-sheets/http-status-codes/

[3]https://www.morling.dev/blog/whats-in-a-good-error-message/

責任編輯:武曉燕 來源: 阿里技術
相關推薦

2025-01-02 10:37:13

2009-07-23 11:11:18

LRU緩存

2020-06-30 11:36:45

錯誤碼合理開發

2009-07-06 13:23:12

C#面向集合

2017-09-05 14:59:34

2020-07-29 10:20:28

Redis數據庫字符串

2022-12-28 08:17:19

異常處理code

2017-11-20 11:53:38

CDN406錯誤故障

2022-01-17 06:58:35

C語言函數錯誤碼

2012-04-16 09:54:05

移動web錯誤理念

2012-07-26 10:27:31

PHP

2024-10-16 15:11:58

消息隊列系統設計

2016-06-07 14:42:18

Swift設計

2011-10-12 11:07:12

iCloudiOS5蘋果

2014-03-11 11:33:21

2012-07-22 15:49:25

Java

2022-09-21 12:01:22

消息隊列任務隊列任務調度

2021-04-14 07:08:14

Nodejs錯誤處理

2019-03-28 09:02:45

區塊鏈數字貨幣比特幣

2011-05-19 15:51:54

測試專家
點贊
收藏

51CTO技術棧公眾號

日韩电影不卡一区| 天天干天天色天天| 日本午夜一区| 欧美电影一区二区| 91传媒免费视频| 五月婷婷久久久| 日本欧洲一区二区| 欧美激情一二区| 免费观看av网站| 99久热在线精品视频观看| 亚洲成人综合视频| 日韩中文一区| 性猛交富婆╳xxx乱大交天津 | 中文字幕免费精品一区| 涩多多在线观看| 欧美电影免费看| 一区二区三区四区不卡在线| 日本在线成人一区二区| 国产精品一线天粉嫩av| 972aa.com艺术欧美| 国产精品免费视频久久久| 顶臀精品视频www| 日韩精品福利一区二区三区| 欧美日韩一区二区在线观看视频 | 成人激情视频小说免费下载| 日韩精品在线免费看| 99精品视频在线观看播放| 精品国产一区二区三区久久影院| 日本a√在线观看| 电影在线观看一区| 亚洲欧美日韩一区二区三区在线观看 | 91黄色在线看| 午夜不卡视频| 国产午夜精品美女毛片视频| 国产日韩三区| www日本高清| 久久91精品久久久久久秒播| 日本一区二区三区四区视频| 国产对白videos麻豆高潮| 围产精品久久久久久久| 夜夜躁日日躁狠狠久久88av| 最近日本中文字幕| 91精品国产自产精品男人的天堂 | 97精品国产97久久久久久春色| 91ts人妖另类精品系列| 夜夜躁狠狠躁日日躁2021日韩| 欧美变态凌虐bdsm| 色男人天堂av| 国产美女亚洲精品7777| 欧美久久久久久久久中文字幕| 成年人免费在线播放| 国产99在线| 亚洲成人免费观看| 日韩精品在线中文字幕| 羞羞的视频在线看| 一区二区在线观看av| 欧美少妇一级片| 黄网站在线免费| 国产精品第一页第二页第三页| 日韩福利影院| 97超碰人人在线| 国产欧美一区二区精品仙草咪| 蜜桃精品久久久久久久免费影院 | 99久久综合国产精品| 国产 高清 精品 在线 a| 国产99久一区二区三区a片| 久久99九九99精品| 国产日韩欧美日韩| 亚洲一区二区三区高清视频| 精品一区二区在线看| 91免费精品国偷自产在线| 国产精品久久久久久免费| 老司机午夜精品| 91精品综合视频| www.天堂在线| av影院午夜一区| 欧美重口乱码一区二区| av在线免费播放网站| 中文字幕日韩一区二区| 成人在线免费观看网址| 日本性爱视频在线观看| 午夜精品久久久久久久久久| 欧美亚洲一二三区| 美女一区网站| 欧美另类videos死尸| 久久久久久久穴| 天堂俺去俺来也www久久婷婷| 亚洲人成电影网| 亚洲国产精品一区二区久久hs| 婷婷亚洲最大| 91精品国产91| 在线观看黄色国产| 国产91在线看| 久久国产精品一区二区三区四区| 欧美在线一卡| 亚洲视频图片小说| 国产婷婷一区二区三区| 精品日韩视频| 欧美mv日韩mv亚洲| 一区二区精品免费| 欧美99久久| 国产91在线播放九色快色| 国产美女三级无套内谢| 不卡一区在线观看| 亚洲午夜高清视频| 成年人国产在线观看| 色婷婷亚洲精品| 日韩欧美中文在线视频| 亚洲欧美tv| 欧美成人精品h版在线观看| 久久不卡免费视频| 激情六月婷婷久久| 久久久久九九九| av网站在线免费| 色成年激情久久综合| 黄色a级三级三级三级| 蜜臀av免费一区二区三区| 精品综合久久久久久97| 中文文字幕一区二区三三| 丁香激情综合五月| 在线观看精品视频| 毛片免费看不卡网站| 欧美成人三级电影在线| 91社区视频在线观看| 99riav国产精品| 51成人做爰www免费看网站| 久草福利在线| 激情成人中文字幕| 性久久久久久久久久久久久久| 精品国产乱码久久久久久1区2匹| 久久久久久久一| 国产女人高潮的av毛片| 国产蜜臀av在线一区二区三区| 亚洲一区二区三区av无码| 免费成人黄色网| 国产亚洲精品久久久久动| 亚州国产精品视频| 国产传媒一区在线| 亚洲免费av网| 欧美视频在线视频精品| 亚洲欧美日本精品| 日韩伦理在线视频| 粉嫩一区二区三区性色av| 日韩视频在线免费播放| 久久久精品一区二区毛片免费看| 国产亚洲精品久久久久动| 男人日女人网站| 91丨九色丨尤物| 又粗又黑又大的吊av| 爱爱精品视频| 久久久久久久久网站| 亚洲欧美另类视频| 亚洲一区二三区| 亚洲图片欧美另类| 黄色av日韩| 国语精品中文字幕| 国产伦理精品| 日韩精品在线免费播放| 日本韩国欧美中文字幕| 91影院在线免费观看| 国产精品333| 五月国产精品| 国产成人福利网站| 成年人在线视频免费观看| 在线精品观看国产| 无码人中文字幕| 国产在线视频一区二区三区| 三年中国中文在线观看免费播放| 激情综合五月| 欧美国产中文字幕| 日本wwwxxxx| 色综合视频一区二区三区高清| 香蕉视频久久久| 九九在线精品视频| 大胆欧美熟妇xx| 欧美在线关看| 国产精品黄色影片导航在线观看| 天堂资源在线中文| 欧美一区二区在线免费播放| 久久成人国产精品入口| a在线播放不卡| 冲田杏梨av在线| 欧美一区网站| 国产一区二区三区奇米久涩| 中文字幕成在线观看| 在线亚洲欧美视频| 性生活免费网站| 欧美视频在线看| 亚洲一级二级片| 国产成人午夜高潮毛片| 97国产精东麻豆人妻电影| 欧美日韩在线二区| 亚洲精品女av网站| 亚洲美女尤物影院| 日韩在线观看成人| 亚洲欧美国产高清va在线播放| 91官网在线观看| 欧美日韩在线观看成人| 91蝌蚪国产九色| 992kp免费看片| 性欧美长视频| 69精品丰满人妻无码视频a片| 丝袜美腿一区二区三区动态图| 91精品久久久久久久久久另类| 国产乱妇乱子在线播视频播放网站| 亚洲欧美一区二区三区四区| 曰批又黄又爽免费视频| 亚洲一区二区三区自拍| 1024在线看片| 99精品久久免费看蜜臀剧情介绍| 久久99爱视频| 亚洲一区国产| 欧美一区二区三区综合| 精品av一区二区| 国产乱码精品一区二区三区日韩精品| 91福利精品在线观看| 欧美国产日韩中文字幕在线| 婷婷免费在线视频| 亚洲精选中文字幕| 亚洲av无码一区二区三区dv| 欧美三日本三级三级在线播放| 日韩乱码在线观看| 樱花影视一区二区| 中文字幕求饶的少妇| 26uuu亚洲婷婷狠狠天堂| 免费黄色av网址| 精品一区二区免费在线观看| 国产女女做受ⅹxx高潮| 在线精品观看| 国产一级大片免费看| 99热国内精品永久免费观看| 日本成人三级电影网站| 红杏aⅴ成人免费视频| 亚洲一区二区三区xxx视频| avav成人| 国产精品你懂得| 色豆豆成人网| 国产精品99久久久久久www| 欧美aaaaa性bbbbb小妇| 国产+成+人+亚洲欧洲| 亚洲91av| 久久久久久久97| 欧美理论片在线播放| 欧美成人sm免费视频| 免费在线观看黄色网| 中文字幕亚洲欧美日韩在线不卡 | 久久久久久99久久久精品网站| 国产女人18毛片水真多18| 国产黄色精品视频| 亚洲一区二区三区三州| 国产乱子轮精品视频| 91性高潮久久久久久久| 国产在线麻豆精品观看| 中文字幕亚洲影院| 国产一区二区毛片| 亚洲欧美激情一区二区三区| 风间由美一区二区三区在线观看| 欧美激情 亚洲| 成人av高清在线| 国产麻豆天美果冻无码视频| 91在线小视频| 中文幕无线码中文字蜜桃| 久久精品一二三| 成人信息集中地| 亚洲一区二区在线免费观看视频| 亚洲欧美一区二区三区四区五区| 一区二区久久久| 在线观看精品国产| 一本一道久久a久久精品综合蜜臀| 亚洲黄网在线观看| 欧美日韩一区二区三区在线 | 欧美久久久久久久久久久久| 亚洲一区在线免费观看| 国产成人愉拍精品久久| 色老综合老女人久久久| 亚洲一区二区人妻| 欧美大肚乱孕交hd孕妇| 亚洲人成色777777精品音频| 亚洲人成啪啪网站| √新版天堂资源在线资源| 蜜月aⅴ免费一区二区三区| 丁香影院在线| 国产98色在线| 国产情侣一区在线| 国产在线精品一区二区三区》| 欧洲专线二区三区| 26uuu成人| 亚洲国内精品| 欧美婷婷精品激情| 国产成a人无v码亚洲福利| 亚洲自拍偷拍一区二区| 成人免费在线视频观看| 日韩黄色精品视频| 欧美日韩情趣电影| 亚洲精品18p| 国产亚洲人成a一在线v站| 日本在线视频站| 91精品91久久久久久| 日本久久久久| 精品无人乱码一区二区三区的优势 | 欧美二区在线| 91精品国产视频| aa在线免费观看| 国产精品一二三区在线| 久久久久久久久久久久| 一区二区三区在线视频免费观看| 久久久成人免费视频| 欧美一区二区三区免费| 久久这里精品| 韩国国内大量揄拍精品视频| 欧美在线一级| 欧美一区二区三区成人久久片| 亚洲综合色站| 日韩av片网站| 99视频超级精品| 美女福利视频在线观看| 在线观看一区二区视频| 日本国产在线观看| 久久国产精品影视| 欧美不卡高清一区二区三区| 精品亚洲一区二区三区四区五区高| 午夜久久免费观看| 天天碰免费视频| 91视频91自| 国产精品第九页| 日韩视频在线你懂得| 一级毛片视频在线| 国产精品户外野外| 亚洲8888| 欧美三级一级片| av福利精品导航| 久久精品亚洲无码| 日韩无一区二区| av黄在线观看| 成人性生交大片免费看小说 | 色av中文字幕一区| 久久sese| 欧洲精品国产| 久久精品1区| a级大片在线观看| 色综合久久六月婷婷中文字幕| 污污网站免费在线观看| 久久久人成影片一区二区三区| 日本在线成人| 成人一区二区av| 国产v综合v亚洲欧| 国产a免费视频| 欧美电影精品一区二区| 午夜av在线播放| 99久久精品免费看国产四区| 欧美久久视频| 欧美久久久久久久久久久| 亚洲自拍偷拍麻豆| 国产91免费看| 97精品国产97久久久久久免费| 天堂俺去俺来也www久久婷婷 | 激情文学综合插| 精品少妇一区二区三区密爱| 777午夜精品免费视频| 色wwwwww| 欧美一区二区三区免费视| 九九综合久久| 国内自拍视频一区| 91碰在线视频| 久久亚洲精品国产| 亚洲国产精品va在看黑人| heyzo高清中文字幕在线| 粉嫩高清一区二区三区精品视频 | 精品久久精品久久| 日韩视频不卡| 国产肥白大熟妇bbbb视频| 色94色欧美sute亚洲13| 日本在线免费看| 91免费综合在线| 欧美a级在线| 日韩www视频| 欧美视频在线观看免费| 高清性色生活片在线观看| 国产精品亚发布| 国产精品videossex久久发布| 最新国产精品自拍| 色天天综合久久久久综合片| 岛国视频免费在线观看| 91精品视频在线| 黄色成人av网站| 三级电影在线看| 欧美天天综合网| h视频网站在线观看| 91丝袜美腿美女视频网站| 欧美午夜在线| theav精尽人亡av| 欧美视频在线播放| 国产第一页在线视频| 久久久久久亚洲精品不卡4k岛国 | 亚洲成人激情小说| 午夜成人免费视频| 色视频在线免费观看| 国产不卡一区二区在线观看 | 欧美成人三级在线播放| 亚洲精品视频观看|