Spring Cloud Sleuth + Zipkin 實現(xiàn)服務(wù)追蹤

1. 什么是調(diào)用鏈

一個業(yè)務(wù)功能可能需要多個服務(wù)協(xié)作才能實現(xiàn),一個請求到達(dá)服務(wù)A掷贾,服務(wù)A需要依賴服務(wù)B倦春,服務(wù)B又依賴服務(wù)C户敬,甚至C仍需依賴其他服務(wù)落剪,形成一個調(diào)用鏈條,即調(diào)用鏈尿庐。

2. 為什么要監(jiān)控調(diào)用鏈


上圖傳遞了一個信息忠怖,就是微服務(wù)的復(fù)雜性

  • 出現(xiàn)問題后,定位困難抄瑟,需要對整個調(diào)用鏈路有個完善的監(jiān)控
  • 鏈路復(fù)雜凡泣,需要清晰的鏈路圖譜反映服務(wù)之間的依賴、調(diào)用關(guān)系
  • 整體系統(tǒng)性能及運(yùn)行情況锐借,需要明確的體現(xiàn)问麸,才能根據(jù)實際情況調(diào)整資源

3. 要監(jiān)控哪些方面

  • 圖形化展示整個調(diào)用鏈路
  • 系統(tǒng)的性能指標(biāo)
  • 健康狀況
  • 基礎(chǔ)告警

4. 調(diào)用鏈監(jiān)控的基礎(chǔ)原理

在介紹調(diào)用鏈監(jiān)控工具之前,我們首先需要知道在微服務(wù)架構(gòu)系統(tǒng)中經(jīng)常會遇到兩個問題:

  • 跨微服務(wù)的API調(diào)用發(fā)生異常钞翔,要求快速定位(比如5分鐘以內(nèi))出問題出在哪里,該怎么辦席舍?
  • 跨微服務(wù)的API調(diào)用發(fā)生性 能瓶頸布轿,要求迅速定位(比如5分鐘以內(nèi))出系統(tǒng)瓶頸,該怎么辦来颤?

一般來說要解決這兩個問題或者與之類似的問題汰扭,就需要用到調(diào)用鏈監(jiān)控工具。那么調(diào)用鏈監(jiān)控工具是怎么實現(xiàn)問題的快速定位的呢福铅?這就需要我們理解調(diào)用鏈監(jiān)控的基礎(chǔ)實現(xiàn)原理萝毛,我們來看一張圖:


圖中有兩個微服務(wù)分別是內(nèi)容中心和用戶中心,其中內(nèi)容中心的/shares/1接口會調(diào)用用戶中心的/users/1接口滑黔,這里就產(chǎn)生了一個調(diào)用鏈笆包。我們可以將調(diào)用的過程分為四個階段或者說狀態(tài),當(dāng)內(nèi)容中心發(fā)送調(diào)用請求時處于“client send”狀態(tài)略荡,用戶中心接收到調(diào)用請求時處于“server receive”狀態(tài)庵佣,用戶中心處理完請求并返回結(jié)果時處于“server send”狀態(tài),最后內(nèi)容中心接收到響應(yīng)結(jié)果時處于“client receive”狀態(tài)汛兜。

假設(shè)巴粪,調(diào)用鏈流轉(zhuǎn)每個狀態(tài)時都會向一張數(shù)據(jù)表里插入一些數(shù)據(jù),如下圖所示:


表字段說明:

  • id:自增id
  • span_id:唯一id
  • pspan_id:父級span_id
  • service_name:服務(wù)名稱
  • api:api路徑
  • stage:階段/狀態(tài)
  • timestamp:插入數(shù)據(jù)時的時間戳

這是一張典型的自表一對多的表結(jié)構(gòu)粥谬,根據(jù)這張表的數(shù)據(jù)肛根,就可以實現(xiàn)對以上所提到的兩個問題進(jìn)行快速定位。首先對于第一個問題漏策,可以通過查詢表內(nèi)的數(shù)據(jù)行數(shù)派哲,判斷調(diào)用鏈在哪個階段中斷了。例如表中只有uuid1和uuid2兩條數(shù)據(jù)哟玷,就可以判斷出是user-center的接口出現(xiàn)了問題狮辽,沒有正常返回結(jié)果一也。再如表中只有uuid1、uuid2及uuid3這三條數(shù)據(jù)喉脖,就可以判斷出content-center沒有正常接收到user-center返回的結(jié)果椰苟,以此類推。如此一來树叽,就可以通過表中的數(shù)據(jù)快速定位出跨微服務(wù)的API調(diào)用是在哪個階段發(fā)生了異常舆蝴。

對于第二個問題,可以通過計算timestamp分析哪個調(diào)用比較耗時题诵。例如上圖中的t2 - t1可以得出請求的發(fā)送到請求的接收所消耗的時間洁仗,再如t3 - t2可以得出/users/1這個接口的調(diào)用耗時,而t4 - t1則可以得出整個調(diào)用鏈的耗時性锭,以此類推赠潦。所以當(dāng)跨微服務(wù)的API調(diào)用發(fā)生性能瓶頸時,就可以通過分析各個調(diào)用接口的耗時草冈,快速定位出是哪個微服務(wù)接口拖慢了整個調(diào)用鏈耗時她奥。

以上舉例簡述了實現(xiàn)調(diào)用鏈監(jiān)控的基礎(chǔ)原理,雖然未必所有的調(diào)用鏈監(jiān)控工具都是這么實現(xiàn)的怎棱,但基本都異曲同工哩俭,或在其之上進(jìn)行了一些拓展。所以只要理解了這一部分拳恋,在學(xué)習(xí)各種調(diào)用鏈監(jiān)控工具時就會比較快上手凡资。


5. Spring Cloud Sleuth簡介

Spring Cloud Sleuth實現(xiàn)了一種分布式的服務(wù)鏈路跟蹤解決方案,通過使用Sleuth可以讓我們快速定位某個服務(wù)的問題谬运。簡單來說隙赁,Sleuth相當(dāng)于調(diào)用鏈監(jiān)控工具的客戶端,集成在各個微服務(wù)上吩谦,負(fù)責(zé)產(chǎn)生調(diào)用鏈監(jiān)控數(shù)據(jù)鸳谜。

官方文檔地址如下:

http://cloud.spring.io/spring-cloud-static/spring-cloud-sleuth/2.0.1.RELEASE/single/spring-cloud-sleuth.html

一些概念:

  1. Span(跨度):Span是基本的工作單元。Span包括一個64位的唯一ID式廷,一個64位trace碼咐扭,描述信息,時間戳事件滑废,key-value 注解(tags)蝗肪,span處理者的ID(通常為IP)。
    最開始的初始Span稱為根span蠕趁,此span中span id和 trace id值相同薛闪。

  2. Trance(跟蹤):包含一系列的span,它們組成了一個樹型結(jié)構(gòu)

  3. Annotation(標(biāo)注):用于及時記錄存在的事件俺陋。常用的Annotation如下:

    • CS(Client Sent 客戶端發(fā)送):客戶端發(fā)送一個請求豁延,表示span的開始
    • SR(Server Received 服務(wù)端接收):服務(wù)端接收請求并開始處理它昙篙。(SR - CS)等于網(wǎng)絡(luò)的延遲
    • SS(Server Sent 服務(wù)端發(fā)送):服務(wù)端處理請求完成,開始返回結(jié)束給服務(wù)端诱咏。(SR - SS)表示服務(wù)端處理請求的時間
    • CR(Client Received 客戶端接收):客戶端完成接受返回結(jié)果苔可,此時span結(jié)束。(CR - CS)表示客戶端接收服務(wù)端數(shù)據(jù)的時間

如果一個服務(wù)的調(diào)用關(guān)系如下:


那么此時將Span和Trace在一個系統(tǒng)中使用Zipkin注解的過程圖形化如下:


每個顏色的表明一個span(總計7個spans袋狞,從A到G)焚辅,每個span有類似的信息

Trace Id = X
Span Id = D
Client Sent

此span表示span的Trance Id是X,Span Id是D苟鸯,同時它發(fā)送一個Client Sent事件

spans 的parent/child關(guān)系圖形化如下:


6. 整合Spring Cloud Sleuth

了解完基本的一些概念后同蜻,我們來在訂單服務(wù)和商品服務(wù)中,集成spring cloud sleuth以及zipkin早处。在兩個服務(wù)的pom.xml文件中湾蔓,增加如下依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

為了更詳細(xì)的查看服務(wù)通信時的日志信息,我們可以將Feign和Sleuth的日志級別設(shè)置為debug陕赃。在兩個項目的配置文件中卵蛉,加入如下內(nèi)容即可:

logging:
  level:
    org.springframework.cloud.openfeign: debug
    org.springframework.cloud.sleuth: debug

啟動訂單、商品服務(wù)項目么库,然后訪問創(chuàng)建訂單的接口,訂單服務(wù)的控制臺會輸出一段這樣的信息:

[order,6c8ecdeefb0fc723,cc4109a6e8e56d1c,false]

商品服務(wù)的控制臺也會輸出類似的信息甘有,如下:

[product,6c8ecdeefb0fc723,40cdc34e745d59e7,false]

說明:

  • product: 看也知道是服務(wù)名稱
  • 6c8ecdeefb0fc723: 是TranceId诉儒,一條鏈路中,只有一個TranceId
  • 40cdc34e745d59e7:則是spanId亏掀,鏈路中的基本工作單元id
  • false:表示是否將數(shù)據(jù)輸出到其他服務(wù)忱反,true則會把信息輸出到其他可視化的服務(wù)上觀察

7. Zipkin搭建與整合

通過Sleuth產(chǎn)生的調(diào)用鏈監(jiān)控信息,讓我們可以得知微服務(wù)之間的調(diào)用鏈路滤愕,但是監(jiān)控信息只輸出到控制臺始終不太方便查看温算。所以我們需要一個圖形化的工具,這時候就輪到zipkin出場了间影。

Zipkin是一款開源的分布式實時數(shù)據(jù)追蹤系統(tǒng)(Distributed Tracking System)注竿,基于 Google Dapper的論文設(shè)計而來,由 Twitter 公司開發(fā)貢獻(xiàn)魂贬。其主要功能是聚集來自各個異構(gòu)系統(tǒng)的實時監(jiān)控數(shù)據(jù)巩割。分布式跟蹤系統(tǒng)還有其他比較成熟的實現(xiàn),例如:Naver的Pinpoint付燥、Apache的HTrace宣谈、阿里的鷹眼Tracing、京東的Hydra键科、新浪的Watchman闻丑,美團(tuán)點(diǎn)評的CAT漩怎,skywalking等。

zipkin官網(wǎng)地址如下:

https://zipkin.io/

ZipKin可以分為兩部分嗦嗡,一部分是zipkin server勋锤,用來作為數(shù)據(jù)的采集存儲、數(shù)據(jù)分析與展示酸钦;zipkin client是zipkin基于不同的語言及框架封裝的一些列客戶端工具怪得,這些工具完成了追蹤數(shù)據(jù)的生成與上報功能,架構(gòu)如下:


zipkin結(jié)構(gòu)圖

Zipkin Server主要包括四個模塊:
(1)Collector 接收或收集各應(yīng)用傳輸?shù)臄?shù)據(jù)
(2)Storage 存儲接受或收集過來的數(shù)據(jù)卑硫,當(dāng)前支持Memory徒恋,MySQL,Cassandra欢伏,ElasticSearch等入挣,默認(rèn)存儲在內(nèi)存中。
(3)API(Query) 負(fù)責(zé)查詢Storage中存儲的數(shù)據(jù)硝拧,提供簡單的JSON API獲取數(shù)據(jù)径筏,主要提供給web UI使用
(4)Web 提供簡單的web界面

ZipKin幾個概念
在追蹤日志中,有幾個基本概念spanId障陶、traceId滋恬、parentId

  • traceId:用來確定一個追蹤鏈的16字符長度的字符串,在某個追蹤鏈中保持不變抱究。
  • spanId:區(qū)域Id恢氯,在一個追蹤鏈中spanId可能存在多個,每個spanId用于表明在某個服務(wù)中的身份鼓寺,也是16字符長度的字符串勋拟。
  • parentId:在跨服務(wù)調(diào)用者的spanId會傳遞給被調(diào)用者,被調(diào)用者會將調(diào)用者的spanId作為自己的parentId妈候,然后自己再生成spanId敢靡。

如下圖:
剛發(fā)起調(diào)用時traceId和spanId是一致,parentId不存在苦银。

被調(diào)用者的traceId和調(diào)用者的traceId時一致的啸胧,被調(diào)用者會產(chǎn)生自己的spanId,并且被調(diào)用者的parentId是調(diào)用者的spanId

接下來我們搭建一個zipkin服務(wù)器墓毒。

方式1吓揪,使用Zipkin官方的Shell下載,使用如下命令可下載最新版本:

[root@01server ~]#  curl -sSL https://zipkin.io/quickstart.sh | bash -s

下載下來的文件名為 zipkin.jar
方式2所计,到Maven中央倉庫下載柠辞,使用瀏覽器訪問如下地址即可:

https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec

下載下來的文件名為 zipkin-server-{版本號}-exec.jar

由于Zipkin實際是一個Spring Boot項目,所以使用以上兩種方式下載的jar包主胧,可以直接使用如下命令啟動:

java jar {zipkin jar包路徑}

方式3叭首,通過docker安裝习勤,命令如下:

[root@01server ~]# docker run -d -p 9411:9411 openzipkin/zipkin

安裝好后,使用瀏覽器訪問9411端口焙格,主頁面如下所示:


然后在訂單服務(wù)中將之前的sleuth依賴替換成如下依賴:

<!-- 這個依賴包含了sleuth和zipkin -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

在配置文件中图毕,增加zipkin相關(guān)的配置項。如下:

spring:
  ...
  zipkin:
    base-url: http://127.0.0.1:9411/  # zipkin服務(wù)器的地址
    # 關(guān)閉服務(wù)發(fā)現(xiàn)眷唉,否則Spring Cloud會把zipkin的url當(dāng)做服務(wù)名稱       
    discoveryClientEnabled: false   
    sender:
      type: web  # 設(shè)置使用http的方式傳輸數(shù)據(jù)
  sleuth:
    sampler:
      probability: 1  # 設(shè)置抽樣采集率為100%予颤,默認(rèn)為0.1,即10%      

配置好后重啟項目冬阳,并訪問創(chuàng)建訂單接口蛤虐。下單成功后,到zipkin頁面上就可以查看到order服務(wù)的鏈路信息了:


會有紅色的信息表示有錯誤肝陪,點(diǎn)擊上圖中的紅色信息后驳庭,可以進(jìn)入到服務(wù)鏈路的查看頁面,在這里可以看到整條服務(wù)鏈路氯窍,并且可以看到每一個服務(wù)調(diào)用的耗時饲常,也可以看到是哪一步調(diào)用發(fā)生了錯誤:


點(diǎn)擊每一行信息都可以查看其詳情信息,例如我點(diǎn)擊耗時46.236ms的那行信息狼讨,其詳細(xì)信息如下:


8. Zipkin數(shù)據(jù)持久化

Zipkin默認(rèn)是將監(jiān)控數(shù)據(jù)存儲在內(nèi)存的贝淤,如果Zipkin掛掉或重啟的話,那么監(jiān)控數(shù)據(jù)就會丟失政供。所以如果想要搭建生產(chǎn)可用的Zipkin霹娄,就需要實現(xiàn)監(jiān)控數(shù)據(jù)的持久化。而想要實現(xiàn)數(shù)據(jù)持久化鲫骗,自然就是得將數(shù)據(jù)存儲至數(shù)據(jù)庫。好在Zipkin支持將數(shù)據(jù)存儲至:

  • 內(nèi)存(默認(rèn))
  • MySQL
  • Elasticsearch
  • Cassandra
    Zipkin數(shù)據(jù)持久化相關(guān)的官方文檔地址如下:

https://github.com/openzipkin/zipkin#storage-component

Zipkin支持的這幾種存儲方式中踩晶,內(nèi)存顯然是不適用于生產(chǎn)的执泰,這一點(diǎn)開始也說了。而使用MySQL的話渡蜻,當(dāng)數(shù)據(jù)量大時术吝,查詢較為緩慢,也不建議使用茸苇。Twitter官方使用的是Cassandra作為Zipkin的存儲數(shù)據(jù)庫排苍,但國內(nèi)大規(guī)模用Cassandra的公司較少,而且Cassandra相關(guān)文檔也不多学密。

綜上淘衙,故采用Elasticsearch是個比較好的選擇,關(guān)于使用Elasticsearch作為Zipkin的存儲數(shù)據(jù)庫的官方文檔如下:

既然選擇Elasticsearch作為Zipkin的存儲數(shù)據(jù)庫腻暮,那么自然首先需要搭建一個Elasticsearch服務(wù)彤守,單節(jié)點(diǎn)搭建比較簡單毯侦,直接到官網(wǎng)下載壓縮包,然后使用如下命令解壓并啟動即可(關(guān)于ES的版本選擇需參考官方文檔具垫,目前Zipkin支持5.x侈离、6.x及7.x):

[root@01server ~]# tar -zxvf elasticsearch-6.5.3-linux-x86_64.tar.gz   # 解壓
[root@01server ~]# cd elasticsearch-6.5.3/bin
[root@01server ~/elasticsearch-6.5.3/bin]# ./elasticsearch  # 啟動

由于Elasticsearch不是本文的重點(diǎn),這里不做不多的介紹筝蚕,關(guān)于Elasticsearch的集群搭建可以參考如下文章:

搭建好Elasticsearch后卦碾,使用如下命令啟動Zipkin,Zipkin就會切換存儲類型為Elasticsearch起宽,然后根據(jù)指定的連接地址連接Elasticsearch并存儲數(shù)據(jù):

STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 java -jar zipkin-server-2.11.3-exec.jar

Tips:

  • 其中洲胖,STORAGE_TYPEES_HOSTS是環(huán)境變量,STORAGE_TYPE用于指定Zipkin的存儲類型是啥燎含;而ES_HOSTS 則用于指定Elasticsearch地址列表宾濒,有多個節(jié)點(diǎn)時使用逗號( , )分隔。
    除此之外屏箍,還可以指定其他環(huán)境變量绘梦,參考下表:

關(guān)于其他環(huán)境變量,可參考官方文檔:

最后可以根據(jù)以下測試步驟赴魁,自行測試一下Zipkin是否能正常將監(jiān)控數(shù)據(jù)持久化存儲:

  1. 往Zipkin中存儲一些數(shù)據(jù)
  2. 停止Zipkin
  3. 再次啟動Zipkin卸奉,查看之前存儲的數(shù)據(jù)是否存在,如果存在說明數(shù)據(jù)已被持久化

關(guān)于依賴關(guān)系圖的問題

在上一小節(jié)中颖御,簡單介紹了Zipkin的數(shù)據(jù)持久化榄棵,并整合了Elasticsearch作為Zipkin的存儲數(shù)據(jù)庫。但此時會有一個問題潘拱,就是Zipkin在整合Elasticsearch后會無法分析服務(wù)之間的依賴關(guān)系圖疹鳄,因為此時數(shù)據(jù)都存儲到Elasticsearch中了,無法再像之前那樣在內(nèi)存中進(jìn)行分析芦岂。

想要解決這個問題瘪弓,需要下載并使用Zipkin的一個子項目:

方式1,使用官方的Shell下載禽最,使用如下命令可下載最新版本:

[root@01server ~]# curl -sSL https://zipkin.io/quickstart.sh | bash -s io.zipkin.dependencies:zipkin-dependencies:LATEST zipkin-dependencies.jar

下載下來的文件名為 zipkin-dependencies.jar

方式2腺怯,到Maven中央倉庫下載,使用瀏覽器訪問如下地址即可:

https://search.maven.org/remote_content?g=io.zipkin.dependencies&a=zipkin-dependencies&v=LATEST

下載下來的文件名為 zipkin-dependencies-{版本號}.jar

下載好后川无,使用如下命令運(yùn)行這個jar包即可分析Elasticsearch中存儲的數(shù)據(jù):

[root@01server ~]# STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 java -jar zipkin-dependencies-2.3.2.jar

該jar包運(yùn)行結(jié)束后呛占,到Zipkin的界面上點(diǎn)開“Dependencies”就可以正常查看到依賴關(guān)系圖了。

方式3懦趋,通過docker下載并運(yùn)行晾虑,命令如下:

[root@01server ~]# docker run --env STORAGE_TYPE=elasticsearch --env ES_HOSTS=192.168.190.129:9200 openzipkin/zipkin-dependencies

Tips:

這個Zipkin Dependencies屬于是一個job,不是服務(wù),即不會持續(xù)運(yùn)行走贪,而是每運(yùn)行一次才分析數(shù)據(jù)佛猛。若想持續(xù)運(yùn)行的話,需要自己寫個定時腳本來定時運(yùn)行這個job

使用Elasticsearch時Zipkin Dependencies支持的環(huán)境變量:


Zipkin Dependencies支持的其他環(huán)境變量:

Zipkin Dependencies默認(rèn)分析的是當(dāng)天的數(shù)據(jù)坠狡,可以通過如下命令讓Zipkin Dependencies分析指定日期的數(shù)據(jù):

參考原文:https://blog.51cto.com/zero01/2173394

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末继找,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子逃沿,更是在濱河造成了極大的恐慌婴渡,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凯亮,死亡現(xiàn)場離奇詭異边臼,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)假消,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門柠并,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人富拗,你說我怎么就攤上這事臼予。” “怎么了啃沪?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵粘拾,是天一觀的道長。 經(jīng)常有香客問我创千,道長缰雇,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任追驴,我火速辦了婚禮械哟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘殿雪。我一直安慰自己戒良,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布冠摄。 她就那樣靜靜地躺著,像睡著了一般几缭。 火紅的嫁衣襯著肌膚如雪河泳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天年栓,我揣著相機(jī)與錄音拆挥,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛纸兔,可吹牛的內(nèi)容都是我干的惰瓜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼汉矿,長吁一口氣:“原來是場噩夢啊……” “哼崎坊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起洲拇,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤奈揍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赋续,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體男翰,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年纽乱,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛾绎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡鸦列,死狀恐怖租冠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敛熬,我是刑警寧澤肺稀,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站应民,受9級特大地震影響话原,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜诲锹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一繁仁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧归园,春花似錦黄虱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至桥爽,卻和暖如春朱灿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钠四。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工盗扒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓侣灶,卻偏偏與公主長得像甸祭,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子褥影,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評論 2 355

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