基于時間線的Feed流后臺系統(tǒng)設(shè)計

本文將總結(jié)一下常用的基于時間線Feed流的后臺存儲設(shè)計方案门岔。結(jié)合具體的業(yè)務(wù)場景库车,講述一下根據(jù)實際需求睁宰,在基本設(shè)計思路上做一些靈活運用。

01

背景介紹

Feed流產(chǎn)品在我們手機APP中幾乎無處不在嘱么,常見的Feed流比如微信朋友圈狮含、新浪微博、今日頭條等曼振。對Feed流的定義几迄,可以簡單理解為只要大拇指不停地往下劃手機屏幕,就有一條條的信息不斷涌現(xiàn)出來冰评。就像給牲畜喂飼料一樣映胁,只要它吃光了就要不斷再往里加,故此得名Feed(飼養(yǎng))甲雅。

大多數(shù)Feed流產(chǎn)品都包含兩種Feed流解孙,一種是基于算法推薦坑填,另一種是基于關(guān)注(好友關(guān)系)。例如下圖中的微博和知乎弛姜,頂欄的頁卡都包含“關(guān)注”和“推薦”這兩種脐瑰。兩種Feed流背后用到的技術(shù)差別會比較大。本文將重點探索一下“關(guān)注”頁卡的后臺實現(xiàn)方式廷臼。


image.png

image.png

圖片來源:知乎

不同于“推薦”頁卡那種千人前面算法推薦的方式苍在,通常“關(guān)注”頁卡所展示的內(nèi)容先后順序都有固定的規(guī)則中剩,最常見的規(guī)則是基于時間線來排序忌穿,也就是展示“我關(guān)注的人所發(fā)的帖子抒寂,根據(jù)發(fā)帖時間從晚到早依次排列”结啼。

02

Feed流實現(xiàn)方案介紹

方案1——讀擴散

讀擴散也稱為拉模式,這應(yīng)該是最符合我們直覺的一種實現(xiàn)方式屈芜。如下圖:


image.png

每一個內(nèi)容發(fā)布者都有一個自己的發(fā)件箱(“我發(fā)布的內(nèi)容”)郊愧,每當(dāng)我們發(fā)出一個新帖子,都存入自己的發(fā)件箱中井佑。當(dāng)我們的粉絲來閱讀時属铁,系統(tǒng)首先需要拿到粉絲關(guān)注的所有人,然后遍歷所有發(fā)布者的發(fā)件箱躬翁,取出他們所發(fā)布的帖子焦蘑,然后依據(jù)發(fā)布時間排序,展示給閱讀者盒发。

這種設(shè)計例嘱,閱讀者讀一次Feed流,后臺會擴散為N次讀操作(N等于關(guān)注的人數(shù))以及一次聚合操作宁舰,因此稱為讀擴散拼卵。每次讀Feed流相當(dāng)于去關(guān)注者的收件箱主動拉取帖子,因此也得名拉模式蛮艰。

這種模式的好處是底層存儲簡單腋腮,沒有空間浪費。壞處是每次讀操作會非常重壤蚜,操作非常多即寡。設(shè)想一下如果我關(guān)注的人數(shù)非常多,遍歷一遍我所關(guān)注的所有人袜刷,并且再聚合一下聪富,這個系統(tǒng)開銷會非常大,時延上可能達到無法忍受的地步水泉。因此讀擴散主要適用系統(tǒng)中閱讀者關(guān)注的人沒那么多善涨,并且刷Feed流并不頻繁的場景窒盐。

拉模式還有一個比較大的缺點就是分頁不方便,我們刷微博或朋友圈钢拧,肯定是隨著大拇指在屏幕不斷劃動蟹漓,內(nèi)容一頁一頁的從后臺拉取。如果不做其他優(yōu)化源内,只采用實時聚合的方式葡粒,下滑到比較靠后的頁碼時會非常麻煩。

方案2——寫擴散

據(jù)統(tǒng)計膜钓,大多數(shù)Feed流產(chǎn)品的讀寫比大概在100:1嗽交,也就是說大部分情況都是刷Feed流看別人發(fā)的朋友圈和微博,只有很少情況是自己親自發(fā)一條朋友圈或微博給別人看颂斜。因此夫壁,讀擴散那種很重的讀邏輯并不適合大多數(shù)場景。我們寧愿讓發(fā)帖的過程復(fù)雜一些沃疮,也不愿影響用戶讀Feed流的體驗盒让,因此稍微改造一下前面方案就有了寫擴散。寫擴散也稱為推模式司蔬,這種模式會對拉模式的一些缺點做改進邑茄。如下圖:


image.png

系統(tǒng)中每個用戶除了有發(fā)件箱,也會有自己的收件箱俊啼。當(dāng)發(fā)布者發(fā)表一篇帖子的時候肺缕,除了往自己發(fā)件箱記錄一下之外,還會遍歷發(fā)布者的所有粉絲授帕,往這些粉絲的收件箱也投放一份相同內(nèi)容同木。這樣閱讀者來讀Feed流時,直接從自己的收件箱讀取即可豪墅。

這種設(shè)計泉手,每次發(fā)表帖子,都會擴散為M次寫操作(M等于自己的粉絲數(shù))偶器,因此成為寫擴散斩萌。每篇帖子都會主動推送到所有粉絲的收件箱,因此也得名推模式屏轰。

這種模式可想而知颊郎,發(fā)一篇帖子,背后會涉及到很多次的寫操作霎苗。通常為了發(fā)帖人的用戶體驗姆吭,當(dāng)發(fā)布的帖子寫到自己發(fā)件箱時,就可以返回發(fā)布成功唁盏。后臺另外起一個異步任務(wù)内狸,不慌不忙地往粉絲收件箱投遞帖子即可检眯。寫擴散的好處在于通過數(shù)據(jù)冗余(一篇帖子會被存儲M份副本),提升了閱讀者的用戶體驗昆淡。通常適當(dāng)?shù)臄?shù)據(jù)冗余不是什么問題锰瘸,但是到了微博明星這里,完全行不通昂灵。比如目前微博粉絲量Top2的謝娜與何炅避凝,兩個人微博粉絲過億。


image.png

圖片來源:新浪微博

設(shè)想一下眨补,如果單純采用推模式管削,那每次謝娜何炅發(fā)一條微博,微博后臺都要地震一次撑螺。一篇微博導(dǎo)致后臺上億次寫操作含思,這顯然是不可行的。另外由于寫擴散是異步操作实蓬,寫的太慢會導(dǎo)致帖子發(fā)出去半天茸俭,有些粉絲依然沒能看見吊履,這種體驗也不太好安皱。

通常寫擴散適用于好友量不大的情況,據(jù)悉微信朋友圈正是寫擴散模式艇炎。每一名微信用戶的好友上限為5000人酌伊,也就是說你發(fā)一條朋友圈最多也就擴散到5000次寫操作,如果異步任務(wù)性能好一些缀踪,完全沒有問題居砖。

方案3——讀寫混合模式

讀寫混合也可以稱作推拉結(jié)合。這種方式可以兼具讀擴散和寫擴散的優(yōu)點驴娃。我們首先來總結(jié)一下讀擴散和寫擴散的優(yōu)缺點:


截屏2021-10-06 下午11.24.30.png

仔細比較一下讀擴散與寫擴散的優(yōu)缺點奏候,不難發(fā)現(xiàn)兩者的適用場景是互補的。因此在設(shè)計后臺存儲的時候唇敞,我們?nèi)绻軌騾^(qū)分一下場景蔗草,在不同場景下選擇最適合的方案,并且動態(tài)調(diào)整策略疆柔,就實現(xiàn)了讀寫混合模式咒精。如下圖:


image.png

當(dāng)何炅這種粉絲量超大的人發(fā)帖時,將帖子寫入何炅的發(fā)件箱旷档,另外提取出來何炅粉絲當(dāng)中比較活躍的那一批(這已經(jīng)可以篩掉大部分了)模叙,將何炅的帖子寫入他們的收件箱。當(dāng)一個粉絲量很小的路人甲發(fā)帖時鞋屈,采用寫擴散方式范咨,遍歷他的所有粉絲并將帖子寫入粉絲收件箱故觅。

對于那些活躍用戶登錄刷Feed流時,他直接從自己的收件箱讀取帖子即可渠啊,保證了活躍用戶的體驗逻卖。當(dāng)一個非活躍的用戶突然登錄刷Feed流時,我們一方面需要讀他的收件箱昭抒,另一方面需要遍歷他所關(guān)注的大V用戶的發(fā)件箱提取帖子评也,并且做一下聚合展示。在展示完后灭返,系統(tǒng)還需要有個任務(wù)來判斷是否有必要將該用戶升級為活躍用戶盗迟。因為有讀擴散的場景存在,因此即使是混合模式熙含,每個閱讀者所能關(guān)注的人數(shù)也要設(shè)置上限罚缕,例如新浪微博限制每個賬號最多可以關(guān)注2000人。如果不設(shè)上限怎静,設(shè)想一下有一位用戶把微博所有賬號全部關(guān)注了邮弹,那他打開關(guān)注列表會讀取到微博全站所有帖子,一旦出現(xiàn)讀擴散蚓聘,系統(tǒng)必然崩潰腌乡;即使是寫擴散,他的收件箱也無法容納這么多的微博夜牡。

讀寫混合模式下与纽,系統(tǒng)需要做兩個判斷。一個是哪些用戶屬于大V塘装,我們可以將粉絲量作為一個判斷指標(biāo)急迂。另一個是哪些用戶屬于活躍粉絲,這個判斷標(biāo)準(zhǔn)可以是最近一次登錄時間等蹦肴。這兩處判斷標(biāo)準(zhǔn)就需要在系統(tǒng)發(fā)展過程中動態(tài)地識別和調(diào)整僚碎,沒有固定公式了。

可以看出讀寫結(jié)合模式綜合了兩種模式的優(yōu)點阴幌,屬于最佳方案勺阐。然而他的缺點是系統(tǒng)機制非常復(fù)雜,給程序員帶來無數(shù)煩惱裂七。通常在項目初期皆看,只有一兩個開發(fā)人員,用戶規(guī)模也很小的時候背零,一步到位地采用這種混合模式還是要慎重腰吟,容易出bug。當(dāng)項目規(guī)模逐漸發(fā)展到新浪微博的水平,有一個大團隊專門來做Feed流時毛雇,讀寫混合模式才是必須的嫉称。

Feed流中的分頁問題

前文已經(jīng)敘述了基于時間線的Feed流常見設(shè)計方案,但實操起來會比理論要麻煩許多灵疮。接下來專門討論一個困難點——Feed流的分頁织阅。不管是讀擴散還是寫擴散,F(xiàn)eed流本質(zhì)上是一個動態(tài)列表震捣,列表內(nèi)容會隨著時間不斷變化荔棉。傳統(tǒng)的前端分頁參數(shù)使用page_size和page_num,分表表示每頁幾條蒿赢,以及當(dāng)前是第幾頁润樱。對于一個動態(tài)列表會有如下問題:


image.png

在T1時刻讀取了第一頁,T2時刻有人新發(fā)表了“內(nèi)容11”羡棵,在T3時刻如果來拉取第二頁壹若,會導(dǎo)致錯位出現(xiàn),“內(nèi)容6”在第一頁和第二頁都被返回了皂冰。事實上店展,但凡兩頁之間出現(xiàn)內(nèi)容的添加或刪除,都會導(dǎo)致錯位問題秃流。

為了解決這一問題赂蕴,通常Feed流的分頁入?yún)⒉粫褂胮age_size和page_num,而是使用last_id來記錄上一頁最后一條內(nèi)容的id剔应。前端讀取下一頁的時候睡腿,必須將last_id作為入?yún)ⅲ笈_直接找到last_id對應(yīng)數(shù)據(jù)峻贮,再往后偏移page_size條數(shù)據(jù),返回給前端应闯,這樣就避免了錯位問題纤控。如下圖:


image.png

采用last_id的方案有一個重要條件,就是last_id本身這條數(shù)據(jù)不可以被硬刪除碉纺。設(shè)想一下上圖中T1時刻返回5條數(shù)據(jù)船万,last_id為內(nèi)容6;T2時刻內(nèi)容6被發(fā)布者刪除骨田;那么T3時刻再來請求第二頁耿导,我們根本找不到last_id對應(yīng)的數(shù)據(jù)了,也就無法確認(rèn)分頁偏移量态贤。通常碰到刪除的場景舱呻,我們采用軟刪除方式,只是在內(nèi)容上置一個標(biāo)志位,表示內(nèi)容已刪除箱吕。由于已經(jīng)刪除的內(nèi)容不應(yīng)該再返回給前端芥驳,因此軟刪除模式下,找到last_id并往后偏移page_size條茬高,如果其中有被刪除的數(shù)據(jù)會導(dǎo)致獲得足夠的數(shù)據(jù)條數(shù)給前端兆旬。這里一個解決方案是找不夠繼續(xù)再往下找,另一種方案是與前端協(xié)商怎栽,允許返回條數(shù)少于page_size條丽猬,page_size只是個建議值。甚至大家約定好了以后熏瞄,可以不要page_size參數(shù)宝鼓。

03

實際業(yè)務(wù)應(yīng)用

業(yè)務(wù)需求

文章最后結(jié)合我們自身業(yè)務(wù),介紹一下實際業(yè)務(wù)場景中碰到的一個非常特殊的Feed流設(shè)計方案巴刻。直享直播是一款直播帶貨工具愚铡,主播可以創(chuàng)建一場未來時刻的直播,到時間后開播賣貨胡陪,直播結(jié)束后沥寥,主播的粉絲可以查看直播回放。這樣柠座,每個直播場次就有三種狀態(tài)——預(yù)告中(創(chuàng)建一場直播但還未開播)邑雅、直播中、回放妈经。作為觀眾淮野,我可以關(guān)注多位主播,這樣從粉絲視角來看吹泡,也會有個直播場次的Feed流頁面骤星。這個Feed流最特殊的地方在于它的Feed流排序規(guī)則。


image.png

Feed流排序規(guī)則:

1.我關(guān)注的所有主播爆哑,正在直播中的場次排在最前洞难;預(yù)告中的場次排中間;回放場次排最后
2.多場次都在直播中的揭朝,按開播時間從晚到早排序
3.多場次都在預(yù)告中的队贱,按預(yù)計開播時間從早到晚排序
4.多場次都在回放的,按直播結(jié)束時間從晚到早排序

04

問題分析
本需求最復(fù)雜的點在于Feed流內(nèi)容融入的“狀態(tài)”因素潭袱,狀態(tài)的轉(zhuǎn)變會直接導(dǎo)致Feed流順序不同柱嫌。為了更清晰解釋一下對排序的影響,我們可以用下圖詳細說明:


image.png

圖中展示了4個主播的5個直播場次屯换,作為觀眾编丘,當(dāng)我在T1時刻打開頁面,看到的順序是場次3在最上方,其余場次均在預(yù)告狀態(tài)瘪吏,按照預(yù)計開播時間從早到晚展示癣防。當(dāng)我在T2時刻打開頁面,場次5在最上方掌眠,其余有三場在預(yù)告狀態(tài)排在中間蕾盯,場次3已經(jīng)結(jié)束了所以排在最后。以此類推蓝丙,直到所有直播都結(jié)束级遭,所有場次最終的狀態(tài)都會變?yōu)榛胤拧?/p>

這里需要注意一點,如果我在T1時刻打開第一頁渺尘,然后盯著頁面不動挫鸽,一直盯到T4時刻再下劃到第二頁,這時上一頁的last_id鸥跟,即分頁偏移量很有可能因為直播狀態(tài)變化而不知道飛到了什么位置丢郊,這會導(dǎo)致嚴(yán)重的錯位問題,以及直播狀態(tài)展示不統(tǒng)一的問題(第一頁展示的是T1時刻的直播狀態(tài)医咨,第二頁展示的是T4時刻的直播狀態(tài))枫匾。

05

解決方案

直播系統(tǒng)是個單向關(guān)系鏈,和微博有些類似拟淮,每個觀眾會關(guān)注少量主播干茉,每個主播會可能有非常多的關(guān)注者。由于有狀態(tài)變化的存在很泊,寫擴散幾乎無法實現(xiàn)角虫。因為如果采用寫擴散的方式,每次主播創(chuàng)建直播委造、直播開播戳鹅、直播結(jié)束這三個事件發(fā)生時導(dǎo)致的場次狀態(tài)變化,會擴散為非常多次的寫操作争涌,不僅操作復(fù)雜粉楚,時延上也無法接受。微博之所以可以寫擴散亮垫,就是因為一篇帖子發(fā)出后,這篇帖子就不會再有任何影響排序的狀態(tài)轉(zhuǎn)變伟骨。在我們場景中饮潦,“預(yù)告中”與“直播中”是兩個中間態(tài),而“回放”狀態(tài)才是所有直播的最終歸宿携狭,一旦進入回放继蜡,這場直播也就不會再有狀態(tài)轉(zhuǎn)變。因此“直播中”與“預(yù)告中”狀態(tài)可以采用讀擴散方式,“回放”狀態(tài)采取寫擴散方式稀并。

最終的方案如下圖所示:


image.png

會影響直播狀態(tài)的三種事件(創(chuàng)建直播仅颇、開播、結(jié)束直播)全部采用監(jiān)聽隊列異步處理碘举。我們?yōu)槊恳晃恢鞑ゾS護一個直播中+預(yù)告中狀態(tài)的優(yōu)先級隊列忘瓦。每當(dāng)監(jiān)聽到有主播創(chuàng)建直播時,將直播場次加入隊列中引颈,得分為開播的時間戳的相反數(shù)(負(fù)數(shù))耕皮。每當(dāng)監(jiān)聽到有主播開播時,把這場直播在隊列中的得分修改為開播時間(正數(shù))蝙场。每當(dāng)監(jiān)聽到有主播結(jié)束直播凌停,則異步地將播放信息投遞到每個觀眾的回放隊列中。

這里有一個小技巧售滤,前文提到罚拟,直播中狀態(tài)按照開播時間從大到小排序,而預(yù)告中狀態(tài)則按照開播時間從小到大排序完箩,因此如果將預(yù)告中狀態(tài)的得分全部取開播時間相反數(shù)讽膏,那排序同樣就成為了從大到小。這樣的轉(zhuǎn)化可以保證直播中與預(yù)告中同處于一個隊列排序碌嘀。預(yù)告中得分全都為負(fù)數(shù)便锨,直播中得分全都為正數(shù),最后聚合時可以保證所有直播中全都自然排在預(yù)告中前面吉捶。

另外前文還提到的另一個問題是T1時刻拉取第一頁夺鲜,T4時刻拉取第二頁,導(dǎo)致第一頁和第二頁直播間狀態(tài)不統(tǒng)一呐舔。解決這個問題的辦法是通過快照方式币励。當(dāng)觀眾來拉取第一頁Feed流時,我們依據(jù)當(dāng)前時間珊拼,將全部直播中和預(yù)告中狀態(tài)的場次建立一份快照食呻,使用一個session_id標(biāo)識,每次前端分頁拉取時澎现,我們直接從快照中讀取即可仅胞。如果快照中讀取完畢,證明該觀眾的直播中和預(yù)告中場次全部讀完剑辫,剩下的則使用回放隊列進行補充干旧。照此一來,我們的Feed流系統(tǒng)妹蔽,前端分頁拉取的參數(shù)一共有4個:


截屏2021-10-06 下午11.28.38.png

每當(dāng)碰到session_id和last_id為空椎眯,則證明用戶想要讀取第一頁挠将,需要重新構(gòu)建快照。這里還有一個衍生問題编整,session_id的如何取值舔稀?如果不考慮同一個觀眾在多端登錄的情況,其實每一位觀眾維護一個快照id即可掌测,也就是直接將系統(tǒng)用戶id設(shè)為session_id内贮;如果考慮多端登錄的情況,則session_id中必須包含每個端的信息赏半,以避免多端快照相互影響贺归;如果不心疼內(nèi)存,也可以每次隨機一個字符串作為session_id断箫,并設(shè)置一個足夠長的過期時間拂酣,讓快照自然過期。

以上設(shè)計仲义,其實系統(tǒng)計算量最大的時刻就是拉取第一頁婶熬,構(gòu)建快照的開銷。目前的線上數(shù)據(jù)埃撵,對于只關(guān)注不到10個主播的觀眾(這也是大多數(shù)場景)赵颅,拉取第一頁的QPS可以達到1.5萬。如果將第二頁以后的請求也算進來暂刘,F(xiàn)eed流的綜合QPS可以達到更高水平饺谬,支撐目前的用戶規(guī)模已經(jīng)綽綽有余。如果我們拉取第一頁時只獲取到前10條即可直接返回谣拣,將構(gòu)建快照操作改為異步募寨,也許QPS可以更高一些,這可能是后續(xù)的優(yōu)化點森缠。

06

總結(jié)

讀擴散拔鹰、寫擴散、讀寫混合贵涵,幾乎所有基于時間線和關(guān)注關(guān)系的Feed流都逃不開這三種基本設(shè)計模式列肢。具體到實際業(yè)務(wù)中,可能會有更復(fù)雜的場景宾茂,比如本文所說的狀態(tài)流轉(zhuǎn)影響排序瓷马,微博朋友圈場景中也會有廣告接入、特別關(guān)注跨晴、熱點話題等可能影響到Feed流排序的因素决采。這些場景就只能根據(jù)業(yè)務(wù)需求,做相對應(yīng)的變通了坟奥。
轉(zhuǎn)自:https://cloud.tencent.com/developer/article/1744756

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末树瞭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子爱谁,更是在濱河造成了極大的恐慌晒喷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件访敌,死亡現(xiàn)場離奇詭異凉敲,居然都是意外死亡,警方通過查閱死者的電腦和手機寺旺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進店門爷抓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人阻塑,你說我怎么就攤上這事蓝撇。” “怎么了陈莽?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵渤昌,是天一觀的道長。 經(jīng)常有香客問我走搁,道長独柑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任私植,我火速辦了婚禮忌栅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘曲稼。我一直安慰自己索绪,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布躯肌。 她就那樣靜靜地躺著者春,像睡著了一般。 火紅的嫁衣襯著肌膚如雪清女。 梳的紋絲不亂的頭發(fā)上钱烟,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天,我揣著相機與錄音嫡丙,去河邊找鬼拴袭。 笑死,一個胖子當(dāng)著我的面吹牛曙博,可吹牛的內(nèi)容都是我干的拥刻。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼父泳,長吁一口氣:“原來是場噩夢啊……” “哼般哼!你這毒婦竟也來了吴汪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蒸眠,失蹤者是張志新(化名)和其女友劉穎漾橙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體楞卡,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡霜运,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蒋腮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片淘捡。...
    茶點故事閱讀 38,622評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖池摧,靈堂內(nèi)的尸體忽然破棺而出焦除,到底是詐尸還是另有隱情,我是刑警寧澤险绘,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布踢京,位于F島的核電站,受9級特大地震影響宦棺,放射性物質(zhì)發(fā)生泄漏瓣距。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一代咸、第九天 我趴在偏房一處隱蔽的房頂上張望蹈丸。 院中可真熱鬧,春花似錦呐芥、人聲如沸逻杖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽荸百。三九已至,卻和暖如春滨攻,著一層夾襖步出監(jiān)牢的瞬間够话,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工光绕, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留女嘲,地道東北人。 一個月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓诞帐,卻偏偏與公主長得像欣尼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子停蕉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,490評論 2 348

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