再不懂ZooKeeper,就安安心心把這篇文章看完

點關(guān)注,不迷路;持續(xù)更新Java架構(gòu)相關(guān)技術(shù)及資訊熱文!!!

我本人曾經(jīng)使用過 ZooKeeper 作為 Dubbo 的注冊中心,另外在搭建 Solr 集群的時候,我使用到了 ZooKeeper 作為 Solr 集群的管理工具。

前幾天,總結(jié)項目經(jīng)驗的時候,我突然問自己 ZooKeeper 到底是個什么東西?

想了半天,腦海中只是簡單的能浮現(xiàn)出幾句話:

  • Zookeeper 可以被用作注冊中心
  • Zookeeper 是 Hadoop 生態(tài)系統(tǒng)的一員
  • 構(gòu)建 Zookeeper 集群的時候,使用的服務(wù)器最好是奇數(shù)臺

可見,我對于 Zookeeper 的理解僅僅是停留在了表面。所以,通過本文,希望帶大家稍微詳細(xì)的了解一下 ZooKeeper 。

如果沒有學(xué)過 ZooKeeper,那么本文將會是你進入 ZooKeeper 大門的墊腳磚;如果你已經(jīng)接觸過 ZooKeeper ,那么本文將帶你回顧一下 ZooKeeper 的一些基礎(chǔ)概念。

最后,本文只涉及 ZooKeeper 的一些概念,并不涉及 ZooKeeper 的使用以及 ZooKeeper 集群的搭建。

網(wǎng)上有介紹 ZooKeeper 的使用以及搭建 ZooKeeper 集群的文章,大家有需要可以自行查閱。

一、什么是 ZooKeeper

Ⅰ.ZooKeeper 的由來

下面這段內(nèi)容摘自《從 Paxos 到 ZooKeeper 》第四章第一節(jié)的某段內(nèi)容,推薦大家閱讀一下:

Zookeeper 最早起源于雅虎研究院的一個研究小組。在當(dāng)時,研究人員發(fā)現(xiàn),在雅虎內(nèi)部很多大型系統(tǒng)基本都需要依賴一個類似的系統(tǒng)來進行分布式協(xié)調(diào),但是這些系統(tǒng)往往都存在分布式單點問題。

所以,雅虎的開發(fā)人員就試圖開發(fā)一個通用的無單點問題的分布式協(xié)調(diào)框架,以便讓開發(fā)人員將精力集中在處理業(yè)務(wù)邏輯上。

關(guān)于“ZooKeeper”這個項目的名字,其實也有一段趣聞。在立項初期,考慮到之前內(nèi)部很多項目都是使用動物的名字來命名的(例如著名的Pig項目),雅虎的工程師希望給這個項目也取一個動物的名字。

時任研究院的首席科學(xué)家 Raghu Ramakrishnan 開玩笑地說:“在這樣下去,我們這兒就變成動物園了!”

此話一出,大家紛紛表示就叫動物園管理員吧,因為各個以動物命名的分布式組件放在一起,雅虎的整個分布式系統(tǒng)看上去就像一個大型的動物園了。

而 Zookeeper 正好要用來進行分布式環(huán)境的協(xié)調(diào),于是,Zookeeper 的名字也就由此誕生了。

Ⅱ.ZooKeeper 概覽

ZooKeeper 是一個開源的分布式協(xié)調(diào)服務(wù),ZooKeeper 框架最初是在“Yahoo!"上構(gòu)建的,用于以簡單而穩(wěn)健的方式訪問他們的應(yīng)用程序。

后來,Apache ZooKeeper 成為 Hadoop,HBase 和其他分布式框架使用的有組織服務(wù)的標(biāo)準(zhǔn)。

例如,Apache HBase 使用 ZooKeeper 跟蹤分布式數(shù)據(jù)的狀態(tài)。

ZooKeeper 的設(shè)計目標(biāo)是將那些復(fù)雜且容易出錯的分布式一致性服務(wù)封裝起來,構(gòu)成一個高效可靠的原語集,并以一系列簡單易用的接口提供給用戶使用。

原語: 操作系統(tǒng)或計算機網(wǎng)絡(luò)用語范疇。它是由若干條指令組成的,用于完成一定功能的一個過程。具有不可分割性,即原語的執(zhí)行必須是連續(xù)的,在執(zhí)行過程中不允許被中斷。

ZooKeeper 是一個典型的分布式數(shù)據(jù)一致性解決方案,分布式應(yīng)用程序可以基于 ZooKeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊列等功能。

ZooKeeper 一個最常用的使用場景就是用于擔(dān)任服務(wù)生產(chǎn)者和服務(wù)消費者的注冊中心。

服務(wù)生產(chǎn)者將自己提供的服務(wù)注冊到 ZooKeeper 中心,服務(wù)的消費者在進行服務(wù)調(diào)用的時候先到 ZooKeeper 中查找服務(wù),獲取到服務(wù)生產(chǎn)者的詳細(xì)信息之后,再去調(diào)用服務(wù)生產(chǎn)者的內(nèi)容與數(shù)據(jù)。

如下圖所示,在 Dubbo 架構(gòu)中 ZooKeeper 就擔(dān)任了注冊中心這一角色。

Dubbo 架構(gòu)圖

Ⅲ.結(jié)合個人使用講一下 ZooKeeper

在我自己做過的項目中,主要使用到了 ZooKeeper 作為 Dubbo 的注冊中心(Dubbo 官方推薦使用 ZooKeeper 注冊中心)。

另外在搭建 Solr 集群的時候,我使用 ZooKeeper 作為 Solr 集群的管理工具。

這時,ZooKeeper 主要提供下面幾個功能:

  • 集群管理:容錯、負(fù)載均衡。
  • 配置文件的集中管理。
  • 集群的入口。

我個人覺得在使用 ZooKeeper 的時候,最好是使用集群版的 ZooKeeper 而不是單機版的。

官網(wǎng)給出的架構(gòu)圖就描述的是一個集群版的 ZooKeeper 。通常 3 臺服務(wù)器就可以構(gòu)成一個 ZooKeeper 集群了。

為什么最好使用奇數(shù)臺服務(wù)器構(gòu)成 ZooKeeper 集群?

我們知道在 ZooKeeper 中 Leader 選舉算法采用了 Zab 協(xié)議。Zab 核心思想是當(dāng)多數(shù) Server 寫成功,則任務(wù)數(shù)據(jù)寫成功:

  • 如果有 3 個 Server,則最多允許 1 個 Server 掛掉。
  • 如果有 4 個 Server,則同樣最多允許 1 個 Server 掛掉。

既然 3 個或者 4 個 Server,同樣最多允許 1 個 Server 掛掉,那么它們的可靠性是一樣的。

所以選擇奇數(shù)個 ZooKeeper Server 即可,這里選擇 3 個 Server。

二、關(guān)于 ZooKeeper 的一些重要概念

Ⅰ.重要概念總結(jié)

關(guān)于 ZooKeeper 的一些重要概念:

  • ZooKeeper 本身就是一個分布式程序(只要半數(shù)以上節(jié)點存活,ZooKeeper 就能正常服務(wù))。
  • 為了保證高可用,最好是以集群形態(tài)來部署 ZooKeeper,這樣只要集群中大部分機器是可用的(能夠容忍一定的機器故障),那么 ZooKeeper 本身仍然是可用的。
  • ZooKeeper 將數(shù)據(jù)保存在內(nèi)存中,這也就保證了 高吞吐量和低延遲(但是內(nèi)存限制了能夠存儲的容量不太大,此限制也是保持 Znode 中存儲的數(shù)據(jù)量較小的進一步原因)。
  • ZooKeeper 是高性能的。在“讀”多于“寫”的應(yīng)用程序中尤其地高性能,因為“寫”會導(dǎo)致所有的服務(wù)器間同步狀態(tài)。(“讀”多于“寫”是協(xié)調(diào)服務(wù)的典型場景。)
  • ZooKeeper 有臨時節(jié)點的概念。當(dāng)創(chuàng)建臨時節(jié)點的客戶端會話一直保持活動,瞬時節(jié)點就一直存在。
  • 而當(dāng)會話終結(jié)時,瞬時節(jié)點被刪除。持久節(jié)點是指一旦這個 ZNode 被創(chuàng)建了,除非主動進行 ZNode 的移除操作,否則這個 ZNode 將一直保存在 Zookeeper 上。
  • ZooKeeper 底層其實只提供了兩個功能:①管理(存儲、讀取)用戶程序提交的數(shù)據(jù);②為用戶程序提交數(shù)據(jù)節(jié)點監(jiān)聽服務(wù)。

下面關(guān)于會話(Session)、 Znode、版本、Watcher、ACL 概念的總結(jié)都在《從 Paxos 到 ZooKeeper 》第四章第一節(jié)以及第七章第八節(jié)有提到,感興趣的可以看看!

Ⅱ.會話(Session)

Session 指的是 ZooKeeper 服務(wù)器與客戶端會話。在 ZooKeeper 中,一個客戶端連接是指客戶端和服務(wù)器之間的一個 TCP 長連接。

客戶端啟動的時候,首先會與服務(wù)器建立一個 TCP 連接,從第一次連接建立開始,客戶端會話的生命周期也開始了。

通過這個連接,客戶端能夠通過心跳檢測與服務(wù)器保持有效的會話,也能夠向 Zookeeper 服務(wù)器發(fā)送請求并接受響應(yīng),同時還能夠通過該連接接收來自服務(wù)器的 Watch 事件通知。

Session 的 sessionTimeout 值用來設(shè)置一個客戶端會話的超時時間。

當(dāng)由于服務(wù)器壓力太大、網(wǎng)絡(luò)故障或是客戶端主動斷開連接等各種原因?qū)е驴蛻舳诉B接斷開時,只要在 sessionTimeout 規(guī)定的時間內(nèi)能夠重新連接上集群中任意一臺服務(wù)器,那么之前創(chuàng)建的會話仍然有效。

在為客戶端創(chuàng)建會話之前,服務(wù)端首先會為每個客戶端都分配一個 sessionID。

由于 sessionID 是 Zookeeper 會話的一個重要標(biāo)識,許多與會話相關(guān)的運行機制都是基于這個 sessionID 的。

因此,無論是哪臺服務(wù)器為客戶端分配的 sessionID,都務(wù)必保證全局唯一。

Ⅲ.Znode

在談到分布式的時候,我們通常說的“節(jié)點"是指組成集群的每一臺機器。

然而,在 ZooKeeper 中,“節(jié)點"分為兩類:

  • 第一類同樣是指構(gòu)成集群的機器,我們稱之為機器節(jié)點。
  • 第二類則是指數(shù)據(jù)模型中的數(shù)據(jù)單元,我們稱之為數(shù)據(jù)節(jié)點一ZNode。

ZooKeeper 將所有數(shù)據(jù)存儲在內(nèi)存中,數(shù)據(jù)模型是一棵樹(Znode Tree),由斜杠(/)的進行分割的路徑,就是一個 Znode,例如/foo/path1。每個上都會保存自己的數(shù)據(jù)內(nèi)容,同時還會保存一系列屬性信息。

在 Zookeeper 中,Node 可以分為持久節(jié)點和臨時節(jié)點兩類。所謂持久節(jié)點是指一旦這個 ZNode 被創(chuàng)建了,除非主動進行 ZNode 的移除操作,否則這個 ZNode 將一直保存在 ZooKeeper 上。

而臨時節(jié)點就不一樣了,它的生命周期和客戶端會話綁定,一旦客戶端會話失效,那么這個客戶端創(chuàng)建的所有臨時節(jié)點都會被移除。

另外,ZooKeeper 還允許用戶為每個節(jié)點添加一個特殊的屬性:SEQUENTIAL。

一旦節(jié)點被標(biāo)記上這個屬性,那么在這個節(jié)點被創(chuàng)建的時候,ZooKeeper 會自動在其節(jié)點名后面追加上一個整型數(shù)字,這個整型數(shù)字是一個由父節(jié)點維護的自增數(shù)字。

Ⅳ.版本

在前面我們已經(jīng)提到,Zookeeper 的每個 ZNode 上都會存儲數(shù)據(jù),對應(yīng)于每個 ZNode,Zookeeper 都會為其維護一個叫作 Stat 的數(shù)據(jù)結(jié)構(gòu)。

Stat 中記錄了這個 ZNode 的三個數(shù)據(jù)版本,分別是:

  • version(當(dāng)前 ZNode 的版本)
  • cversion(當(dāng)前 ZNode 子節(jié)點的版本)
  • aversion(當(dāng)前 ZNode 的 ACL 版本)

Ⅴ.Watcher

Watcher(事件監(jiān)聽器),是 ZooKeeper 中的一個很重要的特性。

ZooKeeper 允許用戶在指定節(jié)點上注冊一些 Watcher,并且在一些特定事件觸發(fā)的時候,ZooKeeper 服務(wù)端會將事件通知到感興趣的客戶端上去,該機制是 ZooKeeper 實現(xiàn)分布式協(xié)調(diào)服務(wù)的重要特性。

Ⅵ.ACL

ZooKeeper 采用 ACL(AccessControlLists)策略來進行權(quán)限控制,類似于 UNIX 文件系統(tǒng)的權(quán)限控制。

ZooKeeper 定義了 5 種權(quán)限,如下圖:

其中尤其需要注意的是,CREATE 和 DELETE 這兩種權(quán)限都是針對子節(jié)點的權(quán)限控制。

三、ZooKeeper 特點

ZooKeeper 有哪些特點呢?具體如下:

  • 順序一致性:從同一客戶端發(fā)起的事務(wù)請求,最終將會嚴(yán)格地按照順序被應(yīng)用到 ZooKeeper 中去。
  • 原子性:所有事務(wù)請求的處理結(jié)果在整個集群中所有機器上的應(yīng)用情況是一致的,也就是說,要么整個集群中所有的機器都成功應(yīng)用了某一個事務(wù),要么都沒有應(yīng)用。
  • 單一系統(tǒng)映像:無論客戶端連到哪一個 ZooKeeper 服務(wù)器上,其看到的服務(wù)端數(shù)據(jù)模型都是一致的。
  • 可靠性:一旦一次更改請求被應(yīng)用,更改的結(jié)果就會被持久化,直到被下一次更改覆蓋。

四、ZooKeeper 設(shè)計目標(biāo)

Ⅰ.簡單的數(shù)據(jù)模型

ZooKeeper 允許分布式進程通過共享的層次結(jié)構(gòu)命名空間進行相互協(xié)調(diào),這與標(biāo)準(zhǔn)文件系統(tǒng)類似。

名稱空間由 ZooKeeper 中的數(shù)據(jù)寄存器組成,稱為 Znode,這些類似于文件和目錄。

與為存儲設(shè)計的典型文件系統(tǒng)不同,ZooKeeper 數(shù)據(jù)保存在內(nèi)存中,這意味著 ZooKeeper 可以實現(xiàn)高吞吐量和低延遲。

Ⅱ.可構(gòu)建集群

為了保證高可用,最好是以集群形態(tài)來部署 ZooKeeper,這樣只要集群中大部分機器是可用的(能夠容忍一定的機器故障),那么 ZooKeeper 本身仍然是可用的。

客戶端在使用 ZooKeeper 時,需要知道集群機器列表,通過與集群中的某一臺機器建立 TCP 連接來使用服務(wù)。

客戶端使用這個 TCP 鏈接來發(fā)送請求、獲取結(jié)果、獲取監(jiān)聽事件以及發(fā)送心跳包。如果這個連接異常斷開了,客戶端可以連接到另外的機器上。

ZooKeeper 官方提供的架構(gòu)圖:

上圖中每一個 Server 代表一個安裝 ZooKeeper 服務(wù)的服務(wù)器。組成 ZooKeeper 服務(wù)的服務(wù)器都會在內(nèi)存中維護當(dāng)前的服務(wù)器狀態(tài),并且每臺服務(wù)器之間都互相保持著通信。

集群間通過 Zab 協(xié)議(Zookeeper Atomic Broadcast)來保持?jǐn)?shù)據(jù)的一致性。

Ⅲ.順序訪問

對于來自客戶端的每個更新請求,ZooKeeper 都會分配一個全局唯一的遞增編號。

這個編號反應(yīng)了所有事務(wù)操作的先后順序,應(yīng)用程序可以使用 ZooKeeper 這個特性來實現(xiàn)更高層次的同步原語。這個編號也叫做時間戳—zxid(ZooKeeper Transaction Id)。

Ⅳ.高性能

ZooKeeper 是高性能的。在“讀”多于“寫”的應(yīng)用程序中尤其地高性能,因為“寫”會導(dǎo)致所有的服務(wù)器間同步狀態(tài)。(“讀”多于“寫”是協(xié)調(diào)服務(wù)的典型場景。)

六、ZooKeeper 集群角色介紹

最典型集群模式:Master/Slave 模式(主備模式)。在這種模式中,通常 Master 服務(wù)器作為主服務(wù)器提供寫服務(wù),其他的 Slave 服務(wù)器從服務(wù)器通過異步復(fù)制的方式獲取 Master 服務(wù)器最新的數(shù)據(jù)提供讀服務(wù)。

但是,在 ZooKeeper 中沒有選擇傳統(tǒng)的 Master/Slave 概念,而是引入了Leader、Follower 和 Observer 三種角色。

如下圖所示:

ZooKeeper 集群中的所有機器通過一個 Leader 選舉過程來選定一臺稱為 “Leader” 的機器。

Leader 既可以為客戶端提供寫服務(wù)又能提供讀服務(wù)。除了 Leader 外,F(xiàn)ollower 和 Observer 都只能提供讀服務(wù)。

Follower 和 Observer 唯一的區(qū)別在于 Observer 機器不參與 Leader 的選舉過程,也不參與寫操作的“過半寫成功”策略,因此 Observer 機器可以在不影響寫性能的情況下提升集群的讀性能。

七、ZooKeeper & ZAB 協(xié)議 & Paxos 算法

Ⅰ.ZAB 協(xié)議 & Paxos 算法

Paxos 算法可以說是 ZooKeeper 的靈魂了。但是,ZooKeeper 并沒有完全采用 Paxos 算法 ,而是使用 ZAB 協(xié)議作為其保證數(shù)據(jù)一致性的核心算法。

另外,在 ZooKeeper 的官方文檔中也指出,ZAB 協(xié)議并不像 Paxos 算法那樣,是一種通用的分布式一致性算法,它是一種特別為 ZooKeeper 設(shè)計的崩潰可恢復(fù)的原子消息廣播算法。

Ⅱ.ZAB 協(xié)議介紹

ZAB(ZooKeeper Atomic Broadcast 原子廣播)協(xié)議是為分布式協(xié)調(diào)服務(wù) ZooKeeper 專門設(shè)計的一種支持崩潰恢復(fù)的原子廣播協(xié)議。

在 ZooKeeper 中,主要依賴 ZAB 協(xié)議來實現(xiàn)分布式數(shù)據(jù)一致性,基于該協(xié)議,ZooKeeper 實現(xiàn)了一種主備模式的系統(tǒng)架構(gòu)來保持集群中各個副本之間的數(shù)據(jù)一致性。

Ⅲ.ZAB 協(xié)議兩種基本的模式

ZAB 協(xié)議包括兩種基本的模式,分別是崩潰恢復(fù)和消息廣播。

當(dāng)整個服務(wù)框架在啟動過程中,或是當(dāng) Leader 服務(wù)器出現(xiàn)網(wǎng)絡(luò)中斷、崩潰退出與重啟等異常情況時,ZAB 協(xié)議就會進入恢復(fù)模式并選舉產(chǎn)生新的 Leader 服務(wù)器。

當(dāng)選舉產(chǎn)生了新的 Leader 服務(wù)器,同時集群中已經(jīng)有過半的機器與該 Leader 服務(wù)器完成了狀態(tài)同步之后,ZAB 協(xié)議就會退出恢復(fù)模式。

其中,所謂的狀態(tài)同步是指數(shù)據(jù)同步,用來保證集群中存在過半的機器能夠和 Leader 服務(wù)器的數(shù)據(jù)狀態(tài)保持一致。

當(dāng)集群中已經(jīng)有過半的 Follower 服務(wù)器完成了和 Leader 服務(wù)器的狀態(tài)同步,那么整個服務(wù)框架就可以進人消息廣播模式了。

當(dāng)一臺同樣遵守 ZAB 協(xié)議的服務(wù)器啟動后加入到集群中時,如果此時集群中已經(jīng)存在一個 Leader 服務(wù)器在負(fù)責(zé)進行消息廣播。

那么新加入的服務(wù)器就會自覺地進人數(shù)據(jù)恢復(fù)模式:找到 Leader 所在的服務(wù)器,并與其進行數(shù)據(jù)同步,然后一起參與到消息廣播流程中去。

正如上文介紹中所說的,ZooKeeper 設(shè)計成只允許唯一的一個 Leader 服務(wù)器來進行事務(wù)請求的處理。

Leader 服務(wù)器在接收到客戶端的事務(wù)請求后,會生成對應(yīng)的事務(wù)提案并發(fā)起一輪廣播協(xié)議。

而如果集群中的其他機器接收到客戶端的事務(wù)請求,那么這些非 Leader 服務(wù)器會首先將這個事務(wù)請求轉(zhuǎn)發(fā)給 Leader 服務(wù)器。

八、總結(jié)

通過閱讀本文,想必大家已從以下這七點了解了 ZooKeeper:

  • ZooKeeper 的由來
  • ZooKeeper 到底是什么
  • ZooKeeper 的一些重要概念(會話(Session)、Znode、版本、Watcher、ACL)
  • ZooKeeper 的特點
  • ZooKeeper 的設(shè)計目標(biāo)
  • ZooKeeper 集群角色介紹(Leader、Follower 和 Observer 三種角色)
  • ZooKeeper & ZAB 協(xié)議 & Paxos 算法

寫在最后

免費Java高級資料需要自己領(lǐng)取:涵蓋了高可用,高并發(fā),高性能及分布式,Jvm性能調(diào)
優(yōu),MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構(gòu)資料。

傳送門:https://shimo.im/docs/f2ajdNJBQJItSobT/

比你優(yōu)秀的對手在學(xué)習(xí),你的仇人在磨刀,你的閨蜜在減肥,隔壁老王在練腰, 我們必須不斷學(xué)習(xí),否則我們將被學(xué)習(xí)者超越!

趁年輕,使勁拼,給未來的自己一個交代!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,635評論 2 380

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