實(shí)戰(zhàn)敢辩!如何從零搭建10萬(wàn)級(jí) QPS 大流量蔽莱、高并發(fā)優(yōu)惠券系統(tǒng)

看自某跳動(dòng)團(tuán)隊(duì)文章,文章我覺(jué)的很好戚长,這里記錄下盗冷。

需求背景

春節(jié)活動(dòng)中,多個(gè)業(yè)務(wù)方都有發(fā)放優(yōu)惠券的需求同廉,且對(duì)發(fā)券的 QPS 量級(jí)有明確的需求仪糖。所有的優(yōu)惠券發(fā)放柑司、核銷、查詢都需要一個(gè)新系統(tǒng)來(lái)承載乓诽。因此帜羊,我們需要設(shè)計(jì)、開(kāi)發(fā)一個(gè)能夠支持十萬(wàn)級(jí) QPS 的券系統(tǒng)鸠天,并且對(duì)優(yōu)惠券完整的生命周期進(jìn)行維護(hù)讼育。

需求拆解及技術(shù)選型

需求拆解

  • 要配置券,會(huì)涉及到券批次(券模板)創(chuàng)建稠集,券模板的有效期以及券的庫(kù)存信息
  • 要發(fā)券奶段,會(huì)涉及到券記錄的創(chuàng)建和管理(過(guò)期時(shí)間,狀態(tài))
    因此剥纷,我們可以將需求先簡(jiǎn)單拆解為兩部分:



    同時(shí)痹籍,無(wú)論是券模板還是券記錄,都需要開(kāi)放查詢接口晦鞋,支持券模板/券記錄的查詢蹲缠。

系統(tǒng)選型及中間件

確定了基本的需求,我們根據(jù)需求悠垛,進(jìn)一步分析可能會(huì)用到的中間件线定,以及系統(tǒng)整體的組織方式。

存儲(chǔ)
由于券模板确买、券記錄這些都是需要持久化的數(shù)據(jù)斤讥,同時(shí)還需要支持條件查詢,所以我們選用通用的結(jié)構(gòu)化存儲(chǔ)MySQL 作為存儲(chǔ)中間件湾趾。

緩存
由于發(fā)券時(shí)需要券模板信息芭商,大流量情況下,不可能每次都從MySQL 獲取券模板信息搀缠,因此考慮引入緩存
同理铛楣,券的庫(kù)存管理,或者叫庫(kù)存扣減艺普,也是一個(gè)高頻簸州、實(shí)時(shí)的操作,因此也考慮放入緩存中
主流的緩存Redis 可以滿足我們的需求衷敌,因此我們選用 Redis 作為緩存中間件勿侯。

消息隊(duì)列
由于券模板/券記錄都需要展示過(guò)期狀態(tài)拓瞪,并且根據(jù)不同的狀態(tài)進(jìn)行業(yè)務(wù)邏輯處理缴罗,因此有必要引入延遲消息隊(duì)列來(lái)對(duì)券模板/券狀態(tài)進(jìn)行處理。RocketMQ 支持延時(shí)消息祭埂,因此我們選用 RocketMQ 作為消息隊(duì)列面氓。

系統(tǒng)框架
發(fā)券系統(tǒng)作為下游服務(wù)兵钮,是需要被上游服務(wù)所調(diào)用的。公司內(nèi)部服務(wù)之間淘菩,采用的都是 RPC 服務(wù)調(diào)用骨望,系統(tǒng)開(kāi)發(fā)語(yǔ)言使用的是 golang反砌,因此我們使用 golang 服務(wù)的 RPC 框架 kitex 進(jìn)行代碼編寫(xiě)。

我們采用 kitex+MySQL+Redis+RocketMQ 來(lái)實(shí)現(xiàn)發(fā)券系統(tǒng)葱轩,RPC 服務(wù)部署在公司的 docker 容器中。

系統(tǒng)開(kāi)發(fā)與實(shí)踐

系統(tǒng)設(shè)計(jì)實(shí)現(xiàn)

系統(tǒng)整體架構(gòu)
從需求拆解部分我們對(duì)大致要開(kāi)發(fā)的系統(tǒng)有了一個(gè)了解藐握,下面給出整體的一個(gè)系統(tǒng)架構(gòu)靴拱,包含了一些具體的功能。

數(shù)據(jù)結(jié)構(gòu) ER 圖
與系統(tǒng)架構(gòu)對(duì)應(yīng)的猾普,我們需要建立對(duì)應(yīng)的MySQL數(shù)據(jù)存儲(chǔ)表袜炕。

核心邏輯實(shí)現(xiàn)

發(fā)券

發(fā)券流程分為三部分:參數(shù)校驗(yàn)、冪等校驗(yàn)初家、庫(kù)存扣減偎窘。



冪等操作用于保證發(fā)券請(qǐng)求不正確的情況下,業(yè)務(wù)方通過(guò)重試溜在、補(bǔ)償?shù)姆绞皆俅握?qǐng)求陌知,可以最終只發(fā)出一張券,防止資金損失炕泳。

券過(guò)期

券過(guò)期是一個(gè)狀態(tài)推進(jìn)的過(guò)程纵诞,這里我們使用 RocketMQ 來(lái)實(shí)現(xiàn)。

  • 由于 RocketMQ 支持的延時(shí)消息有最大限制培遵,而卡券的有效期不固定浙芙,有可能會(huì)超過(guò)限制,所以我們將卡券過(guò)期消息循環(huán)處理籽腕,直到卡券過(guò)期嗡呼。

大流量、高并發(fā)場(chǎng)景下的問(wèn)題及解決方案

實(shí)現(xiàn)了系統(tǒng)的基本功能后皇耗,我們來(lái)討論一下南窗,如果在大流量、高并發(fā)的場(chǎng)景下郎楼,系統(tǒng)可能會(huì)遇到的一些問(wèn)題及解決方案万伤。

存儲(chǔ)瓶頸及解決方案

瓶頸

在系統(tǒng)架構(gòu)中,我們使用了MySQL呜袁、Redis作為存儲(chǔ)組件敌买。我們知道,單個(gè)服務(wù)器的I/O 能力終是有限的阶界,在實(shí)際測(cè)試過(guò)程中虹钮,能夠得到如下的數(shù)據(jù):

  • 單個(gè) MySQL 的每秒寫(xiě)入在 4000 QPS左右聋庵,超過(guò)這個(gè)數(shù)字,MySQL的 I/O 時(shí)延會(huì)劇量增長(zhǎng)芙粱。

  • MySQL 單表記錄到達(dá)了千萬(wàn)級(jí)別祭玉,查詢效率會(huì)大大降低,如果過(guò)億的話春畔,數(shù)據(jù)查詢會(huì)成為一個(gè)問(wèn)題脱货。

  • Redis 單分片的寫(xiě)入瓶頸在 2w 左右,讀瓶頸在 10w左右

解決方案

1律姨、 讀寫(xiě)分離蹭劈。在查詢?nèi)0濉⒉樵內(nèi)涗浀葓?chǎng)景下线召,我們可以將MySQL 進(jìn)行讀寫(xiě)分離铺韧,讓這部分查詢流量走 MySQL 的讀庫(kù),從而減輕 MySQL 寫(xiě)庫(kù)的查詢壓力缓淹。

2哈打、分治。在軟件設(shè)計(jì)中讯壶,有一種分治的思想料仗,對(duì)于存儲(chǔ)瓶頸的問(wèn)題,業(yè)界常用的方案就是分而治之:流量分散伏蚊、存儲(chǔ)分散立轧,即:分庫(kù)分表。

  • 發(fā)券躏吊,歸根結(jié)底是要對(duì)用戶的領(lǐng)券記錄做持久化存儲(chǔ)氛改。對(duì)于 MySQL 本身 I/O 瓶頸來(lái)說(shuō),我們可以在不同服務(wù)器上部署 MySQL 的不同分片比伏,對(duì) MySQL做水平擴(kuò)容胜卤,這樣一來(lái),寫(xiě)請(qǐng)求就會(huì)分布在不同的 MySQL主機(jī)上赁项,這樣就能夠大幅提升 MySQL整體的吞吐量葛躏。

  • 給用戶發(fā)了券,那么用戶肯定需要查詢自己獲得的券悠菜〗⒃埽基于這個(gè)邏輯,我們以 user_id 后四位為分片鍵悔醋,對(duì)用戶領(lǐng)取的記錄表做水平拆分摩窃,以支持用戶維度的領(lǐng)券記錄的查詢。

  • 每種券都有對(duì)應(yīng)的數(shù)量篙顺,在給用戶發(fā)券的過(guò)程中偶芍,我們是將發(fā)券數(shù)記錄在 Redis 中的,大流量的情況下德玫,我們也需要對(duì) Redis做水平擴(kuò)容匪蟀,減輕Redis單機(jī)的壓力。

容量預(yù)估:

基于上述思路宰僧,在要滿足發(fā)券 12w QPS的需求下材彪,我們預(yù)估一下存儲(chǔ)資源。

a. MySQL 資源

在實(shí)際測(cè)試中琴儿,單次發(fā)券對(duì) MySQL 有一次非事務(wù)性寫(xiě)入段化,MySQL 的單機(jī)的寫(xiě)入瓶頸為 4000,據(jù)此可以計(jì)算我們需要的 MySQL 主庫(kù)資源為:

120000/4000 = 30

b. Redis 資源

假設(shè) 12w 的發(fā)券QPS造成,均為同一券模板显熏,單分片的寫(xiě)入瓶頸為 2w,則需要的最少 Redis 分片為:

120000/20000 = 6

熱點(diǎn)庫(kù)存問(wèn)題及解決方案

問(wèn)題

大流量發(fā)券場(chǎng)景下晒屎,如果我們使用的券模板為一個(gè)喘蟆,那么每次扣減庫(kù)存時(shí),訪問(wèn)到的 Redis 必然是特定的一個(gè)分片鼓鲁,因此蕴轨,一定會(huì)達(dá)到這個(gè)分片的寫(xiě)入瓶頸,更嚴(yán)重的骇吭,可能會(huì)導(dǎo)致整個(gè) Redis 集群不可用橙弱。

解決方案

熱點(diǎn)庫(kù)存的問(wèn)題,業(yè)界有通用的方案:即燥狰,扣減的庫(kù)存 key 不要集中在某一個(gè)分片上棘脐。如何保證這一個(gè)券模板的 key不集中在某一個(gè)分片上呢,我們拆key(拆庫(kù)存)即可龙致。如圖:


在業(yè)務(wù)邏輯中荆残,我們?cè)诮ㄈ0宓臅r(shí)候,就將這種熱點(diǎn)券模板做庫(kù)存拆分净当,后續(xù)扣減庫(kù)存時(shí)内斯,也扣減相應(yīng)的子庫(kù)存即可。

建券


庫(kù)存扣減

這里還剩下一個(gè)問(wèn)題像啼,即:扣減子庫(kù)存俘闯,每次都是從 1 開(kāi)始進(jìn)行的話,那對(duì) Redis對(duì)應(yīng)分片的壓力其實(shí)并沒(méi)有減輕忽冻,因此真朗,我們需要做到:每次請(qǐng)求,隨機(jī)不重復(fù)的輪詢子庫(kù)存僧诚。以下是本項(xiàng)目采取的一個(gè)具體思路:

Redis 子庫(kù)存的key 的最后一位是分片的編號(hào)遮婶,如:xxx_stock_key1蝗碎、xxx_stock_key2……,在扣減子庫(kù)存時(shí)旗扑,我們先生成對(duì)應(yīng)分片總數(shù)的隨機(jī)不重復(fù)數(shù)組蹦骑,如第一次是[1,2,3],第二次可能是[3,1,2]臀防,這樣眠菇,每次扣減子庫(kù)存的請(qǐng)求,就會(huì)分布到不同的 Redis 分片上袱衷,緩輕 Redis 單分片壓力的同時(shí)捎废,也能支持更高 QPS的扣減請(qǐng)求。

這種思路的一個(gè)問(wèn)題是致燥,當(dāng)我們庫(kù)存接近耗盡的情況下登疗,很多分片子庫(kù)存的輪詢將變得毫無(wú)意義,因此我們可以在每次請(qǐng)求的時(shí)候嫌蚤,將子庫(kù)存的剩余量記錄下來(lái)谜叹,當(dāng)某一個(gè)券模板的子庫(kù)存耗盡后,隨機(jī)不重復(fù)的輪詢操作直接跳過(guò)這個(gè)子庫(kù)存分片搬葬,這樣能夠優(yōu)化系統(tǒng)在庫(kù)存即將耗盡情況下的響應(yīng)速度荷腊。

業(yè)界針對(duì) Redis 熱點(diǎn) key 的處理,除了分 key 以外急凰,還有一種 key 備份的思路:即女仰,將相同的 key,用某種策略備份到不同的 Redis 分片上去抡锈,這樣就能將熱點(diǎn)打散疾忍。這種思路適用于那種讀多寫(xiě)少的場(chǎng)景,不適合應(yīng)對(duì)發(fā)券這種大流量寫(xiě)的場(chǎng)景床三。在面對(duì)具體的業(yè)務(wù)場(chǎng)景時(shí)一罩,我們需要根據(jù)業(yè)務(wù)需求,選用恰當(dāng)?shù)姆桨?/code>來(lái)解決問(wèn)題撇簿。

券模板獲取失敗問(wèn)題及解決方案
問(wèn)題

高 QPS聂渊,高并發(fā)的場(chǎng)景下,即使我們能將接口的成功率提升 0.01%四瘫,實(shí)際表現(xiàn)也是可觀的『核裕現(xiàn)在回過(guò)頭來(lái)看下整個(gè)發(fā)券的流程:查券模板(Redis)-->校驗(yàn)-->冪等(MySQL)--> 發(fā)券(MySQL)。在查券模板信息時(shí)找蜜,我們會(huì)請(qǐng)求 Redis饼暑,這是強(qiáng)依賴,在實(shí)際的觀測(cè)中,我們會(huì)發(fā)現(xiàn)弓叛,Redis 超時(shí)的概率大概在萬(wàn)分之 2彰居、3。因此撰筷,這部分發(fā)券請(qǐng)求是必然失敗的陈惰。

解決方案

為了提高這部分請(qǐng)求的成功率,我們有兩種方案闭专。

一是從 Redis 獲取券模板失敗時(shí),內(nèi)部進(jìn)行重試旧烧;二是將券模板信息緩存到實(shí)例的本地內(nèi)存中影钉,即引入二級(jí)緩存

內(nèi)部重試可以提高一部分請(qǐng)求的成功率掘剪,但無(wú)法從根本上解決 Redis 存在超時(shí)的問(wèn)題平委,同時(shí)重試的次數(shù)也和接口響應(yīng)的時(shí)長(zhǎng)成正比。二級(jí)緩存的引入夺谁,可以從根本上避免 Redis 超時(shí)造成的發(fā)券請(qǐng)求失敗廉赔。因此我們選用二級(jí)緩存方案:

當(dāng)然,引入了本地緩存匾鸥,我們還需要在每個(gè)服務(wù)實(shí)例中啟動(dòng)一個(gè)定時(shí)任務(wù)來(lái)將最新的券模板信息刷入到本地緩存和 Redis蜡塌,將模板信息刷入 Redis 中時(shí),要加分布式鎖勿负,防止多個(gè)實(shí)例同時(shí)寫(xiě) RedisRedis 造成不必要的壓力馏艾。

服務(wù)治理
系統(tǒng)開(kāi)發(fā)完成后,還需要通過(guò)一系列操作保障系統(tǒng)的可靠運(yùn)行奴愉。

  • 超時(shí)設(shè)置琅摩。優(yōu)惠券系統(tǒng)是一個(gè) RPC 服務(wù),因此我們需要設(shè)置合理的 RPC 超時(shí)時(shí)間锭硼,保證系統(tǒng)不會(huì)因?yàn)樯嫌蜗到y(tǒng)的故障而被拖垮房资。例如發(fā)券的接口,我們內(nèi)部執(zhí)行時(shí)間不超過(guò) 100ms檀头,因此接口超時(shí)我們可以設(shè)置為 500ms轰异,如果有異常請(qǐng)求,在 500ms 后暑始,就會(huì)被拒絕溉浙,從而保障我們服務(wù)穩(wěn)定的運(yùn)行。

  • 監(jiān)控與報(bào)警蒋荚。對(duì)于一些核心接口的監(jiān)控戳稽、穩(wěn)定性、重要數(shù)據(jù),以及系統(tǒng) CPU惊奇、內(nèi)存等的監(jiān)控互躬,我們會(huì)在 Grafana 上建立對(duì)應(yīng)的可視化圖表,在春節(jié)活動(dòng)期間颂郎,實(shí)時(shí)觀測(cè) Grafana 儀表盤吼渡,以保證能夠最快觀測(cè)到系統(tǒng)異常。同時(shí)乓序,對(duì)于一些異常情況寺酪,我們還有完善的報(bào)警機(jī)制,從而能夠第一時(shí)間感知到系統(tǒng)的異常替劈。

  • 限流寄雀。優(yōu)惠券系統(tǒng)是一個(gè)底層服務(wù),實(shí)際業(yè)務(wù)場(chǎng)景下會(huì)被多個(gè)上游服務(wù)所調(diào)用陨献,因此盒犹,合理的對(duì)這些上游服務(wù)進(jìn)行限流,也是保證優(yōu)惠券系統(tǒng)本身穩(wěn)定性必不可少的一環(huán)眨业。

  • 資源隔離急膀。因?yàn)槲覀兎?wù)都是部署在docker 集群中的,因此為了保證服務(wù)的高可用龄捡,服務(wù)部署的集群資源盡量分布在不同的物理區(qū)域上卓嫂,以避免由集群導(dǎo)致的服務(wù)不可用

系統(tǒng)壓測(cè)及實(shí)際表現(xiàn)

做完了上述一系列的工作后聘殖,是時(shí)候檢驗(yàn)我們服務(wù)在生產(chǎn)環(huán)境中的表現(xiàn)了命黔。當(dāng)然,新服務(wù)上線前就斤,首先需要對(duì)服務(wù)進(jìn)行壓測(cè)悍募。這里總結(jié)一下壓測(cè)可能需要注意的一些問(wèn)題及壓測(cè)結(jié)論。

注意事項(xiàng)

首先是壓測(cè)思路洋机,由于我們一開(kāi)始無(wú)法確定 docker 的瓶頸坠宴、存儲(chǔ)組件的瓶頸等。所以我們的壓測(cè)思路一般是:

  • 找到單實(shí)例瓶頸

  • 找到 MySQL 一主的寫(xiě)瓶頸绷旗、讀瓶頸

  • 找到 Redis 單分片寫(xiě)瓶頸喜鼓、讀瓶頸

得到了上述數(shù)據(jù)后,我們就可以粗略估算所需要的資源數(shù)衔肢,進(jìn)行服務(wù)整體的壓測(cè)了庄岖。

  • 壓測(cè)資源也很重要,提前申請(qǐng)到足量的壓測(cè)資源角骤,才能合理制定壓測(cè)計(jì)劃隅忿。
  • 壓測(cè)過(guò)程中心剥,要注意服務(wù)和資源的監(jiān)控,對(duì)不符合預(yù)期的部分要深入思考背桐,優(yōu)化代碼优烧。
  • 適時(shí)記錄壓測(cè)數(shù)據(jù),才能更好的復(fù)盤链峭。
  • 實(shí)際的使用資源畦娄,一般是壓測(cè)數(shù)據(jù)的 1.5 倍,我們需要保證線上有部分資源冗余以應(yīng)對(duì)突發(fā)的流量增長(zhǎng)弊仪。

結(jié)論

系統(tǒng)在 13w QPS 的發(fā)券請(qǐng)求下熙卡,請(qǐng)求成功率達(dá)到 99.9%以上,系統(tǒng)監(jiān)控正常励饵。春節(jié)紅包雨期間驳癌,該優(yōu)惠券系統(tǒng)承載了兩次紅包雨的全部流量,期間未出現(xiàn)異常曲横,圓滿完成了發(fā)放優(yōu)惠券的任務(wù)喂柒。

系統(tǒng)的業(yè)務(wù)思考

目前的系統(tǒng)不瓶,只是單純支持了高并發(fā)的發(fā)券功能禾嫉,對(duì)于券的業(yè)務(wù)探索并不足夠。后續(xù)需要結(jié)合業(yè)務(wù)蚊丐,嘗試批量發(fā)券(券包)熙参、批量核銷等功能
發(fā)券系統(tǒng)只是一個(gè)最底層的業(yè)務(wù)中臺(tái),可以適配各種場(chǎng)景麦备,后續(xù)可以探索支持更多業(yè)務(wù)孽椰。

總結(jié)

從零搭建一個(gè)大流量、高并發(fā)的優(yōu)惠券系統(tǒng)凛篙,首先應(yīng)該充分理解業(yè)務(wù)需求黍匾,然后對(duì)需求進(jìn)行拆解根據(jù)拆解后的需求呛梆,合理選用各種中間件锐涯;本文主要是要建設(shè)一套優(yōu)惠券系統(tǒng),因此會(huì)使用各類存儲(chǔ)組件和消息隊(duì)列填物,來(lái)完成優(yōu)惠券的存儲(chǔ)纹腌、查詢、過(guò)期操作滞磺;

在系統(tǒng)開(kāi)發(fā)實(shí)現(xiàn)過(guò)程中升薯,對(duì)核心的發(fā)券、券過(guò)期實(shí)現(xiàn)流程進(jìn)行了闡述击困,并針對(duì)大流量涎劈、高并發(fā)場(chǎng)景下可能遇到的存儲(chǔ)瓶頸、熱點(diǎn)庫(kù)存、券模板緩存獲取超時(shí)的問(wèn)題提出了對(duì)應(yīng)的解決方案责语。其中炮障,我們使用了分治的思想,對(duì)存儲(chǔ)中間件進(jìn)行水平擴(kuò)容以解決存儲(chǔ)瓶頸坤候;采取庫(kù)存拆分子庫(kù)存思路解決熱點(diǎn)庫(kù)存問(wèn)題胁赢;引入本地緩存解決券模板從Redis獲取超時(shí)的問(wèn)題。最終保證了優(yōu)惠券系統(tǒng)在大流量高并發(fā)的情景下穩(wěn)定可用白筹;

除開(kāi)服務(wù)本身智末,我們還從服務(wù)超時(shí)設(shè)置監(jiān)控報(bào)警徒河、限流系馆、資源隔離等方面對(duì)服務(wù)進(jìn)行了治理,保障服務(wù)的高可用顽照;

壓測(cè)是一個(gè)新服務(wù)不可避免的一個(gè)環(huán)節(jié)由蘑,通過(guò)壓測(cè)我們能夠?qū)Ψ?wù)的整體情況有個(gè)明確的了解,并且壓測(cè)期間暴露的問(wèn)題也會(huì)是線上可能遇到的代兵,通過(guò)壓測(cè)尼酿,我們能夠?qū)π路?wù)的整體情況做到心里有數(shù),對(duì)服務(wù)上線正式投產(chǎn)就更有信心了植影。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末裳擎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子思币,更是在濱河造成了極大的恐慌鹿响,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谷饿,死亡現(xiàn)場(chǎng)離奇詭異惶我,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)博投,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門绸贡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人贬堵,你說(shuō)我怎么就攤上這事恃轩。” “怎么了黎做?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵叉跛,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我蒸殿,道長(zhǎng)筷厘,這世上最難降的妖魔是什么鸣峭? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮酥艳,結(jié)果婚禮上摊溶,老公的妹妹穿的比我還像新娘。我一直安慰自己充石,他們只是感情好莫换,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著骤铃,像睡著了一般拉岁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惰爬,一...
    開(kāi)封第一講書(shū)人閱讀 52,736評(píng)論 1 312
  • 那天喊暖,我揣著相機(jī)與錄音,去河邊找鬼撕瞧。 笑死陵叽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丛版。 我是一名探鬼主播巩掺,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼硼婿!你這毒婦竟也來(lái)了锌半?” 一聲冷哼從身側(cè)響起禽车,我...
    開(kāi)封第一講書(shū)人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤寇漫,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后殉摔,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體州胳,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年逸月,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了栓撞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碗硬,死狀恐怖瓤湘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情恩尾,我是刑警寧澤弛说,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站翰意,受9級(jí)特大地震影響木人,放射性物質(zhì)發(fā)生泄漏信柿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一醒第、第九天 我趴在偏房一處隱蔽的房頂上張望渔嚷。 院中可真熱鬧,春花似錦稠曼、人聲如沸形病。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)窒朋。三九已至,卻和暖如春蝗岖,著一層夾襖步出監(jiān)牢的瞬間侥猩,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工抵赢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欺劳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓铅鲤,卻偏偏與公主長(zhǎng)得像划提,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子邢享,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

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