羅輯思維首席架構(gòu)師:Go微服務(wù)改造實踐

一、改造的背景

得到最早的APP就是一個單體的PHP的應用,就是圖中最大的黃色塊癣疟,中間藍色塊代表不同模塊挣柬。下面的黃色部分代表passport 和支付系統(tǒng),這個是在做得到之前就存在的系統(tǒng)睛挚,因為公司早期有微信里的電商業(yè)務(wù)邪蛔。

后來發(fā)現(xiàn)有一些業(yè)務(wù)邏輯并不需要從得到走,還有一些數(shù)據(jù)格式轉(zhuǎn)換的工作也不需要跟業(yè)務(wù)完全耦合扎狱,所以加了一層PHP的網(wǎng)關(guān)就是下圖看到的V3那部分侧到。但是這樣做也有一些問題,PHP后端是FPM淤击,一旦后端的接口響應較慢床牧,就需要啟動大量FPM保證并發(fā)訪問,從而導致操作系統(tǒng)負載較高遭贸,從這一點上來說,使用PHP做這部分工作并不合適心软。

屋漏偏逢連夜雨

案例一:8/31大故障:2017年8月31日的時候壕吹,老板做活動,導致流量超過預期很多删铃,系統(tǒng)掛了兩個小時耳贬。

案例二:羅老師要跨年

每年羅老師都要跨年演講,第一年是在優(yōu)酷猎唁,有200多萬人的在線觀看咒劲,第二年是同時和優(yōu)酷等視頻網(wǎng)站再加上深圳衛(wèi)視一起合作直播,2016年深圳衛(wèi)視的收視率是地方第一诫隅。2017年的老板當時想要送東西腐魂,送東西的這個場景比較恐怖,二維碼一放出來逐纬,就會有大量用戶同時請求蛔屹。

最恐怖的事情是,老板要送的東西8月31日的時候還沒有豁生,要在后面2個月期間把東西開發(fā)出來兔毒。一方面業(yè)務(wù)迭代不能停,一方面需要扛過跨年甸箱,所以就需要我們對業(yè)務(wù)系統(tǒng)進行改造育叁。

改造目標

高性能:首先是性能要高,如果你單臺機器跑幾十QPS芍殖,那么堆機器也很難滿足要求豪嗽。

服務(wù)化:服務(wù)化實際上在故障之前就已經(jīng)開始了,并且由于我們不同的業(yè)務(wù)團隊已經(jīng)在負責不同的業(yè)務(wù),實際上也是需要服務(wù)化繼續(xù)做下去昵骤。

資源拆分隔離:隨著服務(wù)化過程树碱,就需要對資源進行拆分,需要每個服務(wù)提供相應的接口变秦,服務(wù)之間不能直接訪問其他服務(wù)的數(shù)據(jù)庫或者緩存成榜。

高可用:當時定的目標是99.9的可用性。

Go的好處很多蹦玫,最重要的還是對PHP程序員來說赎婚,上手更容易,而且性能好很多

二樱溉、改造的過程

首先有一個系統(tǒng)架構(gòu)圖

對于系統(tǒng)改造來說挣输,首先需要知道,系統(tǒng)需要改成什么樣子福贞。因此我們需要一個架構(gòu)的藍圖撩嚼。上面就是我們的架構(gòu)藍圖。首先需要的是一個統(tǒng)一對外的API GATEWAY挖帘,圖中最上層的黃色部分完丽。 中間淡紫色的部分是對外的業(yè)務(wù)服務(wù)。淺綠色部分是基礎(chǔ)資源服務(wù)拇舀,比如音頻文稿信息逻族,加密服務(wù)。下面紅色部分是支付和passport等公用服務(wù)骄崩,最右側(cè)是一些通用的框架和中間件聘鳞。最下層是一些基礎(chǔ)設(shè)施。

我們的框架跟基礎(chǔ)設(shè)施的完善和系統(tǒng)重構(gòu)是交織進行的要拂,不是說一開始就有一個完全沒問題的設(shè)計抠璃,隨著業(yè)務(wù)的改造,會有很多新的功能加進來脱惰。

框架和基礎(chǔ)設(shè)施完善

我不講應用系統(tǒng)怎么拆分鸡典,因為每個公司業(yè)務(wù)系統(tǒng)都不一樣,我講一下我們在框架和中間件這部分事情枪芒。

API gateway

API gateway是我們和陳皓(著名的左耳朵耗子)團隊合作研發(fā)的彻况。他們團隊對于我們成功跨年幫助很大,在此先感謝一下舅踪。

目的:

限流

API gateway主要的目的就是限流纽甘,改造過程當中,我們線上有400多個接口抽碌,經(jīng)常加新功能悍赢。我們可以保證新接口的性能决瞳,但是總有在改造過程中疏忽的老接口,通過API gateway限流可以保證在流量大的時候左权,老接口也有部分用戶可用皮胡。

升級API

大部分的API升級都是跟客戶端解決的,但是我們不太強制用戶升級赏迟,導致線上老接口存在很長時間轨域,我們需要在API gateway這一層做一些把新接口數(shù)據(jù)格式轉(zhuǎn)成老接口數(shù)據(jù)格式的工作血当。

鑒權(quán)

在拆分服務(wù)之后盗誊,需要統(tǒng)一對接口進行鑒權(quán)和訪問控制逝钥,業(yè)界的做法通常都是在網(wǎng)關(guān)這一層來做,我們也不例外糕再。

接下來看一下API gateway的架構(gòu):

API gateway由一個write節(jié)點和多個read節(jié)點量没,節(jié)點之間通過gossip協(xié)議通信。每個節(jié)點最上層有一個CLI的命令行突想,可以用來調(diào)用Gateway的API殴蹄。下層的HTTPServer等都是一個plugin,由多個plugin組成不同的pipeline來處理不同的請求猾担。在后面我會介紹這個的設(shè)計饶套。每個節(jié)點都有一個統(tǒng)計模塊來做一些統(tǒng)計信息,這個統(tǒng)計信息主要是接口平均響應時間垒探,QPS等。修改配置之后怠李,write節(jié)點會把配置信息同步到read節(jié)點上圾叼,并且通過model模塊持久化到本地磁盤上。

請求經(jīng)過了兩段pipeline捺癞,第一段pipeline基于請求的url夷蚊。可以在不同的pipeline上面組合不同的plugin髓介。假設(shè)一個接口不需要限流惕鼓,只需要在接口的配置里頭不加limiter plugin就可以了。第二段pipeline基于后端的Server配置唐础,做一些負載均衡的工作箱歧。

接下來看整個API gateway啟動的流程和調(diào)度方面:

啟動是比較簡單的,去加載plugin一膨,然后再去加載相應的配置文件呀邢,根據(jù)配置文件把plugin和pipeline做對應。右上角的這個調(diào)度器分為靜態(tài)調(diào)度和動態(tài)調(diào)度豹绪。靜態(tài)調(diào)度是假設(shè)分配5個go routine來做處理价淌,始終都有5個go routine來處理對應的請求。動態(tài)調(diào)度器是根據(jù)請求繁忙程度,在一個go routine最大值和最小值之間變化蝉衣。

API gateway鑒權(quán)方面比較簡單括尸,客戶端調(diào)用登錄接口,passport會把token和userid病毡,傳到API gateway濒翻,API gateway再把相應的token傳到這個APP端〖粞椋客戶端下次請求就拿token請求肴焊,如果token驗證不過,就返回客戶端功戚。如果驗證通過再調(diào)用后端不同的服務(wù)獲取結(jié)果娶眷,最后返回結(jié)果給客戶端。

最后再強調(diào)一下API gateway如何進行

我們在API gateway里面引入兩種限流的策略:

滑動窗口限流

為什么會根據(jù)滑動窗口限流呢啸臀?因為線上接口太多届宠,我們也不知道到底是限100好200好還是限10000好,除非每一個都進行壓測乘粒。用滑動窗口來統(tǒng)計一個時間窗口之內(nèi)豌注,響應時間,成功和失敗的數(shù)量灯萍,根絕這個統(tǒng)計數(shù)據(jù)對下一個時間窗口是否要進行限流做判斷轧铁。

QPS的限流

為什么還會留一個QPS的限流呢?因為要做活動旦棉,滑動窗口是一個時間窗口齿风,做活動的時候,客戶拿起手機掃二維碼绑洛,流量瞬間就進來了救斑,滑動窗口在這種情況下很難起到作用。

服務(wù)框架

目的:

簡化應用開發(fā)

服務(wù)注冊發(fā)現(xiàn)

方便配置管理

服務(wù)框架的常用架構(gòu)

第一種方式是做成一個庫真屯,把相關(guān)功能編譯進服務(wù)本身脸候。這里有兩個問題,第一個是我們兼容好幾種語言绑蔫,開發(fā)量比較大运沦。還有一個是一旦客戶端跟隨服務(wù)調(diào)用方發(fā)布到生產(chǎn)環(huán)境中,后續(xù)如果要對客戶庫進行升級配深,勢必要求服務(wù)調(diào)用方修改代碼并重新發(fā)布茶袒,所以該方案的升級推廣有不小的阻力。在業(yè)界來說凉馆,spring cloud薪寓,dubbo亡资,motan都是用這樣的機制。

還有一種方案是把Lord Balancing的功能拿出來做成一個agent向叉,跟consumer單獨跑锥腻,每次consumer請求的時候是通過agent拿到Service Provder的地址,然后再調(diào)用Service Provder母谎。

好處是簡化了服務(wù)調(diào)用方瘦黑,不需要為不同語言開發(fā)客戶庫,LB的升級不需要服務(wù)調(diào)用方改代碼奇唤。

缺點也很明顯幸斥,部署比較復雜;還有可用性檢測會更麻煩一點咬扇,這個agent也可能會掛甲葬。如果agent掛掉,整個服務(wù)也要摘下來懈贺。

百度內(nèi)部的BNS和Airbnb的SmartStack服務(wù)發(fā)現(xiàn)框架也是這種做法经窖。由于我們內(nèi)部語言較多,因此選擇了第二種做法梭灿。

在Consul集群中画侣,每個提供服務(wù)的節(jié)點上都要部署和運行Consul的agent,所有運行Consul agent節(jié)點的集合構(gòu)成Consul Cluster堡妒。Consul agent有兩種運行模式:

Server

Client

這里的Server和Client只是Consul集群層面的區(qū)分配乱,與搭建在Cluster之上 的應用服務(wù)無關(guān)。以Server模式運行的Consul agent節(jié)點用于維護Consul集群的狀態(tài)皮迟,官方建議每個Consul Cluster至少有3個或以上的運行在Server mode的Agent搬泥,Client節(jié)點不限。

Client和Server的角色在DDNS是沒有嚴格區(qū)分的万栅,請求服務(wù)時該服務(wù)就是Client,提供服務(wù)時候就是Server西疤。

NNDS提供出來的是一個SDK可以很容易的集成和擴展為一個獨立的服務(wù)并且集成更多的功能烦粒。采用agent方式,將在每一個服務(wù)器部署安裝得到的agent代赁,支持使用HTTP和grpc進行請求扰她。

服務(wù)完成啟動并可以可以對外提供服務(wù)之后,請求agent的接口v1/service/register將其注冊的進入DDNS芭碍;

注冊成功則其他客戶端可以通過DDNS發(fā)現(xiàn)接口獲取到該APP節(jié)點信息徒役;

如果注冊失敗,APP會重復嘗試重新注冊窖壕,重試三次失敗則報警忧勿;

假設(shè)服務(wù)A需要請求服務(wù)B杉女,服務(wù)名稱為bbb,直接請求本機的agent接口v1/service/getservice鸳吸,獲取到bbb的服務(wù)節(jié)點信息熏挎。

對于agent而言,如果服務(wù)bbb是第一次被請求晌砾,則會請求Consul集群坎拐,獲取到服務(wù)bbb的數(shù)據(jù)之后進行本地從cache并對服務(wù)bbb的節(jié)點進行watch監(jiān)控,并定時更新本地的service信息养匈;

如果獲取失敗哼勇,給出原因,如果是系統(tǒng)錯誤則報警呕乎;

這是服務(wù)框架基本的接口

這個就是客戶端調(diào)用的封裝积担,可以同時支持HTTP和JRTC,在這個之后我們還做了RBAC的權(quán)限控制楣嘁,我們希望能調(diào)哪些服務(wù)都是可以做權(quán)限控制的磅轻。

多級緩存

client請求到server,server先在緩存里找逐虚,找到就返回聋溜,沒有就數(shù)據(jù)庫找,如果找到就回設(shè)到緩存然后返回客戶端叭爱。這里是一個比較簡單的模型撮躁。只有一級cache,但是一級cache有可能不夠用买雾,比如說壓測的時候我們發(fā)現(xiàn)把曼,一個redis在我們的業(yè)務(wù)情況下支撐到接口的QPS就是一萬左右,QPS高一點怎么辦呢漓穿?我們引入多級緩存嗤军。

越靠近上面的緩存就越小,一級就是服務(wù)local cache晃危,如果命中就返回數(shù)據(jù)叙赚,如果沒有就去L1查,如果查到就更新local cache,并且返回數(shù)據(jù)僚饭。如果L1級也沒有就去

L2級查震叮,如果查到數(shù)據(jù)就更新L1 cache/local cache,并返回數(shù)據(jù)

我們上面看到的是針對單條內(nèi)容本身的緩存鳍鸵,在整個棧上來看苇瓣,gateway也可以緩存一部分數(shù)據(jù),不用請求透穿偿乖。這個5的虛線是什么意思呢击罪?因為數(shù)據(jù)修改后需要更新哲嘲,在應用層做有時候會有失敗,所以讀取數(shù)據(jù)庫binlog來補漏外邓,減少數(shù)據(jù)不一致的情況撤蚊。

我一直覺得如果有泛型代碼好寫很多,沒有泛型框架里面就要大量的反射來代替泛型损话。

多級緩存開始加了之后整個性能的對比侦啸,最早PHP是一兩百,改成Go之后丧枪,也不強多少光涂,后面Go和big cache的大概到兩千左右的,但是有一些問題拧烦,后面會講當問題忘闻。后面基于對象的cache,把對象緩存起來恋博,我們跑測試的機器是在八核齐佳,達到這樣的結(jié)果還可以接受。

熔斷降級

接口同時請求內(nèi)部服務(wù)债沮,service7炼吴、8、9不一樣疫衩,service5是掛掉的狀態(tài)硅蹦,但是對外的服務(wù)還在每次調(diào)用,我們需要減少調(diào)用闷煤,讓service5恢復過來童芹。

打開的狀態(tài)下,失敗達到一定的閾值就關(guān)起來鲤拿,等熔斷的窗口結(jié)束假褪,達到一個半開的狀態(tài)接受一部分的請求。如果失敗的閾值很高就回到關(guān)閉的狀態(tài)近顷。這個統(tǒng)計的做法就是我們之前提到的滑動窗口算法生音。

這里是移植了JAVA hystrix的庫,JAVA里面有很多做得很不錯的框架和庫幕庐,值得我們借鑒久锥。

經(jīng)驗總結(jié)

通用基礎(chǔ)庫非常重要

剛才講的性能提升部分家淤,QPS 從600提升到12000异剥,我們只用了一天,主要原因就在于我們通過基礎(chǔ)庫做了大量優(yōu)化絮重,而且基礎(chǔ)庫做的提升冤寿,所有服務(wù)都會受益歹苦。

善用工具

generate + framework提升開發(fā)效率

pprof+trace+go-torch確定性能問題

比如說我們大量的用generate + framework,通過generate和模板生成很多代碼督怜。查性能的時候殴瘦,pprof+trace+go-torch可以幫你節(jié)省很多工作。Go-torch是做火焰圖的号杠,Go新版本已經(jīng)內(nèi)置了火焰圖的功能蚪腋。

這是根據(jù)我們的表結(jié)構(gòu)生成相應的數(shù)據(jù)庫訪問代碼,多級緩存是把所有的訪問都要抽象成K-V姨蟋,K-LIST等訪問模式屉凯,每次這么做的時候手動去寫太繁瑣,我們就做了一個工具眼溶,你用哪一個表悠砚,工具就生成好,你只需要把它組裝一下堂飞。

定位性能問題的時候灌旧,火焰圖一定要用

比如說定位性能問題就要看最長的地方在哪里,著力優(yōu)化這個熱點的code绰筛,壓測的時候發(fā)現(xiàn)枢泰,大家600、900的火火焰圖這里有問題别智,優(yōu)化完成后如下圖

其他經(jīng)驗總結(jié)

例如:

針對熱點代碼做優(yōu)化

合理復用對象

盡量避免反射

合理的序列化和反序列化方式

接下來重點講幾個操作:

GC開銷

舉例來說我們之前有一個服務(wù)會從緩存里面拿到很多ID的list宗苍,數(shù)據(jù)是存成json格式[1,2,3]這樣,發(fā)現(xiàn)json的序列化和反序列化性能開銷非常大薄榛,基本上會占到50%以上的開銷讳窟。

滴滴講他們的json庫,可以提升10倍性能敞恋,實際上在我們的場景下提升不了那么多丽啡,大概只能提升一倍,當然提升一倍也是很大的提升(因為你只用改一行代碼就能提升這么多)硬猫。

其次json飯序列化導致的GC的問題也很厲害补箍,最猛的時候能夠達到20%CPU,即使是在Go的算法也做得很不錯的情況下啸蜜。

最終解決的辦法就是在這里引入PB替代json坑雅。PB反序列化性能(在我們的情況下)確實比json好10倍,并且分配的臨時對象少多了衬横,從而也降低了GC開銷裹粤。

為什么要避免反射呢?我們在本地建了local cache蜂林,緩存整個對象就要求你不能在緩存之外修改這個對象遥诉,但是實際業(yè)務(wù)上有這個需求拇泣。我們出現(xiàn)過這樣的情況后就用反射來做deep copy。JAVA反射還可以用矮锈,原因是jvm會將反射代碼生成JAVA代碼霉翔,實際上調(diào)用的是生成的代碼。

但是在Go里面不是苞笨,本來Go的性能是和C接近的债朵,大量用了反射之后,性能就跟python接近額瀑凝。后來我們就定義一個cloneable的接口葱弟,讓程序員手動來做這個clone工作。

壓力測試

我們主要用的就是ab和Siege猜丹,這兩個通常是針對單個系統(tǒng)的壓力測試芝加。實際上用戶在使用的過程當中,調(diào)用鏈上每一個地方都可能出現(xiàn)問題射窒。所以在微服務(wù)的情況下藏杖,單個系統(tǒng)的壓力測試,雖然很重要脉顿,但是不足以完全消除我們系統(tǒng)的所有問題蝌麸。

舉一個例子,跨年的時候羅老板要送東西艾疟,首先要領(lǐng)東西来吩,領(lǐng)東西是一個接口,接下來通常用戶會再刷一下已購列表看看在不在蔽莱,最后再確認一下他領(lǐng)到的東西對不對弟疆。因此你需要對整個鏈路進行壓測,不能只壓測一下領(lǐng)取接口盗冷,這樣可能是有問題的怠苔。假設(shè)你已購列表接口比較慢,用戶領(lǐng)了以后就再刷一下看一看有沒有仪糖,沒有的情況下柑司,一般用戶會持續(xù)的刷,導致越慢的接口越容易成為瓶頸锅劝。因此需要合理的規(guī)劃訪問路徑攒驰,對鏈路上的所有服務(wù)進行壓測,不能只關(guān)注一個服務(wù)故爵。

我們直接買了阿里云PTS的服務(wù)玻粪,他們做法就是在CDN節(jié)點上模擬請求,可以對整個訪問路徑進行模擬。

正在做什么

分庫分表和分布式事務(wù)

選擇一個數(shù)據(jù)庫跟你公司相關(guān)的運維是相關(guān)的奶段。分布式事務(wù)在我這里比較重要,我們有很多購買的環(huán)節(jié)剥纷,一旦拆了微服務(wù)之后痹籍,只要有一個地方錯,就需要對整個進行回滾晦鞋。我們現(xiàn)在的做法是手動控制蹲缠,但是隨著你后面的業(yè)務(wù)越來越多,不可能所有的都手動控制悠垛,這時就需要有一個分布式事務(wù)框架线定,所以我們現(xiàn)在基于TCC的方式正在做自己的分布式事務(wù)框架。

分庫分表也是一個硬性的需求确买,我們在這里暫時沒有上tidb的原因主要是DBA團隊對tidb不熟悉斤讥。我們之前的分庫分表也是程序員自己來處理,現(xiàn)在正在做一個框架能同時支持分庫和分表湾趾,同時支持hash和range兩種方式芭商。

API gateway

API gateway上面有很多事情可以做,我們在熔斷和降級做了一些事情〔蟛現(xiàn)在一些Service mesh做的很多事情是把很多工作放在內(nèi)部API gateway上铛楣,是做控制的事情,實際上不應該是業(yè)務(wù)邏輯關(guān)心的事情艺普。我們也在考慮怎么把API gateway和SM做結(jié)合簸州。

APM

拆了微服務(wù)之后,最大的問題是不方便定位具體問題在哪里歧譬。我們有時候出問題岸浑,我叫好幾個人看看各自負責的系統(tǒng)對不對,大家人肉看出問題的地方在哪瑰步,這是個比較蛋疼的做法助琐。因入APM+tracing之后,就方便我們來追蹤問題在哪里面氓。

容器化

我們現(xiàn)在的線上環(huán)境兵钮,還是在用虛擬機。仿真環(huán)境和測試環(huán)境已經(jīng)是容器舌界,使用容器有很多好處掘譬,我就不一一列舉了。這也是我們下半年要做的重點工作呻拌。

緩存服務(wù)化

我們現(xiàn)在有多級緩存的實現(xiàn)葱轩,但是多級緩存還是一個庫的形式來實現(xiàn)的。如果把緩存抽出來,使用memcached或者redis的協(xié)議靴拱,抽出來成為一個獨立的服務(wù)垃喊。后面的業(yè)務(wù)系統(tǒng)迭代的時候不用關(guān)心緩存本身的擴容縮容策略。在這里順便給大家推薦一個架構(gòu)交流群:617434785袜炕,里面會分享一些資深架構(gòu)師錄制的視頻錄像:有Spring本谜,MyBatis,Netty源碼分析偎窘,高并發(fā)乌助、高性能、分布式陌知、微服務(wù)架構(gòu)的原理他托,JVM性能優(yōu)化這些成為架構(gòu)師必備的知識體系。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末仆葡,一起剝皮案震驚了整個濱河市赏参,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌沿盅,老刑警劉巖登刺,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嗡呼,居然都是意外死亡纸俭,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門南窗,熙熙樓的掌柜王于貴愁眉苦臉地迎上來揍很,“玉大人,你說我怎么就攤上這事万伤≈匣冢” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵敌买,是天一觀的道長简珠。 經(jīng)常有香客問我,道長虹钮,這世上最難降的妖魔是什么聋庵? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮芙粱,結(jié)果婚禮上祭玉,老公的妹妹穿的比我還像新娘。我一直安慰自己春畔,他們只是感情好脱货,可當我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布岛都。 她就那樣靜靜地躺著,像睡著了一般振峻。 火紅的嫁衣襯著肌膚如雪臼疫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天扣孟,我揣著相機與錄音烫堤,去河邊找鬼。 笑死哈打,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的讯壶。 我是一名探鬼主播料仗,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼伏蚊!你這毒婦竟也來了立轧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤躏吊,失蹤者是張志新(化名)和其女友劉穎氛改,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體比伏,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡胜卤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赁项。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葛躏。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖悠菜,靈堂內(nèi)的尸體忽然破棺而出舰攒,到底是詐尸還是另有隱情,我是刑警寧澤悔醋,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布摩窃,位于F島的核電站,受9級特大地震影響芬骄,放射性物質(zhì)發(fā)生泄漏猾愿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一账阻、第九天 我趴在偏房一處隱蔽的房頂上張望匪蟀。 院中可真熱鬧,春花似錦宰僧、人聲如沸材彪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽段化。三九已至嘁捷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間显熏,已是汗流浹背雄嚣。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留喘蟆,地道東北人缓升。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像蕴轨,于是被迫代替她去往敵國和親港谊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,979評論 2 355

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