分布式事務(wù):Saga模式

1 Saga相關(guān)概念

1987年普林斯頓大學(xué)的Hector Garcia-Molina和Kenneth Salem發(fā)表了一篇Paper Sagas愈案,講述的是如何處理long lived transaction(長活事務(wù))。Saga是一個長活事務(wù)可被分解成可以交錯運(yùn)行的子事務(wù)集合顷啼。其中每個子事務(wù)都是一個保持?jǐn)?shù)據(jù)庫一致性的真實(shí)事務(wù)。
論文地址:sagas

1.1 Saga的組成

  • 每個Saga由一系列sub-transaction Ti 組成
  • 每個Ti 都有對應(yīng)的補(bǔ)償動作Ci沐扳,補(bǔ)償動作用于撤銷Ti造成的結(jié)果

可以看到,和TCC相比,Saga沒有“預(yù)留”動作袋毙,它的Ti就是直接提交到庫。

Saga的執(zhí)行順序有兩種:

  • T1, T2, T3, ..., Tn
  • T1, T2, ..., Tj, Cj,..., C2, C1冗尤,其中0 < j < n

Saga定義了兩種恢復(fù)策略:

  • backward recovery听盖,向后恢復(fù),補(bǔ)償所有已完成的事務(wù)裂七,如果任一子事務(wù)失敗皆看。即上面提到的第二種執(zhí)行順序,其中j是發(fā)生錯誤的sub-transaction背零,這種做法的效果是撤銷掉之前所有成功的sub-transation腰吟,使得整個Saga的執(zhí)行結(jié)果撤銷。
  • forward recovery徙瓶,向前恢復(fù)毛雇,重試失敗的事務(wù),假設(shè)每個子事務(wù)最終都會成功侦镇。適用于必須要成功的場景灵疮,執(zhí)行順序是類似于這樣的:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn,其中j是發(fā)生錯誤的sub-transaction壳繁。該情況下不需要Ci震捣。

顯然,向前恢復(fù)沒有必要提供補(bǔ)償事務(wù)闹炉,如果你的業(yè)務(wù)中蒿赢,子事務(wù)(最終)總會成功,或補(bǔ)償事務(wù)難以定義或不可能渣触,向前恢復(fù)更符合你的需求诉植。

理論上補(bǔ)償事務(wù)永不失敗,然而昵观,在分布式世界中晾腔,服務(wù)器可能會宕機(jī),網(wǎng)絡(luò)可能會失敗啊犬,甚至數(shù)據(jù)中心也可能會停電灼擂。在這種情況下我們能做些什么? 最后的手段是提供回退措施觉至,比如人工干預(yù)剔应。

1.2 Saga的使用條件

Saga看起來很有希望滿足我們的需求。所有長活事務(wù)都可以這樣做嗎?這里有一些限制:

  1. Saga只允許兩個層次的嵌套峻贮,頂級的Saga和簡單子事務(wù)
  2. 在外層席怪,全原子性不能得到滿足。也就是說纤控,sagas可能會看到其他sagas的部分結(jié)果
  3. 每個子事務(wù)應(yīng)該是獨(dú)立的原子行為
  4. 在我們的業(yè)務(wù)場景下挂捻,各個業(yè)務(wù)環(huán)境(如:航班預(yù)訂、租車船万、酒店預(yù)訂和付款)是自然獨(dú)立的行為刻撒,而且每個事務(wù)都可以用對應(yīng)服務(wù)的數(shù)據(jù)庫保證原子操作。

補(bǔ)償也有需考慮的事項(xiàng):

  • 補(bǔ)償事務(wù)從語義角度撤消了事務(wù)Ti的行為耿导,但未必能將數(shù)據(jù)庫返回到執(zhí)行Ti時的狀態(tài)声怔。(例如,如果事務(wù)觸發(fā)導(dǎo)彈發(fā)射舱呻, 則可能無法撤消此操作)

但這對我們的業(yè)務(wù)來說不是問題醋火。其實(shí)難以撤消的行為也有可能被補(bǔ)償。例如箱吕,發(fā)送電郵的事務(wù)可以通過發(fā)送解釋問題的另一封電郵來補(bǔ)償芥驳。

對于ACID的保證:

Saga對于ACID的保證和TCC一樣:

  • 原子性(Atomicity):正常情況下保證。
  • 一致性(Consistency)殖氏,在某個時間點(diǎn)晚树,會出現(xiàn)A庫和B庫的數(shù)據(jù)違反一致性要求的情況姻采,但是最終是一致的雅采。
  • 隔離性(Isolation),在某個時間點(diǎn)慨亲,A事務(wù)能夠讀到B事務(wù)部分提交的結(jié)果婚瓜。
  • 持久性(Durability),和本地事務(wù)一樣刑棵,只要commit則數(shù)據(jù)被持久巴刻。

Saga不提供ACID保證,因?yàn)樵有院透綦x性不能得到滿足蛉签。原論文描述如下:

full atomicity is not provided. That is, sagas may view the partial results of other sagas

通過saga log胡陪,saga可以保證一致性和持久性。

和TCC對比

Saga相比TCC的缺點(diǎn)是缺少預(yù)留動作碍舍,導(dǎo)致補(bǔ)償動作的實(shí)現(xiàn)比較麻煩:Ti就是commit柠座,比如一個業(yè)務(wù)是發(fā)送郵件,在TCC模式下片橡,先保存草稿(Try)再發(fā)送(Confirm)妈经,撤銷的話直接刪除草稿(Cancel)就行了。而Saga則就直接發(fā)送郵件了(Ti),如果要撤銷則得再發(fā)送一份郵件說明撤銷(Ci)吹泡,實(shí)現(xiàn)起來有一些麻煩骤星。

如果把上面的發(fā)郵件的例子換成:A服務(wù)在完成Ti后立即發(fā)送Event到ESB(企業(yè)服務(wù)總線,可以認(rèn)為是一個消息中間件)爆哑,下游服務(wù)監(jiān)聽到這個Event做自己的一些工作然后再發(fā)送Event到ESB洞难,如果A服務(wù)執(zhí)行補(bǔ)償動作Ci,那么整個補(bǔ)償動作的層級就很深泪漂。

不過沒有預(yù)留動作也可以認(rèn)為是優(yōu)點(diǎn):

  • 有些業(yè)務(wù)很簡單廊营,套用TCC需要修改原來的業(yè)務(wù)邏輯,而Saga只需要添加一個補(bǔ)償動作就行了萝勤。
  • TCC最少通信次數(shù)為2n露筒,而Saga為n(n=sub-transaction的數(shù)量)。
  • 有些第三方服務(wù)沒有Try接口敌卓,TCC模式實(shí)現(xiàn)起來就比較tricky了慎式,而Saga則很簡單。
  • 沒有預(yù)留動作就意味著不必?fù)?dān)心資源釋放的問題趟径,異常處理起來也更簡單(請對比Saga的恢復(fù)策略和TCC的異常處理)瘪吏。

2 Saga相關(guān)實(shí)現(xiàn)

Saga Log

Saga保證所有的子事務(wù)都得以完成或補(bǔ)償,但Saga系統(tǒng)本身也可能會崩潰蜗巧。Saga崩潰時可能處于以下幾個狀態(tài):

  • Saga收到事務(wù)請求掌眠,但尚未開始。因子事務(wù)對應(yīng)的微服務(wù)狀態(tài)未被Saga修改幕屹,我們什么也不需要做蓝丙。
  • 一些子事務(wù)已經(jīng)完成。重啟后望拖,Saga必須接著上次完成的事務(wù)恢復(fù)渺尘。
  • 子事務(wù)已開始,但尚未完成说敏。由于遠(yuǎn)程服務(wù)可能已完成事務(wù)鸥跟,也可能事務(wù)失敗,甚至服務(wù)請求超時盔沫,saga只能重新發(fā)起之前未確認(rèn)完成的子事務(wù)医咨。這意味著子事務(wù)必須冪等。
  • 子事務(wù)失敗架诞,其補(bǔ)償事務(wù)尚未開始拟淮。Saga必須在重啟后執(zhí)行對應(yīng)補(bǔ)償事務(wù)。
  • 補(bǔ)償事務(wù)已開始但尚未完成侈贷。解決方案與上一個相同惩歉。這意味著補(bǔ)償事務(wù)也必須是冪等的等脂。
  • 所有子事務(wù)或補(bǔ)償事務(wù)均已完成,與第一種情況相同撑蚌。

為了恢復(fù)到上述狀態(tài)上遥,我們必須追蹤子事務(wù)及補(bǔ)償事務(wù)的每一步。我們決定通過事件的方式達(dá)到以上要求争涌,并將以下事件保存在名為saga log的持久存儲中:

  • Saga started event 保存整個saga請求粉楚,其中包括多個事務(wù)/補(bǔ)償請求
  • Transaction started event 保存對應(yīng)事務(wù)請求
  • Transaction ended event 保存對應(yīng)事務(wù)請求及其回復(fù)
  • Transaction aborted event 保存對應(yīng)事務(wù)請求和失敗的原因
  • Transaction compensated event 保存對應(yīng)補(bǔ)償請求及其回復(fù)
  • Saga ended event 標(biāo)志著saga事務(wù)請求的結(jié)束,不需要保存任何內(nèi)容
66ae7b320e502c13f4a21a08baa61ead

通過將這些事件持久化在saga log中亮垫,我們可以將saga恢復(fù)到上述任何狀態(tài)模软。

由于Saga只需要做事件的持久化,而事件內(nèi)容以JSON的形式存儲饮潦,Saga log的實(shí)現(xiàn)非常靈活燃异,數(shù)據(jù)庫(SQL或NoSQL),持久消息隊(duì)列继蜡,甚至普通文件可以用作事件存儲回俐, 當(dāng)然有些能更快得幫saga恢復(fù)狀態(tài)。

注意事項(xiàng)

對于服務(wù)來說稀并,實(shí)現(xiàn)Saga有以下這些要求:

  1. Ti和Ci是冪等的仅颇。
  2. Ci必須是能夠成功的,如果無法成功則需要人工介入碘举。
  3. Ti - Ci和Ci - Ti的執(zhí)行結(jié)果必須是一樣的:sub-transaction被撤銷了忘瓦。

第一點(diǎn)要求Ti和Ci是冪等的,舉個例子引颈,假設(shè)在執(zhí)行Ti的時候超時了耕皮,此時我們是不知道執(zhí)行結(jié)果的,如果采用forward recovery策略就會再次發(fā)送Ti线欲,那么就有可能出現(xiàn)Ti被執(zhí)行了兩次甚疟,所以要求Ti冪等参萄。如果采用backward recovery策略就會發(fā)送Ci,而如果Ci也超時了苗桂,就會嘗試再次發(fā)送Ci逼泣,那么就有可能出現(xiàn)Ci被執(zhí)行兩次趴泌,所以要求Ci冪等。

第二點(diǎn)要求Ci必須能夠成功拉庶,這個很好理解嗜憔,因?yàn)椋绻鸆i不能執(zhí)行成功就意味著整個Saga無法完全撤銷氏仗,這個是不允許的吉捶。但總會出現(xiàn)一些特殊情況比如Ci的代碼有bug、服務(wù)長時間崩潰等,這個時候就需要人工介入了呐舔。

第三點(diǎn)乍看起來比較奇怪币励,舉例說明,還是考慮Ti執(zhí)行超時的場景珊拼,我們采用了backward recovery食呻,發(fā)送一個Ci,那么就會有三種情況:

  1. Ti的請求丟失了澎现,服務(wù)之前沒有仅胞、之后也不會執(zhí)行Ti
  2. Ti在Ci之前執(zhí)行
  3. Ci在Ti之前執(zhí)行

對于第1種情況,容易處理剑辫。對于第2干旧、3種情況,則要求Ti和Ci是可交換的(commutative)妹蔽,并且其最終結(jié)果都是sub-transaction被撤銷莱革。

3 Saga協(xié)調(diào)

協(xié)調(diào)saga:saga的實(shí)現(xiàn)包含協(xié)調(diào)saga步驟的邏輯。當(dāng)系統(tǒng)命令啟動saga時讹开,協(xié)調(diào)邏輯必須選擇并告知第一個saga參與者執(zhí)行本地事務(wù)盅视。一旦該事務(wù)完成,saga的排序協(xié)調(diào)選擇并調(diào)用下一個saga參與者旦万。這個過程一直持續(xù)到saga執(zhí)行了所有步驟闹击。如果任何本地事務(wù)失敗,則saga必須以相反的順序執(zhí)行補(bǔ)償事務(wù)成艘。構(gòu)建一個saga的協(xié)調(diào)邏輯有幾種不同的方法:

  • 編排(Choreography):在saga參與者中分配決策和排序赏半。他們主要通過交換事件進(jìn)行溝通。
  • 控制(Orchestration):在saga控制類中集中saga的協(xié)調(diào)邏輯淆两。一個saga控制者向saga參與者發(fā)送命令消息断箫,告訴他們要執(zhí)行哪些操作。

3.1 編排(Choreography)

基于編排的saga:實(shí)現(xiàn)sagas的一種方法是使用編排秋冰。當(dāng)使用編排時仲义,沒有中央?yún)f(xié)調(diào)員告訴saga參與者該做什么。相反剑勾,sagas參與者訂閱彼此的事件并做出相應(yīng)的響應(yīng)埃撵。

Screen Shot 2018-11-27 at 23.24.17

通過這個sagas的路徑如下:

  1. Order Service在APPROVAL_PENDING狀態(tài)下創(chuàng)建一個Order并發(fā)布OrderCreated事件。
  2. Consumer Service消費(fèi)OrderCreated事件虽另,驗(yàn)證消費(fèi)者是否可以下訂單暂刘,并發(fā)布ConsumerVerified事件。
  3. Kitchen Service消費(fèi)OrderCreated事件捂刺,驗(yàn)證訂單谣拣,在CREATE_PENDING狀態(tài)下創(chuàng)建故障單募寨,并發(fā)布TicketCreated事件。
  4. Accounting服務(wù)消費(fèi)OrderCreated事件并創(chuàng)建一個處于PENDING狀態(tài)的Credit CardAuthorization森缠。
  5. Accounting Service消費(fèi)TicketCreated和ConsumerVerified事件绪商,收取消費(fèi)者的信用卡,并發(fā)布信用卡授權(quán)活動辅鲸。
  6. Kitchen Service使用CreditCardAuthorized事件并更改AWAITING_ACCEPTANCE票的狀態(tài)格郁。
  7. Order Service收到CreditCardAuthorized事件,更改訂單狀態(tài)到APPROVED独悴,并發(fā)布OrderApproved事件例书。

創(chuàng)建訂單saga還必須處理saga參與者拒絕訂單并發(fā)布某種失敗事件的場景。例如刻炒,消費(fèi)者信用卡的授權(quán)可能會失敗决采。saga必須執(zhí)行補(bǔ)償交易以撤消已經(jīng)完成的事情。圖中顯示了AccountingService無法授權(quán)消費(fèi)者信用卡時的事件流坟奥。

Screen Shot 2018-11-27 at 23.54.12

事件順序如下:

  1. Order服務(wù)在APPROVAL_PENDING狀態(tài)下創(chuàng)建一個Order并發(fā)布OrderCreated事件树瞭。
  2. Consumer服務(wù)消費(fèi)OrderCreated事件,驗(yàn)證消費(fèi)者是否可以下訂單爱谁,并發(fā)布ConsumerVerified事件晒喷。
  3. Kitchen服務(wù)消費(fèi)OrderCreated事件,驗(yàn)證訂單访敌,在CREATE_PENDING狀態(tài)下創(chuàng)建故障單凉敲,并發(fā)布TicketCreated事件。
  4. Accounting服務(wù)消費(fèi)OrderCreated事件并創(chuàng)建一個處于PENDING狀態(tài)的Credit CardAuthorization寺旺。
  5. Accounting服務(wù)消費(fèi)TicketCreated和ConsumerVerified事件爷抓,向消費(fèi)者的信用卡收費(fèi),并發(fā)布信用卡授權(quán)失敗事件阻塑。
  6. Kitchen服務(wù)使用信用卡授權(quán)失敗事件并將故障單的狀態(tài)更改為REJECTED蓝撇。
  7. 訂單服務(wù)消費(fèi)信用卡授權(quán)失敗事件,并將訂單狀態(tài)更改為已拒絕陈莽。

可靠的基于事件的通信

在實(shí)施基于編排的saga時渤昌,您必須考慮一些與服務(wù)間通信相關(guān)的問題。第一個問題是確保saga參與者更新其數(shù)據(jù)庫并將事件作為數(shù)據(jù)庫事務(wù)的一部分發(fā)布传透。
您需要考慮的第二個問題是確保saga參與者必須能夠?qū)⑹盏降拿總€事件映射到自己的數(shù)據(jù)耘沼。

編組的saga的好處和缺點(diǎn)

基于編舞的saga有幾個好處

  • 簡單:服務(wù)在創(chuàng)建极颓,更新或刪除業(yè)務(wù)時發(fā)布事件對象
  • 松耦合:參與者訂閱事件并且彼此之間沒有直接的了解朱盐。

并且有一些缺點(diǎn)

  • 更難理解:與業(yè)務(wù)流程不同,代碼中沒有一個地方可以定義saga菠隆。相反兵琳,編排在服務(wù)中分配saga的實(shí)現(xiàn)狂秘。因此,開發(fā)人員有時很難理解給定的saga是如何工作的躯肌。
  • 服務(wù)之間的循環(huán)依賴關(guān)系:saga參與者訂閱彼此的事件者春,這通常會創(chuàng)建循環(huán)依賴關(guān)系。例如清女,如果仔細(xì)檢查圖示钱烟,您將看到存在循環(huán)依賴關(guān)系,例如訂單服務(wù)嫡丙、會計(jì)服務(wù)拴袭、訂單服務(wù)。雖然這不一定是個問題曙博,但循環(huán)依賴性被認(rèn)為是設(shè)計(jì)問題拥刻。
  • 緊密耦合的風(fēng)險(xiǎn):每個saga參與者都需要訂閱所有影響他們的事件。例如父泳,會計(jì)服務(wù)必須訂閱導(dǎo)致消費(fèi)者信用卡被收費(fèi)或退款的所有事件般哼。因此,存在一種風(fēng)險(xiǎn)惠窄,即需要與Order Service實(shí)施的訂單生命周期保持同步更新蒸眠。

3.2 控制(Orchestration)

控制是實(shí)現(xiàn)sagas的另一種方式。使用業(yè)務(wù)流程時杆融,您可以定義一個控制類黔宛,其唯一的職責(zé)是告訴saga參與者該做什么。 saga控制使用命令/異步回復(fù)樣式交互與參與者進(jìn)行通信擒贸。

Screen Shot 2018-11-28 at 00.08.51
  1. Order Service首先創(chuàng)建一個Order和一個創(chuàng)建訂單控制器臀晃。之后,路徑的流程如下:
  2. saga orchestrator向Consumer Service發(fā)送Verify Consumer命令介劫。
  3. Consumer Service回復(fù)Consumer Verified消息徽惋。
  4. saga orchestrator向Kitchen Service發(fā)送Create Ticket命令。
  5. Kitchen Service回復(fù)Ticket Created消息座韵。
  6. saga協(xié)調(diào)器向Accounting Service發(fā)送授權(quán)卡消息险绘。
  7. Accounting服務(wù)部門使用卡片授權(quán)消息回復(fù)。
  8. saga orchestrator向Kitchen Service發(fā)送Approve Ticket命令誉碴。
  9. saga orchestrator向訂單服務(wù)發(fā)送批準(zhǔn)訂單命令宦棺。

使用狀態(tài)機(jī)建模SAGA ORCHESTRATORS

建模saga orchestrator的好方法是作為狀態(tài)機(jī)。狀態(tài)機(jī)由一組狀態(tài)和一組由事件觸發(fā)的狀態(tài)之間的轉(zhuǎn)換組成黔帕。每個transition都可以有一個action代咸,對于一個saga來說是一個saga參與者的調(diào)用。狀態(tài)之間的轉(zhuǎn)換由saga參與者執(zhí)行的本地事務(wù)的完成觸發(fā)成黄。當(dāng)前狀態(tài)和本地事務(wù)的特定結(jié)果決定了狀態(tài)轉(zhuǎn)換以及執(zhí)行的操作(如果有的話)呐芥。對狀態(tài)機(jī)也有有效的測試策略逻杖。因此,使用狀態(tài)機(jī)模型可以更輕松地設(shè)計(jì)思瘟、實(shí)施和測試荸百。

Screen Shot 2018-11-28 at 00.12.58

圖顯示了Create Order Saga的狀態(tài)機(jī)模型。此狀態(tài)機(jī)由多個狀態(tài)組成滨攻,包括以下內(nèi)容:

  • Verifying Consumer:初始狀態(tài)够话。當(dāng)處于此狀態(tài)時,該saga正在等待消費(fèi)者服務(wù)部門驗(yàn)證消費(fèi)者是否可以下訂單光绕。
  • Creating Ticket:該saga正在等待對創(chuàng)建票證命令的回復(fù)更鲁。
  • Authorizing Card:等待Accounting服務(wù)授權(quán)消費(fèi)者的信用卡。
  • OrderApproved:表示saga成功完成的最終狀態(tài)奇钞。
  • Order Rejected:最終狀態(tài)表明該訂單被其中一方參與者們拒絕澡为。

SAGA ORCHESTRATION和TRANSACTIONAL MESSAGING

基于業(yè)務(wù)流程的saga的每個步驟都包括更新數(shù)據(jù)庫和發(fā)布消息的服務(wù)。例如景埃,Order Service持久保存Order和Create Order Saga orchestrator媒至,并向第一個saga參與者發(fā)送消息。一個saga參與者谷徙,例如Kitchen Service拒啰,通過更新其數(shù)據(jù)庫并發(fā)送回復(fù)消息來處理命令消息。 Order Service通過更新saga協(xié)調(diào)器的狀態(tài)并向下一個saga參與者發(fā)送命令消息來處理參與者的回復(fù)消息完慧。服務(wù)必須使用事務(wù)性消息傳遞谋旦,以便自動更新數(shù)據(jù)庫并發(fā)布消息。

讓我們來看看使用saga編排的好處和缺點(diǎn)屈尼。

基于ORCHESTRATION的SAGAS的好處和缺點(diǎn)

基于編排的saga有幾個好處:

  1. 更簡單的依賴關(guān)系:編排的一個好處是它不會引入循環(huán)依賴關(guān)系册着。 saga orchestrator調(diào)用saga參與者,但參與者不會調(diào)用orchestrator脾歧。因此甲捏,協(xié)調(diào)器依賴于參與者,但反之亦然鞭执,因此沒有循環(huán)依賴性司顿。
  2. 較少的耦合:每個服務(wù)都實(shí)現(xiàn)了由orchestrator調(diào)用的API,因此它不需要知道saga參與者發(fā)布的事件兄纺。
  3. 改善關(guān)注點(diǎn)分離并簡化業(yè)務(wù)邏輯:saga協(xié)調(diào)邏輯本地化在saga協(xié)調(diào)器中大溜。域?qū)ο蟾唵危⑶也涣私馑鼈儏⑴c的saga估脆。例如钦奋,當(dāng)使用編排時,Order類不知道任何saga,因此它具有更簡單的狀態(tài)機(jī)模型锨苏。在執(zhí)行創(chuàng)建訂單saga期間疙教,它直接從APPROVAL_PENDING狀態(tài)轉(zhuǎn)換到APPROVED狀態(tài)棺聊。 Order類沒有與saga的步驟相對應(yīng)的任何中間狀態(tài)伞租。因此,業(yè)務(wù)更加簡單限佩。

業(yè)務(wù)流程也有一個缺點(diǎn)

  • 在協(xié)調(diào)器中集中過多業(yè)務(wù)邏輯的風(fēng)險(xiǎn)葵诈。這導(dǎo)致了一種設(shè)計(jì),其中智能協(xié)調(diào)器告訴啞巴服務(wù)要做什么操作祟同。幸運(yùn)的是作喘,您可以通過設(shè)計(jì)獨(dú)立負(fù)責(zé)排序的協(xié)調(diào)器來避免此問題,并且不包含任何其他業(yè)務(wù)邏輯晕城。

除了最簡單的saga泞坦,我建議使用編排。為您的saga實(shí)施協(xié)調(diào)邏輯只是您需要解決的設(shè)計(jì)問題之一砖顷。

4 參考示例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末贰锁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子滤蝠,更是在濱河造成了極大的恐慌豌熄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件物咳,死亡現(xiàn)場離奇詭異锣险,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)览闰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門芯肤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人压鉴,你說我怎么就攤上這事纷妆。” “怎么了晴弃?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵掩幢,是天一觀的道長。 經(jīng)常有香客問我上鞠,道長际邻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任芍阎,我火速辦了婚禮世曾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谴咸。我一直安慰自己轮听,他們只是感情好骗露,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著血巍,像睡著了一般萧锉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上述寡,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天,我揣著相機(jī)與錄音鲫凶,去河邊找鬼禀崖。 笑死,一個胖子當(dāng)著我的面吹牛螟炫,可吹牛的內(nèi)容都是我干的波附。 我是一名探鬼主播昼钻,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼换吧!你這毒婦竟也來了沾瓦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤贯莺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魂莫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耙考,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了鞋邑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逾一。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡肮雨,死狀恐怖酷含,靈堂內(nèi)的尸體忽然破棺而出鄙早,到底是詐尸還是另有隱情,我是刑警寧澤舱污,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站媚赖,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏珠插。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一磨隘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧江解,春花似錦、人聲如沸鳖枕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至读处,卻和暖如春糊治,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背管闷。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工包个, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人糯而。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓像寒,卻偏偏與公主長得像序臂,于是被迫代替她去往敵國和親咸灿。 傳聞我的和親對象是個殘疾皇子囊榜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

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