微服務(wù)架構(gòu)設(shè)計模式 | 第5章 微服務(wù)架構(gòu)中的業(yè)務(wù)邏輯設(shè)計

前言

這是一本關(guān)于微服務(wù)架構(gòu)設(shè)計方面的書携栋,這是本人閱讀的學(xué)習(xí)筆記。首先對一些符號做些說明:

()為補(bǔ)充挖垛,一般是書本里的內(nèi)容痒钝;
[]符號為筆者筆注;


1. 業(yè)務(wù)邏輯組織模式

組織業(yè)務(wù)邏輯有兩種主要的模式:面向過程的事務(wù)腳本模式和面向?qū)ο蟮念I(lǐng)域建模模式痢毒。

1.1 一個典型的服務(wù)架構(gòu)

業(yè)務(wù)邏輯周圍是入站和出站適配器送矩。

  • 入站適配器:處理來自客戶端的請求并調(diào)用業(yè)務(wù)邏輯;
  • 出站適配器:被業(yè)務(wù)邏輯調(diào)用闸准,然后它們再調(diào)用其他服務(wù)和外部程序應(yīng)用益愈;

Order Service具有六邊形架構(gòu)

Order Service具有六邊形架構(gòu)

此服務(wù)由業(yè)務(wù)邏輯和以下適配器組成:

  • REST API adapter:入站適配器,實現(xiàn)REST API夷家,這些API會調(diào)用業(yè)務(wù)邏輯蒸其;
  • OrderCommandHandlers:入站適配器,它接受來自消息代理的出站適配器库快,并調(diào)用業(yè)務(wù)邏輯摸袁;
  • Database Adapter:由業(yè)務(wù)邏輯調(diào)用以訪問數(shù)據(jù)庫的出站適配器;
  • Domain Event Publishing Adapter:將事件發(fā)布到消息代理的出站適配器义屏;

1.2 使用事務(wù)腳本模式設(shè)計業(yè)務(wù)邏輯

事務(wù)腳本:將業(yè)務(wù)邏輯組織為面向過程的事務(wù)腳本的集合靠汁,每種類型的請求都有一個腳本。

使用事務(wù)腳本模式設(shè)計業(yè)務(wù)邏輯

特點(diǎn)

  • 實現(xiàn)行為的類與存儲狀態(tài)的類是分開的闽铐;
  • 腳本通常在服務(wù)類中蝶怔;
  • 每個服務(wù)都有一個用于請求或系統(tǒng)操作的方法;這個方法實現(xiàn)請求的業(yè)務(wù)邏輯兄墅;

1.3 使用領(lǐng)域模型模式設(shè)計業(yè)務(wù)邏輯

領(lǐng)域模型:將業(yè)務(wù)邏輯組織為由具有狀態(tài)和行為的類構(gòu)成的對象模型踢星。

使用領(lǐng)域模型模式設(shè)計業(yè)務(wù)邏輯

特點(diǎn)

  • 服務(wù)方法通常很簡單(因為服務(wù)方法幾乎總是調(diào)用持久化領(lǐng)域?qū)ο螅@些對象中包含大量業(yè)務(wù)邏輯)隙咸;
    • 如:Order類具有狀態(tài)和方法沐悦,狀態(tài)是私有的成洗,只能通過它的方法間接訪問;
  • 易于理解藏否、維護(hù)瓶殃、測試和擴(kuò)展;

1.4 關(guān)于領(lǐng)域驅(qū)動設(shè)計

領(lǐng)域驅(qū)動設(shè)計(DDD)是對面向?qū)ο笤O(shè)計的改進(jìn)副签,是開發(fā)復(fù)雜業(yè)務(wù)邏輯的一種方法遥椿。其基本元素如下:

  • 實體(entity):具有持久化ID的對象。具有相同屬性值的兩個實體仍然是不同的對象继薛;
  • 值對象(value object):作為值集合的對象修壕。具有相同屬性值的兩個值對象可以互換使用愈捅;
  • 工廠(factory):負(fù)責(zé)實現(xiàn)對象創(chuàng)建邏輯的對象或方法遏考,該邏輯過于復(fù)雜,無法由類的構(gòu)造函數(shù)直接完成蓝谨。它還可以隱藏被實例化的具體類灌具。工廠方法一般可實現(xiàn)為類的靜態(tài)方法;
  • 存儲庫(repository):用來訪問持久化實體的對象譬巫,儲存庫也封裝了訪問數(shù)據(jù)庫的底層機(jī)制咖楣;
  • 服務(wù)(service):實現(xiàn)不屬于實體或值對象的業(yè)務(wù)邏輯對象;


2. 使用聚合模式設(shè)計領(lǐng)域模型

傳統(tǒng)領(lǐng)域模型缺少每個業(yè)務(wù)對象的明確邊界芦昔,DDD聚合旨在解決此問題诱贿。

2.1 聚合擁有明確的邊界

聚合模式:將領(lǐng)域模型組織為聚合的集合,每個聚合都是可以作為一個單元進(jìn)行處理的一組對象構(gòu)成的圖咕缎。

Order 聚合及其邊界

Order 聚合及其邊界
  • 聚合代表了一致的邊界珠十;
    • 更新整個聚合可以解決一致性問題;
  • 識別聚合是關(guān)鍵凭豪;
    • 在驅(qū)動領(lǐng)域設(shè)計中焙蹭,設(shè)計領(lǐng)域模型的關(guān)鍵部分是識別聚合,以及它們的邊界和根嫂伞;

2.2 聚合規(guī)則

聚合規(guī)則可以確保聚合是一個可以強(qiáng)制執(zhí)行各種不變量約束的自包含單元孔厉。

  • 規(guī)則一:只引用聚合根
    • 聚合根是聚合中唯一可以由外部類引用的部分帖努;客戶端只能通過調(diào)用聚合根上的方法來更新聚合撰豺;
    • 如:服務(wù)使用儲存庫從數(shù)據(jù)庫加載聚合并獲取聚合根的引用;
  • 規(guī)則二:聚合間的引用必須使用主鍵拼余;
    • 如:Order使用consumerId引用其Consumer而不是直接引用Consumer對象污桦;
  • 規(guī)則三:在一個事務(wù)中,只能創(chuàng)建或更新一個聚合姿搜;
    • 這個約束可以確保單個事務(wù)的范圍不超越服務(wù)的邊界寡润;還滿足大多數(shù)NoSQL數(shù)據(jù)庫的受限事務(wù)模型捆憎;
    • 這個規(guī)則讓創(chuàng)建或更新多個聚合的操作變得更加復(fù)雜,但可以通過Saga解決梭纹;
事務(wù)只能創(chuàng)建或更新單個聚合


2.3 聚合的顆粒度

  • 由于每個聚合的更新都是序列化的躲惰,因此更細(xì)顆粒度的聚合間提高應(yīng)用程序能同時處理的請求數(shù)量,從而提高可擴(kuò)展性变抽;
  • 另一方面础拨,因為聚合是事務(wù)的范圍,所以可能需要定義更大的聚合以使特定的聚合更新操作滿足事務(wù)的原子性绍载;
  • 因此诡宗,在開發(fā)領(lǐng)域模型時,必須做出的關(guān)鍵決策是決定每個聚合的大谢骼堋塔沃;

2.4 使用聚合設(shè)計業(yè)務(wù)

  • 在典型的微服務(wù)中,大部分業(yè)務(wù)邏輯由聚合組成阳谍;其余業(yè)務(wù)邏輯存在與領(lǐng)域服務(wù)和Saga中蛀柴;
  • Saga編排本地事務(wù)的序列,以確保數(shù)據(jù)的一致性矫夯;
  • 服務(wù)是業(yè)務(wù)邏輯的入口鸽疾,由入站適配器調(diào)用;
  • 服務(wù)使用存儲庫從數(shù)據(jù)庫中檢索聚合或?qū)⒕酆媳4娴綌?shù)據(jù)庫训貌;
  • 每個存儲庫都由訪問數(shù)據(jù)庫的出站適配器實現(xiàn)制肮;

2.5 Order Service基于聚合設(shè)計的業(yè)務(wù)邏輯

Order Service基于聚合設(shè)計的業(yè)務(wù)邏輯
  • 業(yè)務(wù)邏輯由Order聚合、OrderService服務(wù)類递沪、OrderRepository和一個或多個Saga組成豺鼻;
  • OrderService調(diào)用OrderRepository來保存和加載Order;
  • 對于能在服務(wù)內(nèi)部完成處理的簡單請求区拳,服務(wù)直接更新Order聚合拘领;
  • 如果更新請求跨越多個服務(wù),OrderService將創(chuàng)建一個Saga樱调;


3. 發(fā)布領(lǐng)域事件

領(lǐng)域事件:聚合在被創(chuàng)建時约素,或發(fā)生其他重大更改時發(fā)布領(lǐng)域事件。

3.1 領(lǐng)域事件的應(yīng)用場景

  • 使用基于編排的Saga維護(hù)服務(wù)之間的數(shù)據(jù)一致性【第四章】笆凌;
  • 通知維護(hù)數(shù)據(jù)副本的服務(wù)圣猎,源數(shù)據(jù)已經(jīng)發(fā)生了更改;這種方法稱為命令查詢職責(zé)隔離(CQRS)【第七章】乞而;
  • 通過Webhook或消息代理通知不同的應(yīng)用程序送悔,以觸發(fā)下一個業(yè)務(wù)流程;
  • 按順序通知同一應(yīng)用程序的不同組件;
  • 向用戶發(fā)送短信或電子郵件通知欠啤,告訴他們訂單發(fā)貨荚藻、航班延誤等消息;
  • 監(jiān)控領(lǐng)域事件以驗證應(yīng)用程序是否正常運(yùn)行洁段;
  • 分析領(lǐng)域事件应狱,為用戶行為建模;

3.2 領(lǐng)域事件的特點(diǎn)

  • 命名領(lǐng)域事件時祠丝,往往選擇動詞的過去分詞疾呻;
  • 領(lǐng)域事件的每個屬性都是原始值或值對象;
    • 如:OrderCreated事件類具有orderId屬性写半;
  • 領(lǐng)域事件通常具有元數(shù)據(jù)岸蜗,如事件ID和時間戳;
  • 元數(shù)據(jù)可以是事件對象的一部分叠蝇,可能在超類中定義璃岳;

OrderCreated事件是領(lǐng)域事件的一個例子

image
  • DomainEvent接口是一個標(biāo)識接口,用于將類標(biāo)識為領(lǐng)域事件蟆肆;
  • OrderDomainEvent是Order聚合發(fā)布的事件的標(biāo)識接口(如OrderCreated)矾睦;
  • DomainEventEnvelope是一個包含事件元數(shù)據(jù)和事件對象的類;

3.3 事件增強(qiáng)

當(dāng)OrderCreated的事件接收方需要訂單的詳細(xì)信息時炎功,一種辦法是從Order Service中檢索該信息,讓事件接收方查詢聚合服務(wù)缓溅,缺點(diǎn)是會產(chǎn)生服務(wù)請求的開銷蛇损;

另一種方案是事件增強(qiáng):

  • 事件包含接收方需要的信息
  • 缺點(diǎn):可能會使領(lǐng)域事件的穩(wěn)定性降低坛怪;每當(dāng)接收方的需求發(fā)生改變時淤齐,事件類都可能需要更改;可能會降低可維護(hù)性袜匿;
在這里插入圖片描述

3.4 識別領(lǐng)域事件

可以使用事件風(fēng)暴方法更啄,其結(jié)果是一個以事件為中心的領(lǐng)域模型,它由聚合和事件組成居灯;包括以下三個步驟:

  1. 頭腦風(fēng)暴:請求領(lǐng)域?qū)<壹w討論領(lǐng)域事件祭务;
  2. 識別事件觸發(fā)器:請求領(lǐng)域?qū)<掖_定每個事件的觸發(fā)器(如:用戶操作、外部系統(tǒng)怪嫌、另一個領(lǐng)域事件义锥、時間的流逝等);
  3. 識別聚合:請求領(lǐng)域?qū)<易R別那些使用命令的聚合并發(fā)出相應(yīng)的事件岩灭;

3.5 生成領(lǐng)域事件

在聚合和調(diào)用它的服務(wù)(或類)之間分配職責(zé)拌倍。

  • 服務(wù)可以使用依賴注入來獲取對消息傳遞API的引用,從而輕松發(fā)布事件;
  • 只要狀態(tài)發(fā)生變化柱恤,聚合就會生成事件并將它們返回給服務(wù)数初;
  • 聚合可以通過以下方法將事件返回給服務(wù):

在聚合方法的返回值中包括一個事件列表

image

該服務(wù)調(diào)用聚合根方法,然后發(fā)布事件梗顺;
image


聚合根在一個內(nèi)部字段中累積保存事件:然后服務(wù)檢索這些事件并發(fā)布它們妙真;

image

3.6 發(fā)布領(lǐng)域事件

服務(wù)必須使用事務(wù)性消息來發(fā)布事件,以確保領(lǐng)域事件是作為更新數(shù)據(jù)庫中聚合的事務(wù)的一部分對外發(fā)布荚守;

Eventuate Tram框架提供DomainEventPublisher接口

[圖片上傳失敗...(image-235173-1629292536189)]
讓服務(wù)實現(xiàn)AbstractAggregateDomainEventPublisher的子類:它為發(fā)布領(lǐng)域事件提供了類型安全的接口珍德;

AbstractAggregateDomainEventPublishe接口

[圖片上傳失敗...(image-973fa8-1629292536189)]
[圖片上傳失敗...(image-2af956-1629292536189)]

3.7 消費(fèi)領(lǐng)域事件

領(lǐng)域事件是接收方使用更高級的API,如:Eventuate Tram框架的DomainEventDispatcher等矗漾。其可以將領(lǐng)域事件調(diào)度到適當(dāng)?shù)奶幚沓绦蚍椒ā?/p>

image
  • 每當(dāng)餐館的菜單更新時锈候,KitchenServiceEventConsumer都會訂閱Restaurant Service發(fā)布事件;
  • 它負(fù)責(zé)使Kitchen Service的數(shù)據(jù)副本保持最新敞贡;


4. Kichen Service的業(yè)務(wù)邏輯

該服務(wù)的主要功能是負(fù)責(zé)實現(xiàn)餐館的訂單管理功能泵琳。其兩個主要聚合是Restaurant和Ticket;

4.1 Kichen Service的設(shè)計

Kitchen Service的設(shè)計
  • 兩個聚合:
    • Restaurant:知道餐館的菜單和營業(yè)事件誊役,并可以驗證訂單获列;
    • Ticket:工單烹飪完成后由送餐員負(fù)責(zé)派送;
  • 核心業(yè)務(wù):
    • KitchenService:業(yè)務(wù)入口蛔垢,定義了創(chuàng)建和更新Restaurant及Ticket聚合的方法击孩;
    • TicketRepository:定義了持久化Tickets的方法;
    • RestaurantRepository:定義了持久化Restaurants的方法鹏漆;
  • 三個入站適配器:
    • REST API:餐館工作人員通過他們的用戶界面調(diào)用這些REST API巩梢;
    • KitchenServiceCommandHandler:由Saga調(diào)用的基于異步請求 / 響應(yīng)的API;它調(diào)用KitchenService來創(chuàng)建和更新Ticket艺玲;
    • KitchenServiceEventConsumer:訂閱Restaurant Service發(fā)布的事件括蝠;它調(diào)用KitchenService來創(chuàng)建和更新Restaurant聚合;
  • 兩個出站適配器:
    • DB Adapter:實現(xiàn)TicketRepository和RestaurantRepository接口并訪問數(shù)據(jù)庫饭聚;
    • DomainEventPublishingAdapter:實現(xiàn)DomainEventPublisher接口并發(fā)布Ticket領(lǐng)域事件忌警;

4.2 Ticket類的結(jié)構(gòu)

該類使用JPA進(jìn)行持久化,并映射到TICKETS表秒梳。

image

Ticket類的結(jié)構(gòu)

4.3 Ticket聚合的行為

image

Ticket的一些方法
  • create():創(chuàng)建Ticket的工廠方法法绵;
  • accept():餐館已接收訂單;
  • preparing():餐館已開始準(zhǔn)備訂單端幼,意味著訂單無法再更改或取消礼烈;
  • readyForPickup():訂單可以派送;

4.4 KitchenService的領(lǐng)域服務(wù)

KitchenService由服務(wù)入站適配器調(diào)用婆跑;定義了用于更改訂單狀態(tài)的各種方法(如accept()此熬、reject()、preparing()等);每個方法加載指定的聚合犀忱,在聚合根上調(diào)用相應(yīng)的方法募谎,并發(fā)布領(lǐng)域事件;如下accept()方法所示:

accept()方法更新Ticket

accept()方法的兩個參數(shù)

  • orderId:要接受訂單的ID阴汇;
  • readyBy:訂單可被派送的預(yù)計時間数冬;

4.5 KitchenServiceCommandHandler類

KitchenServiceCommandHandler類是一個適配器,負(fù)責(zé)處理Order Service實現(xiàn)的各種Saga發(fā)送的命令式消息搀庶;

image
KitchenServiceCommandHandler類


5. Order Service的業(yè)務(wù)邏輯

5.1 Order Service的設(shè)計

Order Service的設(shè)計
  • 幾個入站適配器:
    • REST API:供消費(fèi)者利用用戶界面調(diào)用的REST API拐纱;它調(diào)用OrderService來創(chuàng)建和更新Order;
    • OrderEventConsumer:訂閱Restaurant Service發(fā)布的活動哥倔;它調(diào)用OrderService來創(chuàng)建和更新其Restaurant副本秸架;
    • OrderCommandHandlers:由Saga調(diào)用的基于異步請求 / 相應(yīng)的API;它調(diào)用OrderService來更新Order咆蒿;
    • SagaReplyAdapter:訂閱Saga回復(fù)通道并調(diào)用Saga东抹;
  • 一些出站適配器:
    • DB Adapter:實現(xiàn)OrderRepository接口并訪問Order Service的數(shù)據(jù)庫;
    • DomainEventPublishingAdapter:實現(xiàn)DomainEventPublisher接口并發(fā)布Order領(lǐng)域事件沃测;
    • OutboundCommandMessageAdapter:實現(xiàn)CommandPublisher接口并向Saga參與方發(fā)送命令式消息缭黔;

5.2 Order聚合的結(jié)構(gòu)

Order類是Order聚合的根;Order聚合還包括了值對象蒂破,如:OrderLineItem馏谨、DeliveryInfo和PaymentInfo。

Order聚合的設(shè)計

Order類和它的字段

此類使用JPA持久化寞蚌,并映射到ORDERS表田巴。

image

Order類和它的字段

5.3 Order聚合狀態(tài)機(jī)

為了創(chuàng)建或更新訂單,Order Service必須使用Saga與其他服務(wù)協(xié)作挟秤。

Order聚合狀態(tài)機(jī)

創(chuàng)建Order過程中調(diào)用的Order方法
image

創(chuàng)建Order過程中調(diào)用的方法

更新Order需要調(diào)用的方法

image

更新Order需要調(diào)用的方法

5.4 OrderService類

該類定義了用于創(chuàng)建和更新Orders的方法。

image
OrderService類


6. 微服務(wù)與單體應(yīng)用程序的業(yè)務(wù)邏輯異同點(diǎn)

  • 相同點(diǎn)
    • 由諸如服務(wù)抄伍、JPA支持的實體類和存儲庫等這樣的類組成艘刚;
  • 不同點(diǎn)
    • 領(lǐng)域模型被組織為一組DDD聚合,在其上可以施加各種約束截珍;
    • 與傳統(tǒng)的對象模型不同攀甚,不同聚合中的類之間的引用是基于主鍵而不是對象引用;
    • 事務(wù)只能創(chuàng)建或更新單個聚合岗喉;聚合在狀態(tài)發(fā)生變化時會發(fā)布領(lǐng)域事件秋度;
    • 服務(wù)通常使用Saga來維護(hù)多個服務(wù)之間的數(shù)據(jù)一致性;


7. 本章小結(jié)

  • 事務(wù)腳本模式通常是實現(xiàn)簡單業(yè)務(wù)的好辦法钱床。但在實現(xiàn)復(fù)雜的業(yè)務(wù)邏輯時荚斯,應(yīng)該考慮使用面向?qū)ο蟮念I(lǐng)域模型模式;
  • 設(shè)計服務(wù)的業(yè)務(wù)邏輯的好辦法是使用DDD聚合。DDD聚合很有用事期,因為它們把領(lǐng)域模型模塊化滥壕,消除了服務(wù)之間對象的直接引用,并確保每個ACID事務(wù)都在服務(wù)內(nèi)兽泣;
  • 創(chuàng)建或更新聚合時應(yīng)發(fā)布領(lǐng)域事件绎橘。領(lǐng)域事件具有廣泛的用途。第4章討論了如何實現(xiàn)協(xié)同式Saga唠倦。第7章中將討論如何使用領(lǐng)域事件來更新從其他服務(wù)復(fù)制來的數(shù)據(jù)称鳞。領(lǐng)域事件的訂閱者還可以通知用戶和其他應(yīng)用程序,并將WebSocket消息發(fā)布到用戶的瀏覽器稠鼻。

最后

\color{blue}{\rm\small{新人制作冈止,如有錯誤,歡迎指出枷餐,感激不盡靶瘸!}}

\color{blue}{\rm\small{歡迎關(guān)注我,并與我交流毛肋!}}

\color{blue}{\rm\small{如需轉(zhuǎn)載怨咪,請標(biāo)注出處!}}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末润匙,一起剝皮案震驚了整個濱河市诗眨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌孕讳,老刑警劉巖匠楚,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異厂财,居然都是意外死亡芋簿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進(jìn)店門璃饱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來与斤,“玉大人,你說我怎么就攤上這事荚恶×么” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵谒撼,是天一觀的道長食寡。 經(jīng)常有香客問我,道長廓潜,這世上最難降的妖魔是什么抵皱? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任善榛,我火速辦了婚禮,結(jié)果婚禮上叨叙,老公的妹妹穿的比我還像新娘锭弊。我一直安慰自己,他們只是感情好擂错,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布味滞。 她就那樣靜靜地躺著,像睡著了一般钮呀。 火紅的嫁衣襯著肌膚如雪剑鞍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天爽醋,我揣著相機(jī)與錄音蚁署,去河邊找鬼。 笑死蚂四,一個胖子當(dāng)著我的面吹牛光戈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播遂赠,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼久妆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了跷睦?” 一聲冷哼從身側(cè)響起筷弦,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抑诸,沒想到半個月后烂琴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜕乡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年奸绷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片层玲。...
    茶點(diǎn)故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡健盒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出称簿,到底是詐尸還是另有隱情,我是刑警寧澤惰帽,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布憨降,位于F島的核電站,受9級特大地震影響该酗,放射性物質(zhì)發(fā)生泄漏授药。R本人自食惡果不足惜士嚎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望悔叽。 院中可真熱鬧莱衩,春花似錦、人聲如沸娇澎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽趟庄。三九已至括细,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間戚啥,已是汗流浹背奋单。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猫十,地道東北人览濒。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像拖云,于是被迫代替她去往敵國和親贷笛。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評論 2 355

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