從零開始仿寫一個(gè)抖音App——日志和埋點(diǎn)以及后端初步架構(gòu)

本文首發(fā)于微信公眾號(hào)——世界上有意思的事,搬運(yùn)轉(zhuǎn)載請(qǐng)注明出處,否則將追究版權(quán)責(zé)任。微信號(hào):a1018998632,交流qq群:859640274

本項(xiàng)目的 github 地址:MyTikTok

這兩周實(shí)在是太忙了,第一個(gè)需求即將上線加了一周的班,然后第二周又團(tuán)建了三天導(dǎo)致這次的文章滯后了兩周,估計(jì)大家都以為我要棄坑了。但是其實(shí)我在團(tuán)建的時(shí)候都在趕文章,讓大家久等了。本周的文章將會(huì)討論下面幾個(gè)問題,大家可以按需跳章查看以節(jié)省寶貴的時(shí)間,本文預(yù)計(jì)閱讀時(shí)間10分鐘

  • 1.討論——總結(jié)前兩周評(píng)論中有意義的討論并給予我的解答
  • 2.日志和埋點(diǎn)——討論一下日志和埋點(diǎn)如何設(shè)計(jì)以及實(shí)現(xiàn)方案
  • 3.后端架構(gòu)初步設(shè)想——討論一下未來的 app 的后端需要怎么架構(gòu)以及如何實(shí)現(xiàn)
  • 4.ubuntu環(huán)境初始化——將云上的環(huán)境初始化成我所熟悉的 mac 環(huán)境(讀者如果是 windows 也可以了解一下,到后期的話文章會(huì)涉及到比較多的 linux 下的操作)

一、討論

討論1:項(xiàng)目會(huì)不會(huì)使用 kotlin?

  • 1.目前我的計(jì)劃是在基礎(chǔ)模塊上面使用 java ,在業(yè)務(wù)模塊中看情況選擇幾個(gè)模塊使用 kotlin。

討論2:本系列文章是標(biāo)題黨,蹭抖音的熱度

  • 1.首先明確一點(diǎn)為什么我要以抖音為例子,原因就是我的公司就是開發(fā)短視頻的,技術(shù)上有類似的地方,而本公司的產(chǎn)品是不可能作為例子開發(fā)的,所以我就以抖音為例希望能過一遍大公司的項(xiàng)目開發(fā)流程和架構(gòu),不僅僅是給讀者帶來好處,對(duì)我來說也是一個(gè)很好的提升。
  • 2.當(dāng)然不可否認(rèn)的是抖音這個(gè) title 給我?guī)砹艘欢ǖ牧髁浚参艘徊糠秩说难矍颍俏覇栃臒o愧。因?yàn)槊恳黄恼碌膬?nèi)容都是我花費(fèi)兩周以上的業(yè)余時(shí)間撰寫的,內(nèi)容的質(zhì)量上我敢說比一般的文章要好上不少。
  • 3.有句話說得好:人紅是非多,放在文章上也是一樣。我不希望打無謂的口水仗所以:以后如果文章中有與技術(shù)和文章無關(guān)的攻擊或者詆毀的評(píng)論我會(huì)直接刪除,并且不做回復(fù)。

二、日志和埋點(diǎn)

日志在一個(gè)項(xiàng)目中起著非常重要的輔助作用,它可以讓開發(fā)人員方便的定位 bug。它可以在系統(tǒng)上線之后讓后臺(tái)監(jiān)控 app 的性能以及穩(wěn)定性。他還可以收集用戶的行為數(shù)據(jù)以方便對(duì)用戶的需求進(jìn)行分析。在這一節(jié)中我會(huì)分析5種不同的日志,并講解其中幾種日志的實(shí)現(xiàn)方式。

首先我先列舉一下五種不同的 log 吧。

  • 1.debug 日志:用于開發(fā)人員本地 debug
  • 2.aop debug 日志:用于開發(fā)人員本地 debug, 使用了 aop 可以通過簡(jiǎn)單的注釋,對(duì)方法和類進(jìn)行切片打日志。用于打一些需要統(tǒng)一執(zhí)行的日志。
  • 3.網(wǎng)絡(luò)請(qǐng)求 日志:用于開發(fā)人員在本地對(duì)網(wǎng)絡(luò)請(qǐng)求 debug
  • 4.本地文件 日志:用于記錄在 app 上線之后出現(xiàn)的bug,將日志打到文件中,可以通過一個(gè)入口讓用戶手動(dòng)點(diǎn)擊上傳日志。
  • 5.埋點(diǎn) 日志:用于記錄用戶使用 app 的數(shù)據(jù)、app 性能等等的埋點(diǎn)日志,數(shù)據(jù)結(jié)構(gòu)由前后端協(xié)商定義,最后會(huì)存入后端的數(shù)據(jù)庫以便進(jìn)行一些數(shù)據(jù)分析。埋點(diǎn)的方式可以是手動(dòng)的,可以是自動(dòng)的。

1、debug日志

圖1:debug日志.png
  • 1.debug 日志比較簡(jiǎn)單,如圖一就是將 android 自身提供的 Log 類進(jìn)行一些封裝,添加一些自己需要的特性和擴(kuò)展,這里就不多贅述了具體實(shí)現(xiàn)可以看項(xiàng)目中的代碼。

2、aop日志

圖2:aop日志.png
  • 1.很多人在寫一些重復(fù)性的日志的時(shí)候就會(huì)想到 aop,這種技術(shù)可以在注解的方法前后注入需要的模板代碼。我在上一篇文章中講到了這個(gè)技術(shù),有興趣的同學(xué)可以去看看,這里我就簡(jiǎn)單說一下。
  • 2.首先我們得先定義一個(gè)注解類,其可以用于注解類或者方法。注解類中可以被填入一些信息,比如是否需要打印方法的初入?yún)⒌鹊取?/li>
  • 3.在注解類使用了之后,我們需要用到 gradle transform。這種技術(shù)可以讓我們?cè)诰幾g期間掃描所有的類,從而找被注解類所注解的方法和類。
  • 4.最后我們可以用上javassist來給找到的方法前后注入我們需要的代碼。注意這里的日志可以是本地的 debug日志,也可以是本地文件日志,還可以是埋點(diǎn)日志。可以說 aop 日志只是一種對(duì)另外幾種日志的自動(dòng)化封裝。

3、網(wǎng)絡(luò)請(qǐng)求日志

圖3:網(wǎng)絡(luò)請(qǐng)求日志.png
  • 1.我們?cè)谡{(diào)試網(wǎng)絡(luò)請(qǐng)求的時(shí)候,除了抓包還會(huì)打印出網(wǎng)絡(luò)請(qǐng)求。這個(gè)時(shí)候就如果有一種統(tǒng)一的形式來打印日志的話就會(huì)方便許多。
  • 2.現(xiàn)在絕大部分的廠商使用的網(wǎng)絡(luò)請(qǐng)求庫都是 okhttp ,所以我就直接在其上面進(jìn)行日志的定制就行了。因?yàn)轫?xiàng)目的 http 模塊還沒有進(jìn)行開發(fā),所以還沒有實(shí)現(xiàn)代碼,這里就講一講大致方案。之后在開發(fā) http 模塊的時(shí)候會(huì)順便講解具體實(shí)現(xiàn)。
  • 3.在講解方案之前我們需要知道,okhttp 的工作方式。如圖3中所示,在一個(gè) okhttp 請(qǐng)求的過程中會(huì)經(jīng)過一個(gè)個(gè)攔截器,從本地向網(wǎng)絡(luò)請(qǐng)求的時(shí)候會(huì)經(jīng)過一次,網(wǎng)絡(luò)請(qǐng)求回來的時(shí)候又會(huì)經(jīng)過一次。
  • 4.所以我們就可以添加一個(gè)日志攔截器在兩次經(jīng)過攔截器的時(shí)候打印請(qǐng)求的 head 和按需打印 請(qǐng)求的 body。注意,這里打印可以是向 debug 日志、本地文件日志、埋點(diǎn)日志這三個(gè)地方打印。分別用于本地 debug、線上 debug和網(wǎng)絡(luò)性能監(jiān)控。

4、本地文件日志

圖4:本地文件日志.png
  • 1.當(dāng)我們?cè)诰€上遇見 bug 的時(shí)候咋辦呢?有些 crash 的日志可以通過 bugly 這種平臺(tái)來進(jìn)行回?fù)啤5怯行┢孑獾?bug 只在某些機(jī)型甚至某些用戶的手機(jī)上發(fā)生。這個(gè)時(shí)候本地文件日志就派上用場(chǎng)了。
  • 2.我們可以在開發(fā)的時(shí)候在一些關(guān)鍵的功能上手動(dòng)添加上本地文件日志。當(dāng)某個(gè)用戶報(bào)了 bug 之后我們就可以讓其通過一個(gè)入口將文件日志發(fā)送到后臺(tái),最后由開發(fā)人員進(jìn)行日志分析找到問題。
  • 3.接下來我就來通過代碼結(jié)合上面的圖4來講解本地文件日志的實(shí)現(xiàn)方式。
  • 4.我們先來看看圖4:
    • 1.LocalFileLogger負(fù)責(zé)提供本模塊對(duì)外的 api,主要功能有兩個(gè):
      • 1.初始化和綁定LocalFileLoggerService(這是一個(gè) service,可以通過 binder 來與外部交互)
      • 2.通過 binder 將外部的添加日志的請(qǐng)求交給LocalFileLoggerService
    • 2.LocalFileLoggerService中會(huì)初始化一個(gè) HandlerThread,本 Service 會(huì)通過 Handler 向其不斷的拋入經(jīng)過高性能拼接的日志的添加請(qǐng)求。
    • 3.FileLogger是負(fù)責(zé)將日志寫入本地的類,其也初始化了一個(gè) HandlerThread,并且自定義了一個(gè) LoggerHandler。這個(gè) Handler 會(huì)將 LocalFileLoggerService 拋過來的一條條日志進(jìn)行累積,當(dāng)積累到了一定量的時(shí)候。發(fā)出寫入日志的請(qǐng)求交給 HandlerThread執(zhí)行。
圖5:LocalFileLogger代碼1.png

圖6:LocalFileLoggerService代碼1.png

圖7:FileLogger代碼1.png

圖8:LoggerHandler代碼1.png
  • 5.再來看看代碼,我們跟著代碼走一遍流程:
    • 1.首先在圖5中我們可以看見在 addLog 中經(jīng)過一系列的調(diào)用,最終交給了 sLogInterface.log 這個(gè)對(duì)象是一個(gè) Binder 對(duì)象,用于操作 LocalFileLoggerService 。
    • 2.進(jìn)入到圖6,可以看見 Service 初始化了一個(gè) HandlerThread 然后定義了一個(gè) Handler 用于向其中拋送請(qǐng)求。然后在看 mBinder 的實(shí)現(xiàn)就是通過 Handler 向 HandlerThread 中拋送 FileLogger.addLog 的執(zhí)行請(qǐng)求。
    • 3.進(jìn)入到圖7,可以看見在 FileLogger 初始化的時(shí)候也初始化了一個(gè) HandlerThread ,然后定義了一個(gè) LoggerHandler 來向其中拋日志寫入請(qǐng)求。FileLogger.addLog 方法中是直接發(fā)送一個(gè)請(qǐng)求。
    • 4.再看圖8,LoggerHandler.add 中并不會(huì)立即向本地寫入日志,而是會(huì)有一 LOG_CACHE_COUNT 閾值,只有超過了這個(gè)閾值才會(huì)向文件系統(tǒng)中寫入日志。

5、埋點(diǎn)日志

圖9:埋點(diǎn)日志.png
  • 1.埋點(diǎn)日志其實(shí)和文件日志類似,我這里就結(jié)合圖9簡(jiǎn)單說一下,具體的代碼大家可以去翻看項(xiàng)目
  • 2.首先還是有一個(gè) UploadLogManager 用于給外部提供 api 以及初始化 LocalFileLoggerService。這里比文件系統(tǒng)復(fù)雜的地方就在于多了一個(gè) UploadLogConfiguration 用于裝配一些設(shè)置。
  • 3.有了 LocalFileLoggerService 之后這里分兩個(gè)不同的埋點(diǎn)日志添加方式。
    • 1.實(shí)時(shí)埋點(diǎn)日志添加:外部需要立即將當(dāng)前的埋點(diǎn)日志上報(bào),此時(shí)就直接將請(qǐng)求發(fā)送給 UploadLogHandler 然后交給 HandlerThread 執(zhí)行,最終 通過 LogSender執(zhí)行網(wǎng)絡(luò)上報(bào)。
    • 2.非實(shí)時(shí)埋點(diǎn)日志添加:這種方式是每隔一定的時(shí)間,LocalFileLoggerService 會(huì)從 UploadLogStorage 中取出一定量的日志,合并之后再像1中一樣上報(bào)埋點(diǎn)。
  • 4.目前因?yàn)?Http 模塊和 數(shù)據(jù)庫模塊都沒有開始寫,所以 UploadLogStorage 和 LogSender 都還只是接口,但是并不影響代碼邏輯。

三、后端架構(gòu)的初步設(shè)想

雖然本項(xiàng)目的著重點(diǎn)是仿抖音 android 端 app 的開發(fā),但是后臺(tái)方面也會(huì)有所涉及。接下來筆者會(huì)介紹一下本項(xiàng)目在后端方面的目標(biāo)和預(yù)期達(dá)到的效果。

1、RPC

可能會(huì)有客戶端的同學(xué)對(duì) RPC(遠(yuǎn)程過程調(diào)用) 這個(gè)詞不怎么了解,我這里就先簡(jiǎn)單介紹一下。

拿 Java 來說:比如我們有兩個(gè)服務(wù) A、B 在兩個(gè)服務(wù)器上,此時(shí)我們要在 A 上調(diào)用 B 的服務(wù)獲取其上的數(shù)據(jù) Foo。那么在 A 中可以寫成 Foo f = b.XXXService();。在這里 Foo 是 A、B 兩個(gè)服務(wù)所定義的數(shù)據(jù)傳輸結(jié)構(gòu),b 是 B 服務(wù)所抽象出來的對(duì)象,其內(nèi)部實(shí)現(xiàn)可以是各種網(wǎng)絡(luò)數(shù)據(jù)交互協(xié)議,比如說 http 協(xié)議。簡(jiǎn)單來說:RPC就是要像調(diào)用本地的函數(shù)一樣去調(diào)遠(yuǎn)程函數(shù)。

現(xiàn)存的 RPC 框架有很多,各個(gè)大廠也都開源了自己框架,我這里就介紹和比較一下幾個(gè)框架,最后結(jié)合本項(xiàng)目的需求選擇適合的框架。

  • 1.Dubbo:這個(gè)是阿里開源的一個(gè)框架,后來阿里因?yàn)榉N種原因把他廢棄了,最后被當(dāng)當(dāng)網(wǎng)維護(hù)擴(kuò)展出了一個(gè) Dubbox。這里就講一講他的優(yōu)劣勢(shì)吧:
    • 1.優(yōu)勢(shì):
      • 1.Dubbo 是用 java 寫的,對(duì)于 android 客戶端的開發(fā)者來說比較友好。
      • 2.Dubbo 的生態(tài)目前來說還是比較好的,筆者去年在有贊實(shí)習(xí) java 開發(fā)的時(shí)候,用過半年的 Dubbo,感覺各種坑都有人踩過,各種庫也都比較完善。
      • 3.對(duì)于服務(wù)治理支持的比較到位。
    • 2.劣勢(shì):
      • 1.跨平臺(tái)能力差,原生的 Dubbo 基本上沒有跨平臺(tái)能力,后面的話集成了 thrift 作為擴(kuò)展的話就有了,不過我總感覺集成之后用起來不方便。
      • 2.以 java 作為主開發(fā)語言的話,不能快速迭代。我們項(xiàng)目的時(shí)間主要是要向 android 客戶端傾斜,所以需要一個(gè)能快速迭代的語言。
      • 3.序列化和反序列化的速度與其他 RPC 框架相比都不是很拔尖。
      • 4.性能較其他幾個(gè)框架差。
  • 2.Thrift:這個(gè)是 FaceBook 開源的一個(gè)框架,2007年由facebook貢獻(xiàn)到apache基金,是apache下的頂級(jí)項(xiàng)目。
    • 1.優(yōu)勢(shì):
      • 1.跨平臺(tái)能力強(qiáng),支持幾乎所有的主流語言。
      • 2.性能比較好
    • 2.劣勢(shì):
      • 1.跨平臺(tái)的語言協(xié)議寫起來比較麻煩。
      • 2.不支持服務(wù)治理
  • 3.Grpc:由 Google 開源的框架,我司目前后端也在使用這個(gè)框架
    • 1.優(yōu)勢(shì):
      • 1.跨平臺(tái)能力強(qiáng)、支持大部分主流開發(fā)語言
      • 2.跨平臺(tái)語言協(xié)議用的是 ProtoBuf,與我們客戶端的技術(shù)棧一致。
      • 3.性能比較好
      • 4.有我司的技術(shù)支持,當(dāng)然不是官方的,不過我可以了解我司在這方面的技術(shù),最后反哺到我們的項(xiàng)目中。
    • 2.劣勢(shì):
      • 1.不支持服務(wù)治理

看了上面的比較我想大家心里已經(jīng)有了答案,沒錯(cuò)我決定使用 grpc 做為本項(xiàng)目后端的 rpc 框架。然后開發(fā)的語言是 python 為主,java 為輔助,后面如果有時(shí)間的話可能會(huì)用 go 實(shí)現(xiàn)一個(gè)小的服務(wù)也說不定。使用這些語言的原因有下面幾點(diǎn):

  • 1.首先 python 目前后臺(tái)的生態(tài)也比較成熟,用起來也比較方便快速。
  • 2.其次我們到了后面會(huì)使用 tensorflow 來訓(xùn)練各種深度學(xué)習(xí)的模型,這樣的話熟練使用 python 是必須的。
  • 3.有人會(huì)問你為什么要用幾種不同的語言來實(shí)現(xiàn)后端的服務(wù)呢?這不是多此一舉嗎。的確,從正常開發(fā)的角度來講是挺多余的,但是多語言的環(huán)境在大一些的廠來講是再正常不過的事情,我的一部分目的也是為了模擬這種場(chǎng)景。除此之外,這種多語言的環(huán)境在我看來還是比較有意思的,想試試玩玩看。

2.微服務(wù)與服務(wù)治理

其實(shí)本來在這里我有很多東西想說的,但是發(fā)現(xiàn)自己現(xiàn)在的能力并不能完全說好這兩個(gè)東西,怕最后會(huì)誤導(dǎo)大家,所以我這里就列一下最后本項(xiàng)目需要完成的與這兩個(gè)目標(biāo)相關(guān)的東西。

  • 1.在未來筆者預(yù)期的是會(huì)有10臺(tái)服務(wù)機(jī)器,兩臺(tái)為一組提供一類服務(wù),一共會(huì)有五個(gè)大類的服務(wù)。
  • 2.所以第一個(gè)要實(shí)現(xiàn)的功能就是:服務(wù)發(fā)現(xiàn)注冊(cè)功能。這個(gè)功能主要是和注冊(cè)中心進(jìn)行交互。
    • 1.服務(wù)提供者啟動(dòng),向注冊(cè)中心注冊(cè)自己提供的服務(wù)
    • 2.消費(fèi)者啟動(dòng),向注冊(cè)中心訂閱自己需要的服務(wù)
    • 3.注冊(cè)中心返回服務(wù)提供者的列表給消費(fèi)者
    • 4.消費(fèi)者從服務(wù)提供者列表中,按照軟負(fù)載均衡算法,選擇一臺(tái)發(fā)起請(qǐng)求
  • 3.為了了解和監(jiān)控各個(gè)服務(wù)的情況,第二個(gè)要實(shí)現(xiàn)的功能就是:服務(wù)監(jiān)控,即累計(jì)計(jì)算隨著時(shí)間推移各個(gè)服務(wù)被調(diào)用的次數(shù)。
  • 4.為了區(qū)分內(nèi)外網(wǎng),以及統(tǒng)一鑒權(quán)。需要實(shí)現(xiàn)的第三個(gè)功能就是:服務(wù)網(wǎng)關(guān),所有外部請(qǐng)求都會(huì)經(jīng)過這個(gè)網(wǎng)關(guān),網(wǎng)關(guān)會(huì)將請(qǐng)求分發(fā)給內(nèi)部的機(jī)器,內(nèi)部機(jī)器調(diào)用完成之后會(huì)將結(jié)果通過網(wǎng)關(guān)返回給外部。

四、ubuntu環(huán)境初始化

不知道在我的讀者中有多少個(gè)人用的是 mac。因?yàn)槲冶救司褪?mac 和 win 的雙系統(tǒng)用戶所以我深知。mac 在開發(fā)方面的好處。這一節(jié)就輕松一點(diǎn),我演示一下如何將本地 mac 命令行環(huán)境初始化到云上的 ubuntu 中。

1、oh my zsh

圖10:oh my zsh.png
  • 1.首先需要在XX云中買一個(gè)機(jī)器。我買的是阿里云,最開始的系統(tǒng)模板選擇 ubuntu16,然后什么都不要裝。然后在本地用 ssh 登錄云主機(jī)。
  • 2.在本地電腦上 clone 一下我的這個(gè)庫,接下來要用到里面的兩個(gè)腳本文件。ubuntu初始化
  • 3.用 scp 命令將2中的兩個(gè)文件上傳到服務(wù)器上分別是:ubuntu_init.sh 和 ubuntu_init_oh-my-zsh.sh。例如:scp a.jpg root@47.106.145.211:/root/a.jpg,將本地本目錄的 a.jpg 文件上傳為云服務(wù)器上的/root/a.jpg文件。
  • 4.運(yùn)行ubuntu_init.sh,中間會(huì)讓你輸入密碼,最后會(huì)重啟服務(wù)器。
  • 5.等4中重啟服務(wù)器之后,登錄服務(wù)器然后運(yùn)行ubuntu_init_oh-my-zsh.sh。如此就大功告成了。最終效果如圖10,這個(gè)終端比 ubuntu 原生的好用多了,而且還支持各種定制的插件。
  • 6.忘了說了這個(gè)命令行是一個(gè)開源項(xiàng)目:oh my zsh,英語比較好的同學(xué)可以看原項(xiàng)目,來拓展自己的配置。

2、vim 配置

圖11:vim.png
  • 1.接下來就是 vim 的配置,其實(shí)我到現(xiàn)在也沒完全成功的把配置完全成功的把配置完成成功的轉(zhuǎn)移到 ubuntu 上面,所以大家看看就好。
  • 2.ubuntu初始化,這個(gè)倉庫里 .vimrc 是 vim 的配置文件。vim 插件管理,這個(gè)倉庫里是 vim 插件庫。
  • 3.這里其實(shí)就是為了 show 一下我的成果,對(duì)于初學(xué)者來說能學(xué)習(xí)的方面不多,對(duì)于老鳥來說也看不上我的配置。

3、docker配置

這兩周我也抽空學(xué)習(xí)了一下 docker,我的理解上 docker 就是一個(gè)方便打包重用超輕量虛擬機(jī)。所以我們后端也會(huì)用上這個(gè)技術(shù)以方便運(yùn)維。我也是剛學(xué)這東西,所以我就貼幾個(gè)我學(xué)習(xí)的網(wǎng)址吧!

五、尾巴

本篇文章是從零開始仿寫一個(gè)抖音App系列文章的第四篇,篇幅比較長(zhǎng)能看到這里的同學(xué)非常感謝你們對(duì)我的認(rèn)可。從決定寫這個(gè)系列的文章開始到現(xiàn)在已經(jīng)兩個(gè)多月了,我發(fā)現(xiàn)這兩個(gè)月我的成長(zhǎng)是非常迅速的,所以接下來我還會(huì)堅(jiān)持這樣寫下去。

不販賣焦慮,也不標(biāo)題黨。分享一些這個(gè)世界上有意思的事情。題材包括且不限于:科幻、科學(xué)、科技、互聯(lián)網(wǎng)、程序員、計(jì)算機(jī)編程。下面是我的微信公眾號(hào):世界上有意思的事,干貨多多等你來看。

世界上有意思的事

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