解析使用 Mesos 管理虛擬機(jī)

摘要

為了滿足渲染坯台、基因測(cè)序等計(jì)算密集型服務(wù)的需求秆剪,UCloud 已推出了“計(jì)算工廠”產(chǎn)品,讓用戶可以快速創(chuàng)建大量的計(jì)算資源(虛擬機(jī))本砰。該產(chǎn)品的背后碴裙,是一套基于 Mesos 的計(jì)算資源管理系統(tǒng)。本文主要介紹該系統(tǒng)的結(jié)構(gòu)、Mesos 在 UCloud 的使用青团、我們的解決方案以及遇到的問(wèn)題譬巫。

業(yè)務(wù)需求

我們的需求主要是兩個(gè)方面:

1. 同時(shí)支持虛擬機(jī)和容器。在“容器化”的浪潮下督笆,為什么我們還需要支持虛擬機(jī)呢芦昔?首先,一些業(yè)務(wù)有嚴(yán)格的安全隔離要求娃肿,容器雖好咕缎,但還做不到和虛擬機(jī)同等級(jí)的隔離性。其次料扰,一些業(yè)務(wù)程序不能運(yùn)行在 Linux 上凭豪,比如圖片、動(dòng)畫的渲染軟件大都是 Windows 程序晒杈。

2. 整合多地域多數(shù)據(jù)中心嫂伞。我們的資源來(lái)源于一些擁有閑置資源的合作伙伴,這些資源散布于多個(gè)地域的多個(gè)數(shù)據(jù)中心中拯钻。我們的平臺(tái)需要能夠支持全局的調(diào)度帖努,同時(shí)盡可能減小運(yùn)營(yíng)、運(yùn)維的成本粪般。

簡(jiǎn)單地說(shuō)拼余,我們需要有一個(gè)平臺(tái),統(tǒng)一封裝多個(gè)數(shù)據(jù)中心的計(jì)算資源亩歹,并且同時(shí)支持虛擬機(jī)匙监、容器等多種形式的資源使用方式。

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖1:計(jì)算資源管理平臺(tái)的需求示意圖

說(shuō)到虛擬機(jī)小作,首先想到的就是 UCloud 自己的 UHost 和開源的 OpenStack亭姥,然而,這兩套系統(tǒng)都是針對(duì)大型公有云的場(chǎng)景躲惰,而且主要只針對(duì)于虛擬機(jī)這一種業(yè)務(wù)致份。它們功能豐富、模塊眾多础拨,運(yùn)維運(yùn)營(yíng)上都需要很大的成本氮块。然而我們的業(yè)務(wù)并不需要這么多功能。

最終诡宗,我們選擇了基于 Mesos 來(lái)實(shí)現(xiàn)這套平臺(tái)滔蝉。

為什么選擇 Mesos

Mesos是Apache下的開源分布式資源管理框架,它是一個(gè)分布式系統(tǒng)的內(nèi)核塔沃。

通過(guò) Mesos蝠引,一個(gè)數(shù)據(jù)中心所提供的不再是一臺(tái)臺(tái)服務(wù)器,而是一份份的資源。資源可以是 CPU 核數(shù)螃概、內(nèi)存矫夯、存儲(chǔ)、GPU 等等吊洼。如果把一個(gè)數(shù)據(jù)中心當(dāng)做一個(gè)操作系統(tǒng)的話训貌,Mesos 就是這個(gè)操作系統(tǒng)的內(nèi)核。

我們選擇 Mesos 的原因在于它擁有高度可擴(kuò)展性冒窍,同時(shí)又足夠簡(jiǎn)單递沪。

作為內(nèi)核,Mesos 只提供最基礎(chǔ)的功能:資源管理综液、任務(wù)管理款慨、調(diào)度等。并且每一種功能谬莹,都以模塊的方式實(shí)現(xiàn)檩奠,方便進(jìn)行定制。架構(gòu)上届良,Master 和 Agent 兩個(gè)模塊就實(shí)現(xiàn)了資源相關(guān)的所有工作笆凌,用戶只需根據(jù)自己的業(yè)務(wù)邏輯實(shí)現(xiàn) Framework 和 Executor 即可圣猎。這樣就支持我們能夠把計(jì)算資源封裝成虛擬機(jī)士葫、容器等各種形式。

采用 Mesos 來(lái)進(jìn)行容器編排的方案已經(jīng)被很多廠商使用送悔,相關(guān)的資料文檔也比較豐富慢显。然而用 Mesos 來(lái)管理虛擬機(jī),業(yè)內(nèi)并沒(méi)有應(yīng)用于生產(chǎn)環(huán)境的實(shí)踐欠啤。本文的余下內(nèi)容荚藻,主要向讀者分享一下 UCloud 用 Mesos 管理虛擬機(jī)的思路和實(shí)踐經(jīng)驗(yàn)。

Mesos 簡(jiǎn)介

Mesos 采用 Master-Agent 架構(gòu)洁段。Master 負(fù)責(zé)整體資源的調(diào)度并對(duì)外提供 API应狱。Agent 部署在所有機(jī)器上,負(fù)責(zé)調(diào)用 Executor 執(zhí)行任務(wù)祠丝、向 Master 匯報(bào)狀態(tài)等疾呻。

Mesos 提供了一個(gè)雙層調(diào)度模型:

1. Master 在 Framework 之間進(jìn)行資源調(diào)度;

2. 每個(gè) Framework 內(nèi)部實(shí)現(xiàn)各自業(yè)務(wù)的資源調(diào)度写半。

整體架構(gòu)如下圖:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖2:Mesos 的雙層調(diào)度結(jié)構(gòu)圖

架構(gòu)設(shè)計(jì)

整體架構(gòu)

在 Mesos 的雙層調(diào)度模型上岸蜗,平臺(tái)的整體架構(gòu)如下圖:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖3:基于Mesos的資源管理平臺(tái)整體架構(gòu)圖

結(jié)構(gòu)如下:

1. 每個(gè) IDC 一套或多套 Mesos 集群;

2. 每個(gè) Mesos 集群一個(gè) Cluster Server叠蝇,與 Mesos Master 以及 Framework 交互璃岳,負(fù)責(zé)集群內(nèi)部的調(diào)度、狀態(tài)收集和任務(wù)下發(fā);

3. 一個(gè)Mesos集群上有多個(gè)Framework铃慷,一個(gè) Framework 負(fù)責(zé)一種業(yè)務(wù)单芜,比如 VM Scheduler 管理虛擬機(jī),Marathon Framework 管理Docker任務(wù)犁柜;

4. VM Framework框架實(shí)現(xiàn)管理的 Excutor 是基于Libvirt缓溅,實(shí)現(xiàn)虛擬機(jī)的創(chuàng)建、重啟赁温、刪除等操作坛怪;

5. 所有 Cluster Server 統(tǒng)一向 API Server 匯報(bào),上報(bào)狀態(tài)股囊、獲取任務(wù)袜匿;

6. API Server 負(fù)責(zé)主要業(yè)務(wù)邏輯,以及集群間的調(diào)度稚疹、資源和任務(wù)的管理等等居灯;

7. API Gateway 提供 API 給 UCloud 控制臺(tái)(Console)。

基于 HTTP 的通信

系統(tǒng)內(nèi)的所有通信都基于 HTTP内狗。

首先怪嫌,Mesos 內(nèi)部基于 libprocess 各組件之間的通信都依賴 libprocess 庫(kù),該庫(kù)用 C++ 實(shí)現(xiàn)了 Actor 模式柳沙。每個(gè) Actor 會(huì)監(jiān)聽 HTTP 請(qǐng)求岩灭,向 Actor 發(fā)消息的過(guò)程就是把消息體序列化后放在 HTTP 報(bào)文中,然后請(qǐng)求這個(gè) Actor赂鲤。

其次噪径,業(yè)務(wù)相關(guān)的各個(gè)組件API Server、Cluster Server 等也都通過(guò) Restful 的 API 提供服務(wù)数初。

HTTP 的優(yōu)點(diǎn)在于簡(jiǎn)單可靠找爱、易于開發(fā)調(diào)試和擴(kuò)展。

VM Scheduler

對(duì)于 Docker 容器泡孩,我們采用 Marathon Framework 進(jìn)行管理车摄。而對(duì)于虛擬機(jī),我們則采用自己開發(fā)的 VM Scheduler Framework 仑鸥。

VM Scheduler 從 Master 獲取一個(gè)個(gè)的資源 Offer 吮播。一個(gè)資源 Offer 包含了某個(gè) Agent 上可用的資源。當(dāng)有虛擬機(jī)任務(wù)需要執(zhí)行的時(shí)候锈候,Cluster Server 會(huì)把任務(wù)的具體信息發(fā)送給 VM Scheduler薄料。

任務(wù)分為兩類:

1. 創(chuàng)建/刪除一個(gè)虛擬機(jī)。此時(shí)需要傳入虛擬機(jī)的配置信息泵琳、包括鏡像摄职、網(wǎng)絡(luò)誊役、存儲(chǔ)等。VM Scheduler 根據(jù)這些信息谷市,匹配滿足要求的 Resource Offer蛔垢,然后生成 Task 提交給 Mesos Master 去執(zhí)行。

2. 操作一個(gè)虛擬機(jī)迫悠,如開關(guān)機(jī)鹏漆、重啟、鏡像制作等创泄。此時(shí) VM Scheduler 會(huì)和 VM Executor 通過(guò) Framework Message 通信艺玲,告訴后者去執(zhí)行具體的操作。

VM Executor

Task 是 Mesos 中資源分配的最小單位鞠抑。Master 會(huì)告訴 Agent 需要執(zhí)行哪些 Task饭聚,Agent 也會(huì)把 Task 的狀態(tài)匯報(bào)給 Master。根據(jù) Task 的信息搁拙,Agent 會(huì)下載并啟動(dòng)所需的 Executor秒梳,然后把具體的 Task 描述傳給它。

VM Executor 是我們開發(fā)的對(duì)虛擬機(jī)的生命周期進(jìn)行管理的 Executor箕速,實(shí)現(xiàn)了對(duì)虛擬機(jī)創(chuàng)建酪碘、刪除、開關(guān)機(jī)盐茎、鏡像制作等功能兴垦。

VM Executor 啟動(dòng)后,根據(jù) Task 的描述庭呜,動(dòng)態(tài)生成虛擬機(jī)需要的配置文件滑进,然后調(diào)用 libvirt 進(jìn)行虛擬機(jī)創(chuàng)建。當(dāng)收到來(lái)自 VM Scheduler 的 Framework Message 時(shí)募谎,又調(diào)用 libvirt 進(jìn)行開關(guān)機(jī)等操作。

狀態(tài)的管理是實(shí)現(xiàn)虛擬機(jī)管理的關(guān)鍵部分阴汇。通過(guò) Mesos 我們只能拿到 Task 的狀態(tài)数冬,RUNING 表示虛擬機(jī)創(chuàng)建成功,F(xiàn)AILED 表示虛擬機(jī)失敗搀庶,F(xiàn)INISHED 表示虛擬機(jī)成功銷毀拐纱。然而除此之外,一個(gè)虛擬機(jī)還存在“開機(jī)中”哥倔、“關(guān)機(jī)中”秸架、“關(guān)機(jī)”、“鏡像制作中”等其他狀態(tài)咆蒿。我們通過(guò)在 VM Executor 和 VM Scheduler 之間進(jìn)行心跳东抹,把這些狀態(tài)同步給 VM Scheduler蚂子。后者對(duì)狀態(tài)進(jìn)行判斷,如果發(fā)現(xiàn)狀態(tài)改變了缭黔,就發(fā)送一條狀態(tài)更新的消息給 Cluster Server食茎,然后再轉(zhuǎn)發(fā)給 API Server,最終更新到數(shù)據(jù)庫(kù)馏谨。

虛擬機(jī)的調(diào)度

首先看一下一個(gè) Task 在 Mesos 中是怎么調(diào)度的:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?圖4:Mesos 資源調(diào)度過(guò)程示意圖

上面的示例中:

1. Agent 向 Master 匯報(bào)自己所擁有的資源别渔;

2. Master 根據(jù) Dominant Resource Fairness(DRF) 調(diào)度算法,把這份資源作為一個(gè) Resource Offer 提供給 Framework 1惧互;

3. Framework 1 根據(jù)自己的業(yè)務(wù)邏輯哎媚,告訴 Master 它準(zhǔn)備用這份資源啟動(dòng)兩個(gè) Task;

4. Master 通知 Agent 啟動(dòng)這兩個(gè) Task喊儡。

對(duì)應(yīng)到虛擬機(jī)的情況抄伍,調(diào)度分兩個(gè)部分:

1. 選擇集群。默認(rèn)情況下管宵,API Server 根據(jù)資源需求截珍,從注冊(cè)上來(lái)的集群中選擇一個(gè)擁足夠資源的集群,然后把資源需求分配給該集群箩朴。另外岗喉,還可以針對(duì)不同的公司、項(xiàng)目等維度制定在某個(gè)集群運(yùn)行炸庞;

2. 集群內(nèi)調(diào)度钱床。Cluster Server 從 API Server 處獲取到資源需求,比如說(shuō)需要 200 個(gè)核埠居,于是根據(jù) Mesos 當(dāng)前資源使用情況查牌,創(chuàng)建出一個(gè)“資源計(jì)劃”,200個(gè)核被分配為4個(gè)48核虛擬機(jī)和1個(gè)8核虛擬機(jī)滥壕。然后通知 Framework 按照這份計(jì)劃來(lái)創(chuàng)建5個(gè)Task纸颜。

資源的標(biāo)識(shí)

服務(wù)器之間除了 CPU、內(nèi)存绎橘、硬盤等可能不同外胁孙,還會(huì)存在其他的差別。比如有時(shí)候業(yè)務(wù)要求一定要用某個(gè)型號(hào)的 CPU称鳞,有時(shí)候要求一定要擁有 SSD等等涮较。為了支持更多維度的調(diào)度,我們利用了 Mesos 的 Resource 和 Attribute 來(lái)標(biāo)識(shí)不同的資源冈止。

Resource是 Mesos 中的一個(gè)概念狂票,表示一切用戶需要使用的東西。Agent 默認(rèn)會(huì)自動(dòng)添加 cpus熙暴、gpus闺属、mem慌盯、ports 和 disk 這5種資源。另外還可以在 Agent 啟動(dòng)時(shí)屋剑,通過(guò)參數(shù)指定其他資源润匙。

Attribute 以 Key-Value 形式的標(biāo)簽,標(biāo)識(shí)一個(gè) Agent 擁有的屬性唉匾,同樣可以在啟動(dòng)時(shí)通過(guò)參數(shù)指定孕讳。

通過(guò) Resource 和 Attribute 的靈活運(yùn)用,可以標(biāo)識(shí)出更多的資源情況巍膘,滿足各種資源調(diào)度需求厂财。比如通過(guò) Resource 指定 SSD 大小、CPU型號(hào)峡懈,通過(guò) Attribute 標(biāo)識(shí)機(jī)架位璃饱、是否擁有外網(wǎng) IP,是否支持超線程等等肪康。Framework 收到一個(gè) Resource Offer 后荚恶,與待執(zhí)行的任務(wù)需求進(jìn)行匹配,通過(guò) Resource 判斷資源是否夠用磷支,再通過(guò) Attribute 判斷是否滿足其他維度的需求谒撼,最終決定是否用這個(gè) Offer 來(lái)創(chuàng)建 Task。

鏡像雾狈、存儲(chǔ)和網(wǎng)絡(luò)管理

平臺(tái)提供了一些基礎(chǔ)鏡像廓潜,另外用戶也可以基于自己的虛擬機(jī)創(chuàng)建自己的鏡像。這些鏡像文件統(tǒng)一存儲(chǔ)在一個(gè)基于 GlusterFS 的分部署存儲(chǔ)服務(wù)中善榛,該服務(wù)掛載在每臺(tái)物理機(jī)上辩蛋。

有些業(yè)務(wù)場(chǎng)景需要部分虛擬機(jī)能夠共享同一份存儲(chǔ),于是我們還是基于 GlusterFS 開發(fā)了用戶存儲(chǔ)服務(wù)移盆,能夠根據(jù)用戶的配置悼院,在虛擬機(jī)創(chuàng)建時(shí)自動(dòng)掛載好。

在網(wǎng)絡(luò)方面味滞,每個(gè)用戶可以創(chuàng)建多個(gè)子網(wǎng)樱蛤,各個(gè)子網(wǎng)之間做了網(wǎng)絡(luò)隔離。創(chuàng)建虛擬機(jī)時(shí)剑鞍,需要指定使用哪個(gè)子網(wǎng)。

其他問(wèn)題

在使用 Mesos 的過(guò)程中爽醋,我們也遇到了其他一些問(wèn)題蚁署。

問(wèn)題一:Marathon選主異常

當(dāng)機(jī)器負(fù)載比較高,尤其是 IO 較高時(shí)蚂四,我們發(fā)現(xiàn) Marathon 集群有概率出現(xiàn)不能選主的情況光戈。

我們懷疑是由于 Marathon 節(jié)點(diǎn)和 ZK 的網(wǎng)絡(luò)不穩(wěn)定哪痰,觸發(fā)了 Marathon 或 Mesos 的 Bug導(dǎo)致。于是通過(guò) iptables 主動(dòng)屏蔽 Leader ZK 端口的方式久妆,成功復(fù)現(xiàn)出問(wèn)題晌杰。

通過(guò)在 Marathon 的代碼中加上一些 Leader 選舉相關(guān)的最終日志,成功定位到了問(wèn)題筷弦,原來(lái)是由于 Mesos Driver 的 stop() 方法沒(méi)有成功引起 start() 方法退出阻塞導(dǎo)致肋演。

由于我們的所有程序都是通過(guò)守護(hù)進(jìn)程啟動(dòng)的,所以我們采用了一個(gè)最簡(jiǎn)單的解決方案:修改 Marathon 代碼烂琴,當(dāng) ZK 發(fā)生異常時(shí)爹殊,直接自殺。自殺后守護(hù)進(jìn)程會(huì)把程序再啟動(dòng)起來(lái)奸绷。

問(wèn)題二:go-marathon問(wèn)題

我們的服務(wù)采用 Golang 開發(fā)梗夸,使用 go-marathon 庫(kù)與 Marathon 進(jìn)行交互。使用過(guò)程中發(fā)現(xiàn)該庫(kù)有一些問(wèn)題:

不支持多 Marathon 節(jié)點(diǎn)号醉。于是我們自己創(chuàng)建了一個(gè)分支反症,采用節(jié)點(diǎn)主動(dòng)探測(cè)的方式,實(shí)現(xiàn)了多節(jié)點(diǎn)的支持畔派。(原庫(kù) v5.0 版本以后也支持了該功能)

使用設(shè)有 Timeout 的 http.Client 進(jìn)行 go-marathon 的初始化時(shí)铅碍,訂閱 SSE 會(huì)產(chǎn)生超時(shí)問(wèn)題。于是我們做了修改父虑,普通的 HTTP API 和 SSE 不使用同一個(gè) http.Client该酗,操作 SSE 的 http.Client 不設(shè)置 Timeout。

網(wǎng)絡(luò)異常時(shí)士嚎,go-marathon 的方法調(diào)用會(huì) Hang 住呜魄。于是我們所有對(duì) go-marathon 方法的調(diào)用都加上超時(shí)控制。

結(jié)語(yǔ)

Mesos 在 UCloud 有著廣泛的應(yīng)用莱衩,對(duì)外有“計(jì)算工廠”和 UDocker 等產(chǎn)品爵嗅,對(duì)內(nèi)則支撐著公司內(nèi)網(wǎng)虛擬機(jī)管理平臺(tái)。伴隨著持續(xù)的實(shí)踐笨蚁,我們對(duì) Mesos 的理解和掌控也越來(lái)越深入睹晒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市括细,隨后出現(xiàn)的幾起案子伪很,更是在濱河造成了極大的恐慌,老刑警劉巖奋单,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锉试,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡览濒,警方通過(guò)查閱死者的電腦和手機(jī)呆盖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門拖云,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人应又,你說(shuō)我怎么就攤上這事宙项。” “怎么了株扛?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵尤筐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我席里,道長(zhǎng)叔磷,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任奖磁,我火速辦了婚禮改基,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咖为。我一直安慰自己秕狰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布躁染。 她就那樣靜靜地躺著鸣哀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吞彤。 梳的紋絲不亂的頭發(fā)上我衬,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音饰恕,去河邊找鬼挠羔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛埋嵌,可吹牛的內(nèi)容都是我干的破加。 我是一名探鬼主播,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼雹嗦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼范舀!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起了罪,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锭环,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后泊藕,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體田藐,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年吱七,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了汽久。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡踊餐,死狀恐怖景醇,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情吝岭,我是刑警寧澤三痰,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站窜管,受9級(jí)特大地震影響散劫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜幕帆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一获搏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧失乾,春花似錦常熙、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至纽竣,卻和暖如春墓贿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背蜓氨。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工聋袋, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人语盈。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓舱馅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親刀荒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子代嗤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

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