提高應(yīng)用程序可用性的五個要點

原文鏈接

可用性問題通常會在你最想不到的地方出現(xiàn),許多問題都是系統(tǒng)性的問題趾断,而不僅僅是代碼的問題。本文提出了五個要點能夠幫助你的系統(tǒng)在規(guī)模增長的同時保證高可用性。

如您對可用性不是很了解凡壤,試試在微信后臺回復(fù)“可用性”來了解更多。

相關(guān)圖書推薦耙替,《可伸縮架構(gòu):面向增長應(yīng)用的高可用》

構(gòu)建一個高可用亚侠、可伸縮的應(yīng)用程序不是一件容易的事,也不會是天上掉下來的餡餅俗扇。問題總會以你從未預(yù)期的方式出現(xiàn)硝烂,讓你精心設(shè)計的功能對所有用戶都停止工作。

這些可用性問題通常會在你最想不到的地方出現(xiàn)铜幽,甚至一些最嚴重的問題會來自于最不可能出現(xiàn)的地方滞谢。

一次簡單的圖標故障

這發(fā)生在我親身經(jīng)歷的一個應(yīng)用程序中,是一次因為忽視依賴故障的典型案例啥酱。該程序向用戶提供了一個服務(wù)爹凹,為每個頁面頂部提供一個自定義的圖標厨诸,來表示當前登錄的用戶镶殷。這個圖標由一個第三方系統(tǒng)負責(zé)生成。

有一天微酬,這個生成圖標的第三方系統(tǒng)發(fā)生了故障绘趋。我們的應(yīng)用程序卻假設(shè)該系統(tǒng)總是會正常運行,因此并不知道如何處理這種情況颗管。結(jié)果是陷遮,我們的應(yīng)用程序也跟著發(fā)生故障。我們整個系統(tǒng)僅僅是因為圖標生成這樣一個非常小的“功能”垦江,導(dǎo)致無法提供任何服務(wù)帽馋。

如何才能避免這樣的問題呢?如果我們能夠預(yù)料到第三方系統(tǒng)可能發(fā)生故障,就可以在設(shè)計過程中考慮到這個故障發(fā)生的場景绽族,從而發(fā)現(xiàn)我們的應(yīng)用程序也會隨之發(fā)生故障姨涡。這樣,我們就能添加一些邏輯來檢查第三方服務(wù)吧慢,在問題發(fā)生時刪除圖標涛漂,或者在問題發(fā)生時捕獲錯誤,避免它傳遞下去并影響頁面的其他部分检诗。

一次小小的檢查和一些錯誤恢復(fù)機制匈仗,就可以幫助應(yīng)用程序保持正常運行。否則逢慌,我們的應(yīng)用程序就會經(jīng)歷嚴重的服務(wù)中斷悠轩。

所有這一切都是因為缺少了一個圖標。

沒人有能夠預(yù)料到問題會在何處發(fā)生攻泼,也不可能依靠測試來發(fā)現(xiàn)所有這些問題哗蜈。許多問題都是系統(tǒng)性的問題,而不僅僅是代碼的問題坠韩。

為了發(fā)現(xiàn)這些可用性的問題距潘,我們需要后退一步,系統(tǒng)地去了解應(yīng)用程序的運行機制只搁。以下是五個你可以關(guān)注音比、并且應(yīng)當關(guān)注的要點,它們能夠幫助你的系統(tǒng)在規(guī)模增長的同時保證高可用性:

時刻考慮應(yīng)對故障

時刻考慮如何伸縮

緩和風(fēng)險

監(jiān)控可用性

以可預(yù)期及明確的方式來處理可用性問題

讓我們來詳細講解其中的每一個要點氢惋。

要點1 :時刻考慮應(yīng)對故障

正如Amazon 的CTO Werner Vogels 所說洞翩,“所有事情每時每刻都會失敗”。你應(yīng)當提前為應(yīng)用程序和服務(wù)發(fā)生故障而做出計劃焰望。問題遲早會產(chǎn)生骚亿。不過現(xiàn)在,我們要講的是如何解決它熊赖。

假設(shè)你的應(yīng)用程序發(fā)生了故障来屠,那么它是如何發(fā)生的?當你構(gòu)建系統(tǒng)的時候震鹉,應(yīng)當在設(shè)計和實現(xiàn)的方方面面都考慮可用性俱笛。例如:

設(shè)計

你有考慮過任何設(shè)計模式嗎?你有使用它們來幫助你提升軟件的可用性嗎传趾?

通過使用一些設(shè)計模式迎膜,例如捕獲底層異常、重試邏輯和斷路器浆兰,可以幫助你捕獲錯誤并盡可能避免影響其他功能磕仅。這樣珊豹,你就能夠限制問題的影響范圍,即使應(yīng)用程序的某些部分出現(xiàn)問題榕订,依然能夠提供其他一些有用的功能平夜。

依賴

如果你依賴的組件出現(xiàn)了故障,你會怎樣做卸亮?你如何進行重試忽妒?如果問題是一個無法恢復(fù)的(硬件)故障,你會怎樣做兼贸?如果是一個可恢復(fù)的(軟件)故障呢段直?

斷路器模式在處理依賴故障時非常有用,因為它們可以降低依賴故障對你的系統(tǒng)的影響溶诞。

如果沒有斷路器鸯檬,你可能會因為依賴故障而降低系統(tǒng)的性能(例如,需要一個很長的超時機制來檢測故障)螺垢。而使用了斷路器喧务,你可以“放棄”并停止使用某個依賴,直到你確認它已經(jīng)恢復(fù)了正常工作枉圃。

用戶

如果出現(xiàn)問題的原因是系統(tǒng)的某個用戶功茴,你會怎樣做?你能夠處理海量的請求嗎孽亲?你能夠限制海量的流量嗎坎穿?你能夠處理傳入的垃圾數(shù)據(jù)嗎?如果數(shù)據(jù)量非常大返劲,你會怎樣做玲昧?

有些時候,拒絕式服務(wù)可能來自于“友方”篮绿。例如孵延,用戶可能會因為看到一個臨時活動,而導(dǎo)致大量請求增加亲配〕居Γ或者,用戶程序中的一個bug弃榨,可能導(dǎo)致他們向你的應(yīng)用程序拼命地發(fā)送請求菩收。如果這樣的事情發(fā)生了,你會怎樣做鲸睛?流量突增會讓你的應(yīng)用程序宕機嗎?或者你能否檢測出這種問題坡贺,通過限制請求的速度來降低或者消除它們的影響官辈?

要點2 :時刻考慮如何伸縮

你的系統(tǒng)現(xiàn)在正常運行箱舞,并不意味著它明天還能夠繼續(xù)正常運行。大多數(shù)Web 應(yīng)用程序的流量都是在不斷增加的拳亿。一個今天產(chǎn)生一定流量的網(wǎng)站晴股,明天可能會產(chǎn)生遠比你想象大得多的流量。當你構(gòu)建系統(tǒng)時肺魁,不要只考慮當前的流量电湘,要考慮未來的流量。

具體一點鹅经,這可能意味著:

設(shè)計出能夠增加數(shù)據(jù)庫數(shù)量和容量的架構(gòu)寂呛。

考慮限制你的數(shù)據(jù)伸縮的原因。當數(shù)據(jù)庫達到容量極限的時候會發(fā)生什么瘾晃?你需要確認這些限制因素并在到達極限之前解決它們贷痪。

你應(yīng)當能夠很容易地添加額外的應(yīng)用程序服務(wù)器。這通常需要仔細考慮在何處和如何來維護狀態(tài)蹦误,以及流量是如何路由的劫拢。注1

將靜態(tài)流量導(dǎo)向離線提供方。這樣你的系統(tǒng)只需要處理必要的動態(tài)流量强胰。使用外部的內(nèi)容分發(fā)網(wǎng)絡(luò)(CDN)不僅可以降低網(wǎng)絡(luò)需要處理的流量舱沧,也能夠利用CDN 的伸縮效率將靜態(tài)內(nèi)容更快地分發(fā)給用戶。

考慮是否可以靜態(tài)生成一些動態(tài)資源偶洋。通常來說狗唉,看上去動態(tài)顯示的內(nèi)容實際上大多數(shù)是靜態(tài)的,并且生成靜態(tài)內(nèi)容可以讓你的應(yīng)用程序提高可伸縮性涡真。這種“應(yīng)該靜態(tài)的動態(tài)資源”有些時候隱藏在你想象不到的地方分俯,如下文中所述。

究竟內(nèi)容應(yīng)該是靜態(tài)的還是動態(tài)的哆料?

通常缸剪,看上去是動態(tài)的內(nèi)容實際上大多數(shù)是靜態(tài)的。設(shè)想一個網(wǎng)站上常見的頂部導(dǎo)航欄东亦,絕大多數(shù)時候杏节,其中的內(nèi)容都是靜態(tài)的,但是偶爾也會出現(xiàn)一些動態(tài)的內(nèi)容典阵。

例如奋渔,如果你沒有登錄,頁面的頂部可能會顯示“請登錄”壮啊,如果你已經(jīng)登錄了則顯示“你好嫉鲸,Lee”(當然前提是你的名稱是Lee)。

這是否意味著整個頁面都必須動態(tài)生成呢歹啼?顯然不是玄渗。除了頁面的登錄/ 問候部分座菠,其他部分都是靜態(tài)的,通過CDN 可以輕松地進行分發(fā)并節(jié)省你的計算資源藤树。

當導(dǎo)航欄中大多數(shù)內(nèi)容都是靜態(tài)內(nèi)容時浴滴,你可以在用戶的瀏覽器中動態(tài)地將變更內(nèi)容添加到頁面上(例如根據(jù)具體情況添加“請登錄”或者“你好,Lee”的內(nèi)容)岁钓。通過將這些動態(tài)數(shù)據(jù)進行分組升略,并與靜態(tài)內(nèi)容加以區(qū)分,可以提高Web 頁面的性能屡限,降低應(yīng)用程序需要處理的動態(tài)數(shù)據(jù)量品嚣。這樣可以提高可伸縮性,并最終提高可用性囚霸。

要點3 :緩和風(fēng)險

保持系統(tǒng)高可用需要消除系統(tǒng)中的風(fēng)險腰根。當系統(tǒng)發(fā)生故障時,通常我們已經(jīng)在這之前將故障原因確定為了風(fēng)險拓型。因此额嘿,確定風(fēng)險是提高可用性的一個重要方法。所有的系統(tǒng)中都存在以下這些風(fēng)險:

存在系統(tǒng)崩潰的風(fēng)險

存在數(shù)據(jù)庫崩潰的風(fēng)險

存在返回結(jié)果不正確的風(fēng)險

存在網(wǎng)絡(luò)連接失敗的風(fēng)險

存在新部署的軟件功能出現(xiàn)故障的風(fēng)險

保持系統(tǒng)高可用需要消除風(fēng)險劣挫。但是當系統(tǒng)變得越來越復(fù)雜時册养,消除所有風(fēng)險也變得越來越不可能實現(xiàn)。保持一個大型系統(tǒng)高可用压固,更多的是來管理系統(tǒng)的風(fēng)險球拦,知道這些風(fēng)險是什么,哪些風(fēng)險是可接受的帐我,以及你能夠做什么來緩和風(fēng)險坎炼。

我們稱之為風(fēng)險管理,它是構(gòu)建高可用系統(tǒng)的核心內(nèi)容拦键。

風(fēng)險管理中的一個部分是風(fēng)險緩和谣光。風(fēng)險緩和指的是當問題發(fā)生時,我們知道如何去盡可能降低問題所帶來的影響芬为。緩和意味著即使當服務(wù)和資源不可用時萄金,依然盡可能確保你的系統(tǒng)以最好的、最完整的狀態(tài)工作媚朦。風(fēng)險緩和需要考慮哪些事情可能會出錯氧敢,并且立即制訂相應(yīng)的計劃,以便當問題發(fā)生時能夠提供相應(yīng)的解決方案询张。

示例:風(fēng)險緩和——一個沒有搜索功能的網(wǎng)上商店

假設(shè)有一個售賣T 恤的網(wǎng)上商店孙乖。它是一個很常見的在線商店,你可以在它的首頁上瀏覽T 恤,跳轉(zhuǎn)到其他頁面查看不同的T 恤分類的圆,并且可以搜索指定風(fēng)格和類型的T 恤鼓拧。

為了實現(xiàn)搜索的功能半火,通常這類網(wǎng)上商店需要調(diào)用一個獨立的搜索引擎越妈,這可能是一個單獨的服務(wù),或者甚至由第三方的搜索服務(wù)提供钮糖。

但是梅掠,因為搜索功能是一個獨立的功能,你的系統(tǒng)就存在搜索服務(wù)不可用的風(fēng)險店归。你的風(fēng)險管理計劃需要確定出該問題阎抒,并且將“搜索引擎失敗”列為風(fēng)險之一。

如果沒有風(fēng)險緩和計劃消痛,當搜索服務(wù)失敗時且叁,可能會產(chǎn)生一個錯誤頁面,或者返回不正確或無效的結(jié)果——不管怎樣秩伞,它都會帶來很差的用戶體驗逞带。

這個示例中的風(fēng)險緩和計劃可能是這樣的:

我們知道最受歡迎的T 恤是紅色條紋T 恤,60% 訪問網(wǎng)站的用戶最終都停留在(并很可能最后會購買)這個產(chǎn)品上纱新。因此展氓,如果搜索服務(wù)停止了,我們可以顯示一個“很抱歉”的頁面脸爱,下方是我們最受歡迎的T 恤列表遇汞,其中就包括紅色條紋T 恤。

這會鼓勵遇到這個錯誤頁面的用戶簿废,繼續(xù)瀏覽別人曾經(jīng)感興趣的T 恤空入。

此外,我們還可以顯示一個“下一次購買享受10% 折扣”的優(yōu)惠券族檬,這樣就可以鼓勵之前沒有進行購買的用戶歪赢,在搜索服務(wù)恢復(fù)正常后,繼續(xù)回到我們的網(wǎng)站上進行購買导梆。

示例演示了什么是風(fēng)險緩和轨淌,而確認風(fēng)險、確定該如何處理風(fēng)險看尼,以及如何實現(xiàn)這些緩和措施的過程則被稱為風(fēng)險管理递鹉。

風(fēng)險管理經(jīng)常會暴露應(yīng)用程序中未知的、需要立即修復(fù)的問題藏斩。它還可以用來處理已知的故障問題躏结,減少故障恢復(fù)時間或者降低嚴重性。

可用性和風(fēng)險管理息息相關(guān)狰域。構(gòu)建一個高可用的系統(tǒng)媳拴,主要就是要考慮如何管理風(fēng)險黄橘。

要點4 :監(jiān)控可用性

除非你看到問題發(fā)生,否則你不會知道應(yīng)用程序中存在著問題屈溉。你應(yīng)當確保對應(yīng)用程序進行了適當?shù)谋O(jiān)控塞关,以便可以從外部和內(nèi)部兩個視角來觀察應(yīng)用程序的運行狀況。

監(jiān)控的程度取決于應(yīng)用程序的特點和要求子巾,但是通常必須具備以下這些監(jiān)控帆赢。

服務(wù)器監(jiān)控

監(jiān)控服務(wù)器的健康狀況,并且確保它們始終在有效運行线梗。

配置變化監(jiān)控

監(jiān)控系統(tǒng)配置的變化椰于,以便確定它們對應(yīng)用程序的影響。

應(yīng)用程序性能監(jiān)控

深入了解你的應(yīng)用程序和服務(wù)仪搔,確保它們按照預(yù)期運行瘾婿。

人為測試

從用戶的角度來實時檢測應(yīng)用程序的運行情況,以便在用戶真正發(fā)現(xiàn)問題之前發(fā)現(xiàn)它們烤咧。

報警

當問題發(fā)生時通知相關(guān)人員偏陪,以便使問題可以得到快速有效的解決,將對用戶的影響降低到最小髓削。

如今市面上有許多非常優(yōu)秀的監(jiān)控系統(tǒng)竹挡,包括免費和付費的服務(wù)。我個人推薦NewRelic立膛,它提供了之前提到的所有監(jiān)控和報警能力揪罕。作為一款軟件即服務(wù)(SaaS)的軟件,它能夠支持任何規(guī)模的應(yīng)用系統(tǒng)的監(jiān)控需求宝泵。當你對應(yīng)用程序和服務(wù)進行監(jiān)控之后好啰,請開始尋找它們的運行趨勢。當你明確了一定的趨勢之后儿奶,可以開始尋找一些異常值框往,將它們作為可能存在的可用性問題。你可以利用這些異常值闯捎,在系統(tǒng)發(fā)生故障之前通過監(jiān)控工具來發(fā)送警報椰弊。除此之外,你還可以在系統(tǒng)增長過程中時刻進行跟蹤瓤鼻,確北妫可伸縮性計劃的實施。

你應(yīng)當為服務(wù)間通信建立內(nèi)部的茬祷、私有的運行目標清焕,并持續(xù)對它們進行監(jiān)控。通過這種方式,當出現(xiàn)任何與性能或者可用性相關(guān)的問題時秸妥,你都可以快速診斷出哪個服務(wù)或者系統(tǒng)出現(xiàn)了問題滚停,并定位問題的原因。此外粥惧,你可以發(fā)現(xiàn)一些“熱點”——即性能超出預(yù)期的地方键畴,以及針對這些問題制訂相應(yīng)的開發(fā)計劃。

要點5 :以預(yù)測和確定的方式來應(yīng)對可用性問題

如果你對監(jiān)控中所發(fā)生的問題置之不理影晓,那么監(jiān)控系統(tǒng)就毫無用處镰吵。這意味著當問題發(fā)生時必須要發(fā)出報警檩禾,這樣你才能有所行動挂签。除此之外,你應(yīng)當建立整個團隊都遵循的流程盼产,幫助診斷問題饵婆,并輕松修復(fù)常見的故障問題。

例如戏售,如果某個系統(tǒng)無法響應(yīng)侨核,你可能會有一系列措施來解決。這其中可能包括運行一個測試來診斷問題原因灌灾,重啟一個已知會導(dǎo)致系統(tǒng)無法響應(yīng)的守護進程搓译,或者當其他手段都失敗時重啟整個服務(wù)器。為常見的故障問題提供標準化流程可以降低系統(tǒng)不可用的時間锋喜。此外些己,它們還可以提供更多有用的診斷信息,幫助工程師團隊找到常見問題的根本原因嘿般。

當觸發(fā)某個服務(wù)的報警時段标,該服務(wù)的負責(zé)人必須是第一個被通知到的。畢竟炉奴,他們負責(zé)修復(fù)自己服務(wù)中的所有問題逼庞。但是,其他與之緊密相關(guān)或依賴的團隊也應(yīng)當收到報警信息瞻赶。例如赛糟,如果某個團隊使用了一個特殊服務(wù),他們希望知道該服務(wù)什么時候出現(xiàn)故障砸逊,從而在問題發(fā)生時能夠更加主動地保證自己的系統(tǒng)不受影響璧南。

這些標準的流程和辦法應(yīng)當被寫進支持手冊中,團隊中每個負責(zé)人人手一份痹兜。這本支持手冊還應(yīng)該包含相關(guān)系統(tǒng)和服務(wù)的聯(lián)系人列表穆咐,以及當無法用簡單手段解決問題時,需要上報問題的聯(lián)系人列表。

所有這些流程对湃、辦法以及支持手冊都應(yīng)該提前準備好崖叫,以便當服務(wù)出現(xiàn)問題時,值班人員能準確知道如何在不同的情況下進行操作拍柒,快速恢復(fù)服務(wù)心傀。這些流程和辦法之所以非常有效,是因為故障通常都發(fā)生在一些不太方便的時間點拆讯,例如午夜或者周末這些效率比較低下的時間脂男。這些建議可以幫助你的團隊更聰明、更安全地將系統(tǒng)恢復(fù)到可運行狀態(tài)种呐。

做好準備

沒人能夠預(yù)測到可用性問題在什么地方宰翅、什么時間發(fā)生。但是你可以假設(shè)它們會發(fā)生爽室,尤其是當你的系統(tǒng)面臨越來越多的用戶需求汁讼,變得越來越復(fù)雜的時候。提前做好處理可用性問題的準備阔墩,是降低問題出現(xiàn)概率和嚴重性的最佳方法嘿架。

本文選自《可伸縮架構(gòu):面向增長應(yīng)用的高可用》,點此鏈接可在博文視點官網(wǎng)查看此書啸箫。

想及時獲得更多精彩文章耸彪,可在微信中搜索“博文視點”或者掃描下方二維碼并關(guān)注。

原文鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末忘苛,一起剝皮案震驚了整個濱河市蝉娜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌柑土,老刑警劉巖蜀肘,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異稽屏,居然都是意外死亡扮宠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門狐榔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來坛增,“玉大人,你說我怎么就攤上這事薄腻∈盏罚” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵庵楷,是天一觀的道長罢艾。 經(jīng)常有香客問我楣颠,道長,這世上最難降的妖魔是什么咐蚯? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任童漩,我火速辦了婚禮,結(jié)果婚禮上春锋,老公的妹妹穿的比我還像新娘矫膨。我一直安慰自己,他們只是感情好期奔,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布颗味。 她就那樣靜靜地躺著碰纬,像睡著了一般寿弱。 火紅的嫁衣襯著肌膚如雪错沽。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天搁胆,我揣著相機與錄音弥搞,去河邊找鬼。 笑死渠旁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的船逮。 我是一名探鬼主播顾腊,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼挖胃!你這毒婦竟也來了杂靶?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤酱鸭,失蹤者是張志新(化名)和其女友劉穎吗垮,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凹髓,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡烁登,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蔚舀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饵沧。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖赌躺,靈堂內(nèi)的尸體忽然破棺而出狼牺,到底是詐尸還是另有隱情,我是刑警寧澤礼患,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布是钥,位于F島的核電站掠归,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏悄泥。R本人自食惡果不足惜拂到,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望码泞。 院中可真熱鬧兄旬,春花似錦、人聲如沸余寥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽宋舷。三九已至绪撵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間祝蝠,已是汗流浹背音诈。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留绎狭,地道東北人细溅。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像儡嘶,于是被迫代替她去往敵國和親喇聊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容