消息隊(duì)列之通信協(xié)議

1摘完、消息隊(duì)列是什么

分布式系統(tǒng)中常用通訊模型主要是“請(qǐng)求-應(yīng)答”模型和“發(fā)布-訂閱”模型。前者常見(jiàn)如RPC通訊枉侧,常用HTTP REST或Dubbo等協(xié)議汞幢;后者多指消息隊(duì)列通訊。

RPC大多屬于請(qǐng)求-應(yīng)答模式舰罚,也包括越來(lái)越多響應(yīng)式范式纽门,對(duì)于需要點(diǎn)對(duì)點(diǎn)交互、強(qiáng)事務(wù)保證和延遲敏感的服務(wù)/應(yīng)用之間的通信营罢,RPC是優(yōu)于消息隊(duì)列的赏陵。

消息隊(duì)列(Message Queue饼齿,MQ)可以看做是一種異步RPC,把一次RPC變?yōu)閮纱位蚨啻悟ΓM(jìn)行內(nèi)容轉(zhuǎn)存缕溉,再在合適的時(shí)機(jī)投遞出去。消息的發(fā)送者和接收者不需要在同一時(shí)間與消息隊(duì)列進(jìn)行交互吃型,消息在被處理或被刪除之前一直存儲(chǔ)在隊(duì)列上证鸥。

1.png

消息隊(duì)列提供一個(gè)臨時(shí)存儲(chǔ)消息的輕量級(jí)緩存區(qū),以及允許軟件組件連接到隊(duì)列以發(fā)送接受消息的的終端節(jié)點(diǎn)勤晚。這些消息通常較小枉层,可以是請(qǐng)求、恢復(fù)赐写、錯(cuò)誤消息或明文消息等鸟蜡。要發(fā)送消息時(shí),一個(gè)名為“生產(chǎn)者”的組件將消息添加到隊(duì)列血淌。消息將存儲(chǔ)在隊(duì)列中矩欠,直至名為“消費(fèi)者”的另一組件檢索該消息并執(zhí)行相關(guān)操作。

許多生產(chǎn)者和消費(fèi)者都可以使用隊(duì)列悠夯,但一條信息只能有一組消費(fèi)者處理一次癌淮。因此,這種消息收發(fā)模式通常稱為一對(duì)一或點(diǎn)對(duì)點(diǎn)通信沦补。如果消息需要由多個(gè)消費(fèi)者進(jìn)行處理乳蓄,可以將將消息隊(duì)列與發(fā)布/訂閱結(jié)合起來(lái)使用。

2夕膀、消息隊(duì)列協(xié)議

AMQP虚倒、MQTTSTOMP是三種最常見(jiàn)、最流行的基于TCP/IP的消息傳遞協(xié)議产舞。

2.1 AMQP

AMQP魂奥,即高級(jí)消息隊(duì)列協(xié)議(Advanced Message Queuing Protocol),一個(gè)提供統(tǒng)一消息服務(wù)的應(yīng)用層標(biāo)準(zhǔn)高級(jí)消息隊(duì)列協(xié)議易猫,是應(yīng)用層協(xié)議的一個(gè)開(kāi)放標(biāo)準(zhǔn)耻煤,為面向消息的中間件設(shè)計(jì)∽纪牵基于此協(xié)議的客戶端與消息中間件可傳遞消息哈蝇,并不受客戶端/中間件不同產(chǎn)品,不同的開(kāi)發(fā)語(yǔ)言等條件的限制攘已。

核心角色如下:

  • Message(消息):消息服務(wù)器處理消息的原子單元炮赦,包括一個(gè)內(nèi)容頭,一組屬性和一個(gè)內(nèi)容體样勃。
    消息有優(yōu)先級(jí)吠勘,高優(yōu)先級(jí)的消息在等待同一消息隊(duì)列時(shí)會(huì)比低優(yōu)先級(jí)的消息先發(fā)送性芬,而且當(dāng)消息必須被丟棄時(shí),低優(yōu)先級(jí)的消息優(yōu)先被丟棄看幼。
    使用AMQP協(xié)議批旺,消息服務(wù)器不能修改內(nèi)容體和內(nèi)容頭,但可以在內(nèi)容頭上添加額外信息诵姜。
  • PubLisher(消息生產(chǎn)者):發(fā)送消息
  • Consumer(消息消費(fèi)者):消費(fèi)消息
  • Broker(消息代理):消息隊(duì)列服務(wù)器汽煮,負(fù)責(zé)接收客戶端連接,路由消息棚唆。
  • Queue(消息隊(duì)列):Broker中的一個(gè)角色暇赤,一個(gè)Broker中可以有多個(gè)Queue,負(fù)責(zé)保存消息直到發(fā)送給不同的消費(fèi)者宵凌。算是消息的容器鞋囊。一個(gè)消息可以被投入一個(gè)或多個(gè)隊(duì)列中,每個(gè)隊(duì)列的消息都會(huì)等待消費(fèi)者連接到這個(gè)隊(duì)列并被取走瞎惫。
  • Exchange(交換路由):Broker中的一個(gè)角色溜腐,負(fù)責(zé)接收生產(chǎn)者發(fā)送的消息,并路由給服務(wù)器中的隊(duì)列瓜喇⊥σ妫可以被理解成一個(gè)規(guī)則表,指明消息該被投到哪個(gè)隊(duì)列中乘寒。
  • Channel(信道):信道是一條獨(dú)立的雙向數(shù)據(jù)流通道望众。為了解決操作系統(tǒng)無(wú)法承受每秒建立特別多的TCP連接。

生產(chǎn)者發(fā)送消息時(shí)伞辛,必須指定消息要被路由到哪些個(gè)消息隊(duì)列中烂翰。當(dāng)消息到消息隊(duì)列中,消息隊(duì)列會(huì)嘗試將消息傳給消費(fèi)者蚤氏,如果失敗甘耿,消息隊(duì)列會(huì)存儲(chǔ)消息并等待消費(fèi)者。如果沒(méi)有消費(fèi)者竿滨,消息隊(duì)列將選擇性的將消息返回給生產(chǎn)者佳恬。如果消息別消費(fèi)掉,消息隊(duì)列會(huì)刪除消息姐呐,刪除的過(guò)程或者是及時(shí)的殿怜,或者是等到消費(fèi)者消費(fèi)結(jié)果后才刪除的典蝌。

RabbitMQ是AMQP消息隊(duì)列最有名的開(kāi)源實(shí)現(xiàn)曙砂,當(dāng)然RabbitMQ同時(shí)還可以通過(guò)插件支持STOMP、MQTT等協(xié)議接入骏掀。Kafka鸠澈、RocketMQ均使用自定義的協(xié)議柱告。

2.2 MQTT

MQTT,即消息隊(duì)列遙測(cè)傳輸(Message Queuing Telemetry Transport)笑陈。由IBM開(kāi)發(fā)际度,現(xiàn)在被廣泛用于物聯(lián)網(wǎng)公司。因?yàn)樗奶攸c(diǎn)就是輕量涵妥,簡(jiǎn)單乖菱,開(kāi)放和易于實(shí)現(xiàn)。所以它常用于很多計(jì)算能力有限蓬网、帶寬低窒所、網(wǎng)絡(luò)不可靠的遠(yuǎn)程通信應(yīng)用場(chǎng)景。

核心角色如下:

  • Publisher(發(fā)布者):消息發(fā)布客戶端
  • Subscriber(訂閱者):消息訂閱客戶端
  • Broker(消息代理):消息服務(wù)器端
  • Application Message(應(yīng)用消息):指通過(guò)網(wǎng)絡(luò)傳輸?shù)膽?yīng)用數(shù)據(jù)帆锋,一般包括主題和負(fù)載吵取。
  • Topic(主題):應(yīng)用消息的類型,一般消息發(fā)布者會(huì)確定消息的主題锯厢,訂閱者根據(jù)自己實(shí)際情況選擇不同的主題進(jìn)行消息訂閱消費(fèi)皮官。
  • Payload(負(fù)載):消息訂閱者具體接收的內(nèi)容。

MQTT協(xié)議是通過(guò)交換預(yù)定義的MQTT控制報(bào)文來(lái)通信的实辑,控制報(bào)文內(nèi)容由三部分組成:固定報(bào)頭捺氢,可變報(bào)頭和消息體。固定報(bào)頭通過(guò)標(biāo)識(shí)不同位的值來(lái)確定報(bào)文類型徙菠,包括發(fā)布訂閱的一些完成狀態(tài)等讯沈;可變報(bào)頭的內(nèi)容根據(jù)控制報(bào)文類型不同而不同,常作為包的標(biāo)識(shí)符婿奔;消息體也是根據(jù)不同的消息類型有著不同的內(nèi)容缺狠。

MQTT協(xié)議中,客戶端和服務(wù)端是通過(guò)請(qǐng)求-應(yīng)答模式通信的萍摊〖非眩客戶端發(fā)送一條控制報(bào)文數(shù)據(jù)給服務(wù)器,服務(wù)器再發(fā)送一條控制報(bào)文數(shù)據(jù)給客戶端冰木。

MQTT在發(fā)布消息時(shí)穷劈,有三種Qos等級(jí):

  • 至多一次(0級(jí))
  • 至少一次(1級(jí))
  • 只有一次(2級(jí))

至多一次等級(jí)最低,客戶端只需要將消息發(fā)出去即可踊沸,這種等級(jí)很低歇终,用于消息不重要但特別多,為了減輕通信壓力逼龟,就不顧質(zhì)量评凝,只看數(shù)量了。

至少一次等級(jí)中等腺律,客戶端要保證發(fā)出去的消息至少一次被服務(wù)端接收到奕短,所以要收到服務(wù)端的回應(yīng)宜肉,否則一直發(fā),這種等級(jí)一般用于服務(wù)端有冪等處理翎碑,所以不怕重復(fù)消費(fèi)谬返,還要保證消息不會(huì)丟失。

只有一次等級(jí)最高日杈,客戶端先發(fā)消息過(guò)去遣铝,然后本地記錄一個(gè)我已發(fā)送,但不確定你是否收到的狀態(tài)莉擒,然后服務(wù)端接收到消息后翰蠢,回給客戶端一個(gè)我已接收的報(bào)文,同時(shí)服務(wù)端記錄一個(gè)我不確定你知不知道我已接收的狀態(tài)啰劲,然后客戶端收到這個(gè)已接收的消息后梁沧,就確定服務(wù)端收到這個(gè)消息了,于是把自己本地記錄的已發(fā)送未確定的狀態(tài)刪除蝇裤,同時(shí)再給客戶端發(fā)送一個(gè)我已經(jīng)知道你收到的報(bào)文廷支,服務(wù)端收到這個(gè)報(bào)文,也會(huì)把自己之前記錄的狀態(tài)刪掉栓辜,整個(gè)一條報(bào)文只有一次的通信才算完成恋拍,這種等級(jí)就比較嚴(yán)格了,但質(zhì)量上去了藕甩,相對(duì)低等級(jí)的施敢,數(shù)量就會(huì)相對(duì)小些,但可靠就是王道狭莱,不多不少才是最好的僵娃。

只有一次的發(fā)送和確定,其實(shí)思想和三次握手差不多腋妙,都是兩端互相確認(rèn)的過(guò)程默怨,所以會(huì)一來(lái)一回的。如果傳輸過(guò)程中出現(xiàn)丟包骤素,都會(huì)由發(fā)送者重發(fā)上一條消息匙睹。

2.3 STOMP

STOMP,即流文本定向消息協(xié)議(Streaming Text Orientated Messaging Protocal)济竹,是一個(gè)相對(duì)簡(jiǎn)單的文本消息傳輸協(xié)議痕檬,主要特點(diǎn)就是簡(jiǎn)單易懂,沒(méi)有特別多的套路送浊。

核心角色如下:

  • 客戶端:既可以是生產(chǎn)者梦谜,也可以是消費(fèi)者
  • 服務(wù)端:消息中心

ActiveMQ以及它的下一代實(shí)現(xiàn)Apache Apollo,是STOMP協(xié)議的典型實(shí)現(xiàn)。

3改淑、JMS

3.1 概述

JMS(Java MessageService)實(shí)際上是一套JAVA API接口,是由Sun公司早期提出的消息標(biāo)準(zhǔn)浴讯,旨在為java應(yīng)用提供統(tǒng)一的消息操作朵夏,包括create、send榆纽、receive等仰猖。

嚴(yán)格來(lái)講,JMS并不屬于消息協(xié)議奈籽,而是一種規(guī)范饥侵,是對(duì)AMQP,MQTT衣屏,STOMP等協(xié)議更高一層的抽象躏升。從使用角度看,JMS和JDBC擔(dān)任差不多的角色狼忱,用戶都是根據(jù)相應(yīng)的接口可以和實(shí)現(xiàn)了JMS的服務(wù)進(jìn)行通信膨疏,進(jìn)行相關(guān)的操作。

JMS通常包含如下一些角色:

  • JMS provider:實(shí)現(xiàn)了JMS接口的消息中間件钻弄,如ActiveMQ

  • JMS client:生產(chǎn)或者消費(fèi)消息的應(yīng)用

  • JMS producer/publisher:JMS消息生產(chǎn)者

  • JMS consumer/subscriber:JMS消息消費(fèi)者

  • JMS message:消息佃却,在各個(gè)JMS client傳輸?shù)膶?duì)象

  • JMS queue:Provider存放等待被消費(fèi)的消息的地方

  • JMS topic:一種提供多個(gè)訂閱者消費(fèi)消息的一種機(jī)制;在MQ中常常被提到窘俺,topic模式

消息如何從producer端達(dá)到consumer端由message-routing來(lái)決定饲帅。在JMS中,消息路由非常簡(jiǎn)單瘤泪,由producer和consumer鏈接到同一個(gè)queue(p2p)或者topic(pub/sub)來(lái)實(shí)現(xiàn)消息的路由灶泵。JMSconsumer同時(shí)支持message selector(消息選擇器),通過(guò)消息選擇器对途,consumer可以只消費(fèi)那些通過(guò)了selector篩選的消息丘逸。

3.2 通信模型

JMS具有兩種通信模式:

  • Point-to-Point Messaging Domain (點(diǎn)對(duì)點(diǎn))

  • Publish/Subscribe Messaging Domain (發(fā)布/訂閱模式)

在JMS API出現(xiàn)之前,大部分產(chǎn)品使用“點(diǎn)對(duì)點(diǎn)”和“發(fā)布/訂閱”中的任一方式來(lái)進(jìn)行消息通訊掀宋。JMS定義了這兩種消息發(fā)送模型的規(guī)范深纲,它們相互獨(dú)立。任何JMS的提供者可以實(shí)現(xiàn)其中的一種或兩種模型劲妙,這是它們自己的選擇湃鹊。JMS規(guī)范提供了通用接口保證我們基于JMS API編寫(xiě)的程序適用于任何一種模型。

3.2.1 點(diǎn)對(duì)點(diǎn)模型

2.png

在點(diǎn)對(duì)點(diǎn)通信模式中镣奋,應(yīng)用程序由消息隊(duì)列币呵,發(fā)送方,接收方組成。每個(gè)消息都被發(fā)送到一個(gè)特定的隊(duì)列余赢,接收者從隊(duì)列中獲取消息芯义。隊(duì)列保留著消息,直到他們被消費(fèi)或超時(shí)妻柒。

  • 每個(gè)消息只要一個(gè)消費(fèi)者
  • 發(fā)送者和接收者在時(shí)間上是沒(méi)有時(shí)間的約束扛拨,也就是說(shuō)發(fā)送者在發(fā)送完消息之后,不管接收者有沒(méi)有接受消息举塔,都不會(huì)影響發(fā)送方發(fā)送消息到消息隊(duì)列中绑警。
  • 發(fā)送方不管是否在發(fā)送消息,接收方都可以從消息隊(duì)列中去到消息
  • 接收方在接收完消息之后央渣,需要向消息隊(duì)列應(yīng)答成功

3.2.2 發(fā)布/訂閱模型

3.png

在發(fā)布/訂閱消息模型中计盒,發(fā)布者發(fā)布一個(gè)消息,該消息通過(guò)topic傳遞給所有的客戶端芽丹。該模式下北启,發(fā)布者與訂閱者都是匿名的,即發(fā)布者與訂閱者都不知道對(duì)方是誰(shuí)拔第。并且可以動(dòng)態(tài)的發(fā)布與訂閱Topic暖庄。Topic主要用于保存和傳遞消息,且會(huì)一直保存消息直到消息被傳遞給客戶端楼肪。

  • 一個(gè)消息可以傳遞個(gè)多個(gè)訂閱者(即:一個(gè)消息可以有多個(gè)接受方)
  • 發(fā)布者與訂閱者具有時(shí)間約束培廓,針對(duì)某個(gè)主題(Topic)的訂閱者,它必須創(chuàng)建一個(gè)訂閱者之后春叫,才能消費(fèi)發(fā)布者的消息肩钠,而且為了消費(fèi)消息,訂閱者必須保持運(yùn)行的狀態(tài)暂殖。
  • 為了緩和這樣嚴(yán)格的時(shí)間相關(guān)性价匠,JMS允許訂閱者創(chuàng)建一個(gè)可持久化的訂閱。這樣呛每,即使訂閱者沒(méi)有被激活(運(yùn)行)踩窖,它也能接收到發(fā)布者的消息。

3.3 接收消息

在JMS中晨横,消息的產(chǎn)生和消息是異步的洋腮。對(duì)于消費(fèi)來(lái)說(shuō),JMS的消息者可以通過(guò)兩種方式來(lái)消費(fèi)消息手形。

  • 同步(Synchronous)
    在同步消費(fèi)信息模式模式中啥供,訂閱者/接收方通過(guò)調(diào)用 receive()方法來(lái)接收消息。在receive()方法中库糠,線程會(huì)阻塞直到消息到達(dá)或者到指定時(shí)間后消息仍未到達(dá)伙狐。
  • 異步(Asynchronous)
    使用異步方式接收消息的話,消息訂閱者需注冊(cè)一個(gè)消息監(jiān)聽(tīng)者,類似于事件監(jiān)聽(tīng)器贷屎,只要消息到達(dá)罢防,JMS服務(wù)提供者會(huì)通過(guò)調(diào)用監(jiān)聽(tīng)器的onMessage()遞送消息。

3.4 編程模型

4.png
  • Connection Factories:創(chuàng)建Connection對(duì)象的工廠唉侄,針對(duì)兩種不同的jms消息模型咒吐,分別有QueueConnectionFactory和TopicConnectionFactory兩種∶谰桑可以通過(guò)JNDI來(lái)查找ConnectionFactory對(duì)象”岫眨客戶端使用一個(gè)連接工廠對(duì)象連接到JMS服務(wù)提供者榴嗅,它創(chuàng)建了JMS服務(wù)提供者和客戶端之間的連接。JMS客戶端(如發(fā)送者或接受者)會(huì)在JNDI名字空間中搜索并獲取該連接陶舞。使用該連接嗽测,客戶端能夠與目的地通訊,往隊(duì)列或話題發(fā)送/接收消息肿孵。
  • Destination:目的地指明消息被發(fā)送的目的地以及客戶端接收消息的來(lái)源唠粥。JMS使用兩種目的地,隊(duì)列和話題
  • Connection:表示在客戶端和JMS系統(tǒng)之間建立的鏈接(對(duì)TCP/IP socket的包裝)停做。Connection可以產(chǎn)生一個(gè)或多個(gè)Session晤愧。跟ConnectionFactory一樣,Connection也有兩種類型:QueueConnection和TopicConnection蛉腌。
  • Session:對(duì)消息進(jìn)行操作的接口官份,可以通過(guò)session創(chuàng)建生產(chǎn)者、消費(fèi)者烙丛、消息等舅巷。Session 提供了事務(wù)的功能,如果需要使用session發(fā)送/接收多個(gè)消息時(shí)河咽,可以將這些發(fā)送/接收動(dòng)作放到一個(gè)事務(wù)中钠右。
  • Producter:消息生產(chǎn)者由Session創(chuàng)建,用于往目的地發(fā)送消息忘蟹。生產(chǎn)者實(shí)現(xiàn)MessageProducer接口飒房,我們可以為目的地、隊(duì)列或話題創(chuàng)建生產(chǎn)者媚值。
  • Consumer:消息消費(fèi)者由Session創(chuàng)建情屹,用于接收被發(fā)送到Destination的消息。
  • MessageListener:消息監(jiān)聽(tīng)器杂腰。如果注冊(cè)了消息監(jiān)聽(tīng)器垃你,一旦消息到達(dá),將自動(dòng)調(diào)用監(jiān)聽(tīng)器的onMessage方法。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末惜颇,一起剝皮案震驚了整個(gè)濱河市皆刺,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌凌摄,老刑警劉巖羡蛾,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異锨亏,居然都是意外死亡痴怨,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門器予,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)浪藻,“玉大人,你說(shuō)我怎么就攤上這事乾翔“” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵反浓,是天一觀的道長(zhǎng)萌丈。 經(jīng)常有香客問(wèn)我,道長(zhǎng)雷则,這世上最難降的妖魔是什么辆雾? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮月劈,結(jié)果婚禮上乾颁,老公的妹妹穿的比我還像新娘。我一直安慰自己艺栈,他們只是感情好英岭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著湿右,像睡著了一般诅妹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上毅人,一...
    開(kāi)封第一講書(shū)人閱讀 51,578評(píng)論 1 305
  • 那天吭狡,我揣著相機(jī)與錄音,去河邊找鬼丈莺。 笑死划煮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缔俄。 我是一名探鬼主播弛秋,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼器躏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了蟹略?” 一聲冷哼從身側(cè)響起登失,我...
    開(kāi)封第一講書(shū)人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎挖炬,沒(méi)想到半個(gè)月后揽浙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡意敛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年馅巷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片草姻。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡钓猬,死狀恐怖锯岖,靈堂內(nèi)的尸體忽然破棺而出叹坦,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布跌榔,位于F島的核電站,受9級(jí)特大地震影響捶障,放射性物質(zhì)發(fā)生泄漏僧须。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一项炼、第九天 我趴在偏房一處隱蔽的房頂上張望担平。 院中可真熱鬧,春花似錦锭部、人聲如沸暂论。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)取胎。三九已至,卻和暖如春湃窍,著一層夾襖步出監(jiān)牢的瞬間闻蛀,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工您市, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留觉痛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓茵休,卻偏偏與公主長(zhǎng)得像薪棒,于是被迫代替她去往敵國(guó)和親手蝎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355