RabbitMQ中AMQP 0-9-1模型講解

這個指導提供一個AMQP 0-9-1協(xié)議的概述凌节,它是RabbitMq支持的一個協(xié)議。

什么是AMQP 0-9-1朴上?

AMQP 0-9-1是一個能使客戶端和符合條件的消息中間代理通訊的消息協(xié)議痪宰。

代理和他們的角色

消息代理從發(fā)送者接受消息和路由他們想消費者衣撬。由于它是一個網(wǎng)絡(luò)協(xié)議扮饶,發(fā)送者甜无,消費者岂丘,代理可以位于不同的機器上。

AMQP0-9-1 模型的簡述

AMQP模型遵循下面觀點:消息被發(fā)送到交換機元潘,它常比作是郵局或郵箱。之后它能分發(fā)消息副本到隊列使用定義的綁定規(guī)則牲距。AMQP代理可以發(fā)送消息給訂閱隊列的消費者牍鞠,或者消費者可以按需求從隊列中拉取消息难述。


當發(fā)送一條消息胁后,發(fā)送者可以指定各種各樣的消息屬性(消息元數(shù)據(jù))攀芯。一些元數(shù)據(jù)被通過代理使用侣诺,然而,它的其他部分對代理是完全不透明的年鸳,只給接受消息的應用使用趴久。

網(wǎng)絡(luò)是不可靠的和應用可能處理消息會失敗,所有AMQP模型有消息確認的概念搔确。當消息發(fā)送到消費者時彼棍,消費者可通過,一種是自動的或者應用開發(fā)者選擇處理完后就通知代理妥箕。當使用消息確認時,只要代理收到一個對這個消息的通知更舞,它就會完全從隊列中刪除這條消息(或者一群消息)

在某種情況下畦幢,例如,當消息不能路由宇葱,消息可能會返回給發(fā)送者,或者丟棄掉印颤,如果代理實現(xiàn)了一個擴展,被放入死信隊列(dead letter queue)矢否。發(fā)送者這可以通過發(fā)送消息時使用某一參數(shù)來處理這種情況屑彻。

隊列壶谒,交換機和綁定共同稱為AMQP實體让禀。

AMQP是一個可編程協(xié)議

從某種意義說AMQP0-9-1是一個可編程協(xié)議,AMQP實體和路由方案主要由應用自身定義腮敌,而不是代理由代理管理。因此捌木,聲明隊列娶靡,交換機漠烧,定義它們之間的綁定,訂閱隊列等等都是為協(xié)議操作準備的慈俯。

這給應用開發(fā)者大量的自由而且需要它們關(guān)注潛在的定義沖突。在練習中,定義沖突是少見的嘗嘗會表明錯誤的配置突梦。

應用聲明它們需要的AMQP0-9-1實體,定義需要的路由方案以及當它們不在使用實體的時候選擇刪除娃闲。

交換機和交換機類型

交換機是一個消息發(fā)送目的地的AMQP實體卷哩。它能持有消息并路由它到一個或者多個隊列。路由算法的使用依靠交換機類型和綁定的規(guī)則,AMQP0-9-1代理提供了四中交換機類型:

名稱? ?|? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?默認預聲明名稱

-------|-------------------------

直接交換機? ? ? ? ? ? ? ? ? ? ?|? ? ? ? ? ? ? 空串和amq.direct

扇區(qū)交換機? ? ? ? ? ? ? ? ? ? ? |? ? ? ? ? ? ? amq.fanout

主題交換機? ? ? ? ? ? ? ? ? ? ? ?|? ? ? ? ? ? ?amq.topic

頭交換機? ? ? ? ? ? ? ? ? ? ? ? ? ?|? ? ? ? ? ? ?amq.match(在RabbitMq中是amq.header)

除了交換機類型栋齿,交換機可以聲明一些屬性励堡,下面是最重要的:

名稱

持久化(代理重啟交換機存活)

自動刪除(當沒有隊列綁定它的時候交換機刪除)

參數(shù)(可選,被插件或者指定代理特征使用)

交換機能持久化或者臨時的鹅龄,持久化的交換機重啟能存活而臨時交換機不能。不是所有場景和使用例子都需要交換機持久化。

默認交換機

  默認交換機是一個通過代理生成沒名字的預聲明的直接交換機。它有一個特殊屬性那能使得它非常有用為了簡單的應用:每一個隊列被創(chuàng)建自動綁定到它用和隊列名稱相同的路由key兄渺。

例如叔壤,當你聲明一個隊列名稱為"search-indexing-online", AMQP0-9-1代理能綁定向默認交換機使用search-indexing-online作為路由key庐扫。因此铅辞,一個消息被發(fā)送向默認的交換機用這個路由key "search-indexing-online"路由到隊列"search-indexing-online"。換句話說囤踩,默認交換機就好像是直接發(fā)送消息向隊列,即使技術(shù)上不是這樣的。

直接交換機

直接交換機發(fā)送消息向隊列基于消息的路由鍵愉镰。一個直接交換機對單播路由消息(雖然它們也可以被使用單播路由)。這是它如何工作的:

一個隊列用路由K綁定到交換機

當一條新的消息用路由R到達直接交換機,這個交換機路由這條消息向隊列遗锣,如果K = R

直接交換機常常被使用在多個工作者之間分發(fā)任務(相同應用的實例)用輪詢的方式。當是這樣的時候笔咽,理解它是很重要的,用AMQP 0-9-1拯田,消息在消費者之間是負載均衡的而不是在隊列中甩十。

直接交換機如下圖所示:


扇出交換機

扇出交換機路由消息到所有綁定它的隊列而且路由關(guān)鍵字被忽略。如果一N個隊列綁定到扇出交換機姓蜂,當一個新的消息發(fā)送到那個交換機時消息副本被發(fā)送到N個隊列钱慢。扇出交換機對廣播路由消息是種理想的選擇滩字。

因為扇出交換機發(fā)送副本消息到每個綁定它的隊列挟裂,它的使用案例和下面的非常類似:

大規(guī)模的多玩家在線游戲使用它為了排行榜更新或其他的全局事件渠啤。

運動新聞網(wǎng)站使用扇出交換機為實時的分發(fā)成績更新向手機客戶端。

分布式系統(tǒng)廣播各種狀態(tài)和配置更新。

群組聊天能在參與者之間發(fā)布信息使用扇出交換機(但是AMQP沒有內(nèi)置的展現(xiàn)概念,因此XMPP可能是更好的選擇)


主題交換機

主題交換機路由消息到一個或者多個隊列基于消息路由鍵和隊列綁定到交換機模式的匹配贵试。主題交換機類型常常被使用實現(xiàn)各種各樣的發(fā)布和訂閱模式變種琉兜。主題交換機通常被用來做多播消息路由。

主題交換機有一個廣泛的使用集毙玻。無論什么時候一個問題涉及到多個消費者它們可以有選擇性的選擇接受哪些消息類型往声。主題交換機應該被考慮。

使用案例:

發(fā)布相關(guān)的具體地理位置數(shù)據(jù)太防,例如,銷售點仁连,多任務的后臺處理,處理指定任務集的能力阱穗,股票數(shù)據(jù)更新饭冬。

涉及到類別化和標簽化的新聞更新。等等

頭交換機

一個頭交換機被設(shè)計為在多個路由屬性上它是更容易表示的作為消息頭比一個路由鍵揪阶。頭交換機會忽略路由屬性昌抠。相反,為了路由屬性會從頭屬性中持有鲁僚。一個消息會認為被匹配炊苫,如果一個頭的值等于在綁定上指定的值。

為了匹配綁定到隊列到頭交換機肯能會使用多個頭冰沙。在這種情況下侨艾,代理需要從應用開發(fā)者那里多一個信息,也就是說拓挥,它應該考慮是匹配任何一個頭還是它們的所有唠梨?這就是靠"x-match"參數(shù)去綁定。當"x-match"參數(shù)設(shè)置為"any"時侥啤,只要一個匹配的頭值就充足了当叭。或者設(shè)置"x-match"為all將會強制多個值匹配盖灸。

頭交換機可以被看作是直接交換機的一類蚁鳖。因為他們是基于路由值的,他們能使用直接交換機哪里路由key不僅僅是字符串糠雨;它還可以是一個整數(shù)或者哈希才睹。

隊列

在AMQP 0-9-1模型的隊列和其他消息的任務隊列系統(tǒng)非常相似:他們是存儲消息能被應用消費徘跪。隊列有一些和交換機共享的屬性甘邀,也有一些額外的屬性:

名稱

持久化(代理重啟隊列可以存活)

專用的(只被一個鏈接使用,當沒有消費者訂閱時自動刪除)

自動刪除(當沒有消費者使用垮庐,隊列刪除)

參數(shù)(可選的松邪,被插件或者指定代理特征使用,例如消息過期時間(message TTL), 隊列長度限制等)

在使用隊列之前需要聲明哨查。如果隊列不存在聲明隊列會使得它被創(chuàng)建逗抑。如果這個隊列存在而且聲明時使用的屬性相同,這個聲明不會有影響。當這個存在的隊列屬性和聲明不同時邮府,在通道層會發(fā)生一個代碼為406的異常荧关。

隊列名稱

應用可以選擇一個隊列名稱或者詢問代理產(chǎn)生一個名稱。隊列名稱可以達到UTF-8字符編碼的255個字節(jié)褂傀。AMQP 0-9-1代理能產(chǎn)生一個唯一的隊列名稱忍啤。為了使用這個特征,通過一個空串作為隊列名稱參數(shù)仙辟。產(chǎn)生的名稱將會返回至客戶端聲明隊列的響應中同波。

隊列名稱以amq.開頭的被預留在代理內(nèi)部。嘗試聲明一個這樣的隊列名稱將會違反這個規(guī)則會導致拋出一個通道層的403異常叠国。

隊列持久化

持久化隊列能保存到硬盤和因此代理重啟會存活未檩。不持久化的隊列是臨時的。不是所有的場景和使用案例都要強制隊列持久化粟焊。

隊列的持久化不會使路由到該隊列的消息持久化冤狡。如果一個隊列宕機了和之后恢復,持久化的隊列在代理重啟的時候重新聲明项棠,然后筒溃,只有持久化的消息才會被恢復。

綁定

綁定是交換機使用路由消息向隊列的規(guī)則沾乘。為通知一個交換機E路由消息到隊列Q怜奖,Q不得不綁定到E。綁定有一個被一些交換機使用的可選路由鍵屬性翅阵。路由鍵的目的是選擇一個消息發(fā)送到路由到綁定隊列的一個交換機歪玲,換句話說,路由鍵扮演一個過濾器掷匠。

類似于這樣的描述:

隊列就像你的目的地在紐約城市

交換機就像肯尼迪機場

綁定就是從肯尼迪到你目的地的路線滥崩。有零個或者多種方式到達。

有這個中間層能夠使路由場景變成可能讹语,不然直接發(fā)送到隊列是非常難實現(xiàn)的也消除了應用開發(fā)者來回復制的工作钙皮。

如果AMQP消息不能路由到任何隊列,它會被丟棄掉或者會返回給發(fā)送者顽决,依靠發(fā)送者在消息屬性上的設(shè)置短条。

消費者

存儲消息在隊列中是無用的除非應用消費了他們。在AMQP 0-9-1模型中才菠,有兩種方法可以消費:

有消息發(fā)送給他們("push API")

按需抓取消息("pull API")

用"push API" 應用會表明從指定隊列消費消息的興趣茸时。當他們這么做,我們說他們注冊了一個消費者赋访,簡單說可都,就是訂閱一個隊列缓待。它是可能的每個隊列有多個消費者或者注冊一個專用的消費者(從隊列中排除所有其他的消費者當它消費的時候)

每個消費者有一個標識符被稱為消費者標簽。它能被使用取消訂閱消息渠牲。這個標簽是一個字符串

消息確認

消費者應用--應用會接受和處理消息--可能偶爾失敗處理個別消息或者有時宕機旋炒。也有可能是網(wǎng)絡(luò)問題造成。這將會發(fā)生一個問題:AMQP代理什么時候從隊列中移除消息签杈?AMQP有兩個選擇:

代理發(fā)送一條消息到應用后国葬。

一個應用發(fā)送一個回執(zhí)確認。

前者是被稱為自動確認模型芹壕,而后者一個明確的確認模式汇四。明確模型可以應用選擇什么時候發(fā)送確認模型。它能在接受一條消息后踢涌,也可以在處理之前存儲數(shù)據(jù)之后通孽,也可以在完全處理消息之后(例如:成功抓取一個網(wǎng)頁,處理和存儲它之后)

如果消費者宕機沒有發(fā)送一個確認到AMQP代理將會重新傳遞它像另一個消費者睁壁,或者當是沒有提供時背苦,代理將會等到至少有一個消費者注冊到相同隊列才會嘗試重新投遞。

拒絕消息

當消費者應用收到一條消息潘明,處理消息可能成功可能失敗行剂。一個應用將會向代理表明這消息處理失敗而拒絕消息。當拒絕消息時钳降,一個應用會要求一個代理丟棄還是重新入隊列厚宰。當只有一個消費者在一個隊列上,確保你不要創(chuàng)建一個無限消息傳遞循環(huán)通過拒絕和重新排隊一個消息從相同的消費者一次又一次的遂填。

否認確認

消息可以使用AMQP的basic.reject方法拒絕铲觉。這個方法有一個限制:沒有拒絕多條消息的方式。然而如果你使用RabbitMQ,就會有一個解決方法吓坚。RabbitMq提供了一個AMQP 0-9-1擴展被稱為否認確認或nacks撵幽。更多信息,請參考the help page.

預抓取消息

當多個消費者共享一個隊列時礁击,它是有用的為了指定每個消費者能被發(fā)送多少消息在發(fā)送下一次確認之前盐杂。這被用來作為一個簡單的負載均衡技術(shù)和提高吞吐量如果消息傾向于批量發(fā)送的話。例如哆窿,如果一個生產(chǎn)應用由于它所做的工作每分鐘發(fā)送消息

注意RabbitMQ值支持通道層面的與抓取數(shù)量链烈,不是基于連接和大小的預取。

消息屬性和負載

在AMQP模型中消息有屬性更耻。一些屬性在AMQP 0-9-1說明定義他們是很普遍的和應用開發(fā)者不必要精確知道屬性名测垛。例如:

Content type(內(nèi)容類型)

Content encoding(內(nèi)容編碼)

Routing key(路由鍵)

Delivery mode (persistent or not)(是否持久化)

Message priority(消息優(yōu)先級)

Message publishing timestamp(消息發(fā)布的時間戳)

Expiration period(過期時間)

Publisher application id(發(fā)布的應用id)

一些屬性是被AMQP代理使用,但是大多數(shù)是對接受他們的應用作說明的秧均。一些屬性是可選的和稱為頭食侮。他們類似于HTTP中的頭。當消息被發(fā)送時消息屬性被設(shè)置目胡。

AMQP消息也有一個有效負載(他們能持有多少數(shù)據(jù))锯七,它被消息代理對待為一個不透明的字節(jié)數(shù)組。這個代理不會去檢查和修改負載誉己。對一個消息只包含屬性和沒有有效負載也是可能的眉尸。對數(shù)據(jù)進行json,Thrift巨双,Protocol buffers和消息包裹的結(jié)構(gòu)化數(shù)據(jù)序列化微樂發(fā)送一條有效負載消息噪猾。AMQP的對等體通常使用"content-type"和"content-encoding"域去交流這個信息,這已經(jīng)是慣例了筑累。

消息能被持久化發(fā)送袱蜡,它會使AMQP代理持久化它們向硬盤。如果服務器重啟系統(tǒng)可以確保它收到的消息不會丟失慢宗。簡單的發(fā)送消息向一個持久化的交換機或者被路由到持久化的隊列不會使消息持久化:它是依靠消息他自身的持久化模式坪蚁。發(fā)布持久化消息會影響性能。

消息確認

由于網(wǎng)絡(luò)是不可靠的和應用會失敗镜沽,它常常需要有處理確認的機制敏晤。有時它只需要的當一個消息被接受的時就確認,有時確認意味著被消息被消費者驗證和處理缅茉,例如嘴脾,核實是否有強制的數(shù)據(jù)和持久化數(shù)據(jù)。

這個解決是很普遍的蔬墩,因此AMQP 0-9-1有一個內(nèi)置的消息確認機制機制(被稱為acks)那消費者使用它確認消息發(fā)送了或處理了统阿。如果一個應用宕掉(當一個連接關(guān)閉AMQP代理會知道)。如果一個消息確認被期待筹我,而AMQP代理沒收到扶平,消息會重新排列(可能會立即發(fā)送到另一個存在的消費者)

有消息確認能幫助開發(fā)者構(gòu)建穩(wěn)定的軟件。

AMQP 0-9-1方法

AMQP 0-9-1 構(gòu)成了一些方法蔬蕊。方法的操作和面向?qū)ο缶幊陶Z言沒有共同點结澄。AMQP方法被分成了類,類是AMQP方法的邏輯分作岸夯。

讓我們看看交換機的這些類麻献,一組關(guān)聯(lián)的方法在交換機上。它包括如下操作:

exchange.declare

exchange.declare-ok

exchange.delete

exchange.delete-ok

上面的這些操作邏輯方法對:exchange.declare?and?exchange.declare-ok,?exchange.delete?and?exchange.delete-ok. 這些操作是請求和響應(發(fā)送給代理響應對上述的請求)

作為一個例子猜扮,客戶端要求代理聲明一個新的交換機使用exchange.declare方法


作為上面顯示的圖標勉吻,exchange.declare攜帶幾個參數(shù)。他們能讓客戶端指定交換機的名稱旅赢,類型齿桃,持久化標簽等等惑惶。

如果一個操作成功,代理將會通過exchange.declare-ok方法:


exchange.declare-ok除了通道編碼不會攜帶任何參數(shù)短纵。

不是所有的AMQP方法都是相對的带污,一些(basic.publish 用的最廣泛)不會有響應方法和另外(例如basic.get)比一個響應更多。

連接

AMQP連接通常是長期存活的香到。AMQP是一個應用層協(xié)議它使用TCP可靠傳送鱼冀。AMQP連接使用認證和能使用TLS保護。當應用不再需要連接向AMQP代理的時候悠就,它應該優(yōu)雅關(guān)閉AMQP連接而不是突然關(guān)閉潛在的TCP連接

通道

一些應用需要多個連接向AMQP代理千绪。然而,同事打開多個TCP連接是不好的因為它會消耗系統(tǒng)資源和配置防火墻也是困難的梗脾。AMQP 0-9-1連接是多路復用的通道它是輕量級的連接被單個TCP 連接共享荸型。

為了應用使用多線程處理,為每個線程打開一個通道而不是通道之間共享藐唠。

在一個指定的通道的通信和另一個通道通信是完全隔離的帆疟。因此每個AMQP方法會攜帶一個客戶端使用的通道編碼為了方法是使用的哪個通道。

虛擬主機

為了使單個代理隔離成多個主機環(huán)境(用戶宇立,交換機踪宠,隊列等等的群),AMQP包括了一個虛擬主機的概念妈嘹。他們類似于虛擬機被用于多個流行的Web服務器和提供完全的隔離環(huán)境在AMQP下柳琢。AMQP客戶端會在AMQP連接期間指定他們想要使用什么樣的Vhosts.

AMQP的擴展

Custom exchange types(定制交換機類型)讓開發(fā)者去實現(xiàn)路由方案,箱外的交換機類型沒有涉及的情況下润脸,例如基于地理數(shù)據(jù)的路由柬脸。

交換機和隊列聲明包括額外的屬性也是代理能使用的。例如per-queue message TTL(每個消息隊列的過期時間)毙驯,可以通過該方式實現(xiàn)倒堕。

特定代理對協(xié)議擴展,例如爆价,extensions that RabbitMQ implements

New AMQP 0-9-1 method classes(新的AMQP 0-9-1方法類)介紹

代理能擴展additional plugins(額外的插件)垦巴,例如RabbitMQ management(RabbitMq管理前端)和Http Api被作為插件實現(xiàn)

這些特征能使AMQP 0-9-1模型更加靈活和可以應用于非常廣泛的問題

AMQP 0-9-1客戶端的生態(tài)體系

有大量的many AMQP 0-9-1 clients為了大量流行的編程語言和平臺,他們的一些遵循AMQP術(shù)語和僅僅提供AMQP方法的實現(xiàn)铭段。其他的會有額外的特征骤宣,方便方法和抽象。有一些客戶端是異步的序愚,一些是同步的憔披,一些都支持。一些客戶端支持指定供應的擴展(例如,特定的RabbitMq擴展)芬膝。

由于AMQP的主要目標是互操作性望门,所以開發(fā)者要理解協(xié)議操作而不要限于他們自己指定客戶端庫的術(shù)語。這方法會讓開發(fā)者使用不同庫會更加容易蔗候。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末怒允,一起剝皮案震驚了整個濱河市埂软,隨后出現(xiàn)的幾起案子锈遥,更是在濱河造成了極大的恐慌,老刑警劉巖勘畔,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件所灸,死亡現(xiàn)場離奇詭異,居然都是意外死亡炫七,警方通過查閱死者的電腦和手機爬立,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來万哪,“玉大人侠驯,你說我怎么就攤上這事∞任。” “怎么了吟策?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長的止。 經(jīng)常有香客問我檩坚,道長,這世上最難降的妖魔是什么诅福? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任匾委,我火速辦了婚禮,結(jié)果婚禮上氓润,老公的妹妹穿的比我還像新娘赂乐。我一直安慰自己,他們只是感情好咖气,可當我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布挨措。 她就那樣靜靜地躺著,像睡著了一般采章。 火紅的嫁衣襯著肌膚如雪运嗜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天悯舟,我揣著相機與錄音担租,去河邊找鬼。 笑死抵怎,一個胖子當著我的面吹牛奋救,可吹牛的內(nèi)容都是我干的岭参。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尝艘,長吁一口氣:“原來是場噩夢啊……” “哼演侯!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起背亥,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤秒际,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后狡汉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體娄徊,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年盾戴,在試婚紗的時候發(fā)現(xiàn)自己被綠了寄锐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡尖啡,死狀恐怖橄仆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情衅斩,我是刑警寧澤盆顾,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站矛渴,受9級特大地震影響椎扬,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜具温,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一蚕涤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧铣猩,春花似錦揖铜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至峦椰,卻和暖如春龄寞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背汤功。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工物邑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓色解,卻偏偏與公主長得像茂嗓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子科阎,可洞房花燭夜當晚...
    茶點故事閱讀 44,976評論 2 355

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