超詳細!高頻面試知識點總結(jié):面試官問我高并發(fā)服務模型哪家強绕娘?

面試中經(jīng)常會被問到高性能服務模型選擇對比脓规,以及如何提高服務性能和處理能力,這其中涉及操作系統(tǒng)軟件和計算機硬件知識险领,其實都是在考察面試者的基礎知識掌握程度侨舆,但如果沒準備的話容易一頭霧水,這次帶大家從頭到尾學習一遍舷暮,學完這一篇再也不怕面試官刨根問底了态罪!

任務類型

談高并發(fā)服務模型選擇之前噩茄,我們先來看下程序的的任務類型下面,程序任務類型一般分為 CPU 密集型任務和 IO 密集型任務,這兩種任務有各自的特點绩聘,對程序的要求是不一樣的需要分開對待沥割。

CPU密集型任務

一個程序任務大部分是計算類的,比如邏輯處理凿菩、數(shù)值比較和計算机杜,我們就稱它是 CPU 密集型任務或計算密集型任務。CPU 密集型任務的特點是要進行大量的計算衅谷,消耗 CPU 資源椒拗,比如計算圓周率、視頻編解碼這些靠的是 CPU 的運算能力获黔。

CPU 密集型任務雖然也可以用多任務完成蚀苛,但是任務越多,任務之間切換的時間就越多玷氏,CPU 執(zhí)行效率反而更低堵未,所以要最高效地利用 CPU,任務并行數(shù)應當?shù)扔?CPU 的核心數(shù)盏触,避免任務在 CPU 核之間頻繁切換渗蟹。

芯片線路

IO密集型任務

一個程序涉及到大量網(wǎng)絡块饺、磁盤等比較耗時的輸入輸出任務,就稱它是 IO 密集型任務雌芽,這類任務的特點是 CPU 消耗很少授艰,任務的大部分時間都在等待 IO 操作完成(因為 IO 的速度遠遠低于 CPU 和內(nèi)存的速度,不是一個數(shù)量級的)世落。

對于 IO 密集型任務想诅,任務越多 CPU 效率越高,但也不是無限的開啟多任務岛心,如果任務過多頻繁切換的開銷也不可忽視来破。常見的大部分程序都是執(zhí)行 IO 密集型任務,比如互聯(lián)網(wǎng)業(yè)務的 Web 服務忘古,數(shù)據(jù)庫操作等徘禁。

五彩的以太網(wǎng)口

服務模型

不管是 CPU 密集型任務還是 IO 密集型任務,要提高服務器處理能力髓堪,可以從軟件和硬件兩個層面來做文章送朱。

先說軟件層面,單個任務處理能力有限干旁,可以通過啟動多個功能完全相同的服務實例驶沼,借此來提高服務整體處理性能,多服務實例的實現(xiàn)主流的技術(shù)有三種:多進程争群、多線程回怜、多協(xié)程。當然除了用多實例的方式换薄,還有 IO 多路復用玉雾、異步 IO 等技術(shù),為了文章主題明確轻要,不在本文展開討論复旬。

服務模型哪家強

既然有三種技術(shù)實現(xiàn),那么你可能會問冲泥,在三個模型里選一個最好的來實現(xiàn)服務驹碍,該如何選擇一個適合的服務模型呢?

image

抱歉凡恍,小孩子才做選擇我全都要志秃!哈哈,開個玩笑咳焚。

答案是沒有最好洽损,服務模型選擇要結(jié)合自身服務處理的任務類型。任務類型就是我們上面說的 CPU 密集型和 IO 密集型革半,只有清楚的知道所處理業(yè)務的任務類型碑定,才能在上述服務模型中選擇其一或多種模型組合流码,來搭建適合你的高性能服務框架。

多進程服務模型

進程概念

程序是一些保存在磁盤上的指令的有序集合延刘,是靜態(tài)的漫试。進程是程序執(zhí)行的過程,包括了動態(tài)創(chuàng)建碘赖、調(diào)度和消亡的整個過程驾荣,進程是程序資源管理的最小單位

多進程模型

多進程模型是啟動多個服務進程普泡。原來由一個進程做的事播掷,當一個進程忙不過來,創(chuàng)建幾個功能一樣的進程來幫它一起干活撼班,人多力量大歧匈。

由于多進程地址空間不同,數(shù)據(jù)不能共享砰嘁,一個進程內(nèi)創(chuàng)建的變量在另一個進程是無法訪問件炉。操作系統(tǒng)看不下去了,憑什么同在一臺機器矮湘,彼此相愛的兩個進程不能說說話呢斟冕?

于是操作系統(tǒng)提供了各種系統(tǒng)調(diào)用,搭建起各個進程間通信的橋梁缅阳,這些方法統(tǒng)稱為進程間通信 IPC (IPC InterProcess Communication)

常見進程間通信方式

管道 Pipe

管道的實質(zhì)是一個內(nèi)核緩沖區(qū)磕蛇,進程以先進先出 FIFO 的方式從緩沖區(qū)存取數(shù)據(jù)。 是一種半雙工的通信方式券时,數(shù)據(jù)只能單向流動孤里,而且只能在具有親緣關(guān)系(父子進程間)的進程間通信伏伯。

管道工作原理

  1. 管道一端的進程順序的將數(shù)據(jù)寫入緩沖區(qū)橘洞,另一端的進程則順序的讀出數(shù)據(jù)。

  2. 緩沖區(qū)可以看做是一個循環(huán)隊列说搅,一個數(shù)據(jù)只能被讀一次炸枣,讀出來后在緩沖區(qū)就不復存在了。

  3. 當緩沖區(qū)為讀空或?qū)憹M弄唧,讀數(shù)據(jù)的進程或?qū)憯?shù)據(jù)進程進入等待隊列适肠。

  4. 空的緩沖區(qū)有新數(shù)據(jù)寫入,或者滿的緩沖區(qū)有數(shù)據(jù)讀出時候引,喚醒等待隊列中的進程繼續(xù)讀寫侯养。

管道圖解

命名管道 FIFO

上面介紹的管道也稱為匿名管道,只能用于親緣關(guān)系的進程間通信澄干。為了克服這個缺點逛揩,出現(xiàn)了有名管道 FIFO 柠傍。有名管道提供了一個路徑名與之關(guān)聯(lián),以文件形式存在于文件系統(tǒng)中辩稽,這樣即使不存在親緣關(guān)系的進程惧笛,只要可以訪問該路徑也能相互通信。

命名管道支持同一臺計算機的不同進程之間逞泄,可靠的患整、單向或雙向的數(shù)據(jù)通信。


FIFO圖解.png

信號 Signal

信號是Linux系統(tǒng)中用于進程間互相通信或者操作的一種機制喷众,信號可以在任何時候發(fā)給某一進程各谚,無需知道該進程的狀態(tài)。如果該進程當前不是執(zhí)行態(tài)到千,內(nèi)核會暫時保存信號嘲碧,當進程恢復執(zhí)行后傳遞給它。

如果一個信號被進程設置為阻塞父阻,則該信號的傳遞被延遲愈涩,直到其阻塞被取消是才被傳遞給進程。

信號在用戶空間進程和內(nèi)核之間直接交互加矛,內(nèi)核可以利用信號來通知用戶空間的進程發(fā)生了哪些系統(tǒng)事件履婉,信號事件主要有兩個來源:

  • 硬件來源:用戶按鍵輸入Ctrl+C退出、硬件異常如無效的存儲訪問等斟览。
  • 軟件終止:終止進程信號毁腿、其他進程調(diào)用 kill 函數(shù)、軟件異常產(chǎn)生信號苛茂。

消息隊列 Message Queue

消息隊列是存放在內(nèi)核中的消息鏈表已烤,每個消息隊列由消息隊列標識符表示, 只有在內(nèi)核重啟或主動刪除時妓羊,該消息隊列才會被刪除胯究。

消息隊列是由消息的鏈表,存放在內(nèi)核中并由消息隊列標識符標識躁绸。消息隊列克服了信號傳遞信息少裕循、管道只能承載無格式字節(jié)流以及緩沖區(qū)大小受限等缺點。 另外净刮,某個進程往一個消息隊列寫入消息之前剥哑,并不需要另外讀進程在該隊列上等待消息的到達。


消息隊列圖解

共享內(nèi)存 Shared memory

共享內(nèi)存是一個進程把地址空間的一段淹父,映射到能被其他進程所訪問的內(nèi)存株婴,一個進程創(chuàng)建、多個進程可訪問暑认,進程就可以直接讀寫這一塊內(nèi)存而不需要進行數(shù)據(jù)的拷貝困介,從而大大提高效率揪垄。

共享內(nèi)存使得多個進程可以可以直接讀寫同一塊內(nèi)存空間,是最快的可用 IPC 形式逻翁,是針對其他通信機制運行效率較低而設計的饥努。共享內(nèi)存往往與其他通信機制,如信號量配合使用八回,來實現(xiàn)進程間的同步和互斥通信酷愧。

共享內(nèi)存

套接字 Socket

套接字你可能沒聽過這個名字,但絕對是接觸的最多的一種進程間通信方式缠诅。因為我們熟悉的 TCP/IP 協(xié)議棧溶浴,也是建立在 socket 通信之上,TCP/IP 構(gòu)建起了當前的互聯(lián)網(wǎng)通信網(wǎng)絡管引。

它是一種通信機制士败,憑借這種機制,既可以在本機進程間通信褥伴,也可以跨網(wǎng)絡通過谅将,因為,套接字通過網(wǎng)絡接口將數(shù)據(jù)發(fā)送到本機的不同進程或遠程計算機的進程重慢。

socket套接字

多線程服務模型

線程概念

線程是操作操作系統(tǒng)能夠進行運算調(diào)度的最小單位饥臂。線程被包含在進程之中,是進程中的實際運作單位似踱,一個進程內(nèi)可以包含多個線程隅熙,線程是資源調(diào)度的最小單位。

進程線程關(guān)系

多線程模型

啟動多個相同功能的進程能提高服務處理能力核芽,但由于各個進程的地址空間相互隔離囚戚,通信不便。

于是轧简,多線程服務模型出場驰坊。通過前面的學習我們知道,一個進程內(nèi)的多個線程可以共享進程的全部系統(tǒng)資源吉懊。進程內(nèi)創(chuàng)建的多個線程都可以訪問進程內(nèi)的全局變量庐橙。

當然沒有免費的午餐,線程雖然能方便的訪問進程資源借嗽,但也帶來了額外的問題。比如多線程訪公共資源帶來的同步與互斥問題转培,不同線程訪問資源的先后順序會相互影響恶导,如果不做好同步和互斥會產(chǎn)生預期之外的結(jié)果,甚至死鎖浸须。

什么是多線程同步

多線程同步是線程之間的一種直接制約關(guān)系惨寿,一個線程的執(zhí)行依賴另一個線程的通知邦泄,當它沒有得到另一個線程的通知時必須等待,直到消息到達時才被喚醒裂垦,即有很強的執(zhí)行先后關(guān)系顺囊。

比如你搭建了一個商城服務。這個服務的下單流程是這樣的:第一步必須要先挑選商品加入購物車蕉拢,第二步才能結(jié)賬計算訂單金額特碳,假設這兩個步驟的操作分別由兩個線程去完成,則這兩個線程的操作順序很重要晕换,必須是先下單再結(jié)賬午乓,這就是線程同步。


購物車

什么是多線程互斥

多線程互斥指的是多線程對資源訪問的排他性闸准。所謂排他性益愈,就是當有多個線程都要使用某一共享資源時,任何時刻最多只允許一個線程獲得對這個共享資源的使用權(quán)夷家,當共享資源被其中一個線程占有時蒸其,其他未獲得資源的線程必須等待,直到占用資源的線程釋放資源库快。

打個比方枣接,你們班只有一臺投影儀,當一個同學在上面放電影的時候缺谴,如果老師進來上課要用這個投影儀但惶,那就只能由這個同學放棄投影儀的使用權(quán),交給老師上課投影使用湿蛔,對膀曾,教室里唯一的投影儀是共享資源,具有排他性阳啥,老師和學生比作是兩個線程的話添谊,那這兩個線程是互斥的訪問共享資源(投影儀)。

投影儀

多線程同步和互斥方法

Linux 系統(tǒng)提供以下幾種方法來解決多線程的同步和互斥問題察迟,分別是:互斥鎖斩狱、條件變量、讀寫鎖扎瓶、自旋鎖所踊、條件變量。

互斥鎖(同步)

互斥鎖的作用是對臨界區(qū)加以保護概荷,以使任意時刻只有一個線程能夠執(zhí)行臨界區(qū)的代碼秕岛,實現(xiàn)了多線程對臨界資源的互斥訪問。

互斥鎖接口函數(shù):

互斥鎖api

條件變量(同步)

條件變量是用來等待而不是用來上鎖的。條件變量用來自動阻塞一個線程继薛,直到某特殊情況發(fā)生為止修壕。適合多個線程等待某個條件的發(fā)生,不使用條件變量遏考,那么每個線程就不斷嘗試互斥鎖并檢測條件是否發(fā)生慈鸠,浪費系統(tǒng)資源

通常條件變量和互斥鎖同時使用灌具。條件的檢測是在互斥鎖的保護下進行的青团。如果一個條件為假,一個線程自動阻塞稽亏,并釋放等待狀態(tài)改變的互斥鎖壶冒。如果另一個線程改變了條件,它發(fā)信號給關(guān)聯(lián)的條件變量截歉,喚醒一個或多個等待它的線程胖腾,重新獲得互斥鎖,重新評價條件瘪松,可以用來實現(xiàn)線程間的同步咸作。

條件變量系統(tǒng) API 如下:

條件變量API

讀寫鎖(同步)

互斥量要么是加鎖狀態(tài),要么是不加鎖狀態(tài)宵睦,而且一次只有一個線程對其進行加鎖记罚。讀寫鎖可以有3種狀態(tài):讀加鎖狀態(tài)、寫加鎖狀態(tài)和不加鎖狀態(tài)壳嚎。

一次只有一個線程可以占有寫模式讀寫鎖桐智,但是可以有多個線程同時占有讀模式的讀寫鎖。因此烟馅,讀寫鎖適合于對數(shù)據(jù)結(jié)構(gòu)的讀次數(shù)比寫次數(shù)多得多的情況说庭,且讀寫鎖比互斥量具有更高的并行性。

讀寫鎖加鎖規(guī)則

1:如果某線程申請了讀鎖郑趁,其它線程可以再申請讀鎖刊驴,但不能申請寫鎖;

2:如果某線程申請了寫鎖寡润,其它線程不能申請讀鎖捆憎,也不能申請寫鎖。

讀寫鎖系統(tǒng) API

讀寫鎖API

自旋鎖(同步)

互斥鎖得不到鎖時梭纹,線程會進入休眠躲惰,引發(fā)任務上下文切換,任務切換涉及一系列耗時的操作栗柒,因此用互斥鎖一旦遇到阻塞切換代價是十分昂貴的礁扮。

而自旋鎖阻塞后不會引發(fā)上下文切換知举,當鎖被其他線程占有時瞬沦,獲取鎖的線程便會進入自旋太伊,不斷檢測自旋鎖的狀態(tài),直到得到鎖逛钻,所謂的自旋就是循環(huán)等待的意思僚焦。

自旋鎖在用戶態(tài)使用的比較少,在內(nèi)核使用的比較多曙痘。自旋鎖適用于臨界區(qū)代碼比較短芳悲,鎖的持有時間比較短的場景,否則會讓其他線程一直等待造成饑餓現(xiàn)象边坤。

自旋鎖 API 接口

自旋鎖API

信號量(同步與互斥)

信號量本質(zhì)上是一個非負的整數(shù)計數(shù)器名扛,它被用來控制對公共資源的訪問。

信號量是一個特殊類型的變量茧痒,它可以被增加或者減少肮韧。可根據(jù)操作信號量值的結(jié)果判斷是否對公共資源具有訪問的權(quán)限旺订,當信號量值大于 0 時弄企,則可以訪問,否則將阻塞区拳。但對其的訪問被保證是原子操作拘领,即使在一個多線程程序中也是如此。

信號量類型:

  • 二進制信號量樱调,它只有0和1兩種取值约素。適用于臨界代碼每次只能被一個執(zhí)行線程運行,就要用到二進制信號量笆凌。

  • 計數(shù)信號量圣猎。它可以有更大的取值范圍,適用于臨界代碼允許有限數(shù)目的線程執(zhí)行菩颖,就需要用到計數(shù)信號量样漆。

信號量 API

信號量API

協(xié)程服務模型

什么是協(xié)程

什么是協(xié)程呢?協(xié)程 Coroutines 是一種比線程更加輕量級的微線程晦闰。類比一個進程可以擁有多個線程放祟,一個線程也可以擁有多個協(xié)程,因此協(xié)程又稱微線程和纖程呻右。

協(xié)程圖解

可以粗略的把協(xié)程理解成子程序調(diào)用跪妥,每個子程序都可以在一個單獨的協(xié)程內(nèi)執(zhí)行。

協(xié)程子程序模型

協(xié)程服務模型

為了說明什么是協(xié)程模型声滥,先用多線程下的生產(chǎn)者消費者模型舉個栗子眉撵。

啟動兩個線程分別執(zhí)行兩個函數(shù) Do_some_IODo_some_process 侦香,第一個做耗時的 IO 處理操作,第二個對 IO 操作結(jié)果做快速的處理計算工作纽疟。偽代碼如下:

函數(shù)偽代碼

多線程執(zhí)行過程是這樣的:

  1. 生產(chǎn)者線程先調(diào)用函數(shù) Do_some_IO 做比較耗時的 IO 操作罐韩,比如從網(wǎng)絡套接字中讀取數(shù)據(jù)這類操作。

  2. 在生產(chǎn)者線程執(zhí)行 Do_some_IO 完成數(shù)據(jù)讀取之前污朽,消費者線程要阻塞等待散吵。

  3. 在消費者線程執(zhí)行 Do_some_process 完成數(shù)據(jù)處理完成之前,生產(chǎn)者線程要阻塞等待蟆肆。

  4. 在消費者線程執(zhí)行 Do_some_process 完成數(shù)據(jù)處理完成之后矾睦,要通知生成者線程繼續(xù) Do_some_IO

    多線程執(zhí)行模型.png

可以看到,多線程模型為了保證各個線程并行工作炎功,需要額外做很多線程間的同步和通知工作枚冗,而且線程頻繁的在阻塞和喚醒間切換,我們知道 Linux 下線程是輕量級線程 LWP 蛇损,每次線程切換涉及用戶態(tài)和內(nèi)核態(tài)的切換赁温,還是很消耗性能的。

同樣的場景在協(xié)程模型里是怎么處理的呢州藕?還是用前面的例子束世,說明協(xié)程模型的執(zhí)行流程。

Do_some_IO()       // IO處理協(xié)程
Do_some_process()  // 計算處理協(xié)程
  1. 分配生產(chǎn)者協(xié)程執(zhí)行 Do_some_IO 做 IO 處理操作床玻,分配消費者協(xié)程執(zhí)行 Do_some_process 計算處理操作毁涉。
  2. 在生產(chǎn)者協(xié)程工作期間,消費者協(xié)程保持等待锈死。
  3. 當生產(chǎn)者協(xié)程完成 IO 處理贫堰,返回處理結(jié)果給消費者,并把程序執(zhí)行權(quán)限交給消費者協(xié)程向下執(zhí)行待牵。
協(xié)程執(zhí)行時間線.png

協(xié)程優(yōu)勢

  • 由于協(xié)程在線程內(nèi)實現(xiàn)其屏,因此始終都是一個線程操作共享資源,所以不存在多線程搶占資源和資源同步問題缨该。

  • 生產(chǎn)者協(xié)程和消費者協(xié)程奄妨,互相配合協(xié)作完成工作唯竹,而不是相互搶占,而且協(xié)程創(chuàng)建和切換的開銷比線程小得多。

硬件提升性能

前面講的多線程斤吐、多進程葫录、協(xié)程都還只是軟件層面的提高服務處理能力挺邀。真正硬核的是從硬件層面提高處理能力蝠嘉,增加 CPU 物理核心數(shù)目,當然硬件都是有成本的荚守,所以只有軟件層面已經(jīng)充分榨干性能才會考慮增加硬件珍德。

不過练般,老板有錢買最好最貴的服務器另說,這是人民幣玩家和窮逼玩家的區(qū)別了锈候,軟件工程師留下了貧困的淚水薄料。


增加機器核心數(shù)

CPU領域有一條摩爾定律:大概 18 個月會將芯片的性能提高一倍。現(xiàn)在這個定律變的越來越難以突破晴及,CPU 晶體管密度工作頻率很難再提高都办,轉(zhuǎn)而通過增加 CPU 核心數(shù)目的方式提高處理器性能嫡锌。

cpu

目前商用服務器架構(gòu)基本都是多核處理器虑稼,多核的處理器能夠真正做到程序并行運行,處理效率大幅度提升势木,那該如何查看 CPU 核心數(shù)目呢蛛倦?

對于 Windows 操作系統(tǒng),打開任務管理器啦桌,通過界面的「內(nèi)核」和「邏輯處理器」能看到溯壶。

windows 查看核心

查看 cpu 核心數(shù)

對于 Linux 操作系統(tǒng),通過下面 2 種方式查看 CPU 核心相關(guān)信息甫男。

1. 通過cpuinfo文件查看

使用cat /proc/cpuinfo查看 cpu 核心信息且改,如下兩個信息:

  • processor,指明第幾個cpu處理器
  • cpu cores板驳,指明每個處理器的核心數(shù)

cpuinfo 輸出示例:

cpuinfo

2. 通過編程接口查看

除了上面以文件的形式查看 cpu 核心信息之外又跛,系統(tǒng)還提供了編程接口可以查詢,系統(tǒng) API 如下若治。

查看核數(shù)API

CPU親和性

CPU 親和性是綁定某一進程或線程到特定的 CPU 或 CPU 集合慨蓝,從而使得該進程或線程只能被調(diào)度運行在綁定的 CPU或 CPU 集合上。

為什么要設置 CPU 親和性綁定 CPU 呢端幼?理論上進程上一次運行后的上下文信息會保留在 CPU 的緩存中礼烈,如果下一次仍然將該進程調(diào)度到同一個 CPU 上,就能避免緩存未命中對 CPU 處理性能的影響婆跑,從而使得進程的運行更加高效此熬。

假如某些進程或線程是 CPU 密集型的,不希望被頻繁調(diào)度滑进,又或者你有其他特殊需求犀忱,不希望進程或線程被調(diào)度在不同 CPU 之間頻繁切換,則可以將該進程或線程綁定到特定的 CPU 上 郊供,可以在特定場景下優(yōu)化程序性能峡碉。

綁定進程

在多進程模型中,綁定進程到特定的核心驮审,下面是綁定進程的系統(tǒng) API


設置進程親和性

綁定線程

在多線程模型中鲫寄,綁定線程到特定的核心吉执,下面是綁定線程的系統(tǒng) API

設置線程親和性

總總結(jié)結(jié)

本文從程序任務類型出發(fā),區(qū)分任務為 CPU 密集型和 IO 密集型兩大類地来。接著分別說明提高基于這兩類任務的服務性能方法戳玫,分為軟件層面的方法和硬件層面的方法,其中軟件層面主要講述利用多進程未斑、多線程以及協(xié)程模型咕宿,當然現(xiàn)有的技術(shù)還有 IO 多路復用、異步 IO 蜡秽、池化技術(shù)等方案府阀。講到多線程和多進程,順勢說明了進程間通信和線程間同步互斥技術(shù)芽突。

第二部分试浙,講解了從硬件層面提高服務性能:提高機器核心數(shù),并教你如何查看 CPU 核心數(shù)的方法寞蚌。最后田巴,還可以通過軟硬結(jié)合的方式,把硬件核心綁定到指定進程或者線程執(zhí)行挟秤,最大程度的利用 CPU 性能壹哺。

希望通過本文的學習,讀者對高性能服務模型有個初步的了解艘刚,并能對服務優(yōu)化的方法和利弊舉例一二管宵,就是本文的價值所在。

再聊兩句(求個三連)

感謝各位的閱讀昔脯,文章的目的是分享對知識的理解啄糙,技術(shù)類文章我都會反復求證以求最大程度保證準確性,若文中出現(xiàn)明顯紕漏也歡迎指出云稚,我們一起在探討中學習隧饼。

如果覺得文章寫的還行,對你有所幫助静陈,不要白票 lemon燕雁,動動手指點個「在看」或「分享」是對我持續(xù)創(chuàng)作的最大支持。

今天的技術(shù)分享就到這里鲸拥,我們下期再見拐格。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市刑赶,隨后出現(xiàn)的幾起案子捏浊,更是在濱河造成了極大的恐慌,老刑警劉巖撞叨,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件金踪,死亡現(xiàn)場離奇詭異浊洞,居然都是意外死亡,警方通過查閱死者的電腦和手機胡岔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門法希,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人靶瘸,你說我怎么就攤上這事苫亦。” “怎么了怨咪?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵屋剑,是天一觀的道長。 經(jīng)常有香客問我惊暴,道長饼丘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任辽话,我火速辦了婚禮,結(jié)果婚禮上卫病,老公的妹妹穿的比我還像新娘油啤。我一直安慰自己,他們只是感情好蟀苛,可當我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布益咬。 她就那樣靜靜地躺著,像睡著了一般帜平。 火紅的嫁衣襯著肌膚如雪幽告。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天裆甩,我揣著相機與錄音冗锁,去河邊找鬼。 笑死嗤栓,一個胖子當著我的面吹牛冻河,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播茉帅,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼叨叙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了堪澎?” 一聲冷哼從身側(cè)響起擂错,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎樱蛤,沒想到半個月后钮呀,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桃犬,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年行楞,在試婚紗的時候發(fā)現(xiàn)自己被綠了攒暇。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡子房,死狀恐怖形用,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情证杭,我是刑警寧澤田度,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站解愤,受9級特大地震影響镇饺,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜送讲,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一奸笤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧哼鬓,春花似錦监右、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至称簿,卻和暖如春扣癣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背憨降。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工父虑, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人券册。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓频轿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親烁焙。 傳聞我的和親對象是個殘疾皇子航邢,可洞房花燭夜當晚...
    茶點故事閱讀 45,922評論 2 361