如何構(gòu)建高并發(fā)高可用的網(wǎng)站應(yīng)用蜗侈,以及我的思考

前言

本文版權(quán)屬于?天職信息,你可以用它做任何事情睡蟋,但是轉(zhuǎn)載請(qǐng)保留鏈接踏幻。
http://www.tztech.net

我們構(gòu)建的大多數(shù)系統(tǒng)都不用考慮并發(fā)性能。然而戳杀,系統(tǒng)的“速度”是用戶體驗(yàn)的第一要素该面。所以當(dāng)系統(tǒng)的反應(yīng)速度變慢的時(shí)候,我們不得不面對(duì)一系列的并發(fā)問題豺瘤∵壕耄客戶會(huì)經(jīng)常這么說:

  • 這個(gè)網(wǎng)站太慢了!
  • 這怎么加載這么長(zhǎng)時(shí)間坐求?
  • 我剛提交的數(shù)據(jù)蚕泽,怎么失敗了?
  • 我和某人同時(shí)修改某一數(shù)據(jù)桥嗤,怎么提交失敗了须妻?
  • 導(dǎo)入的數(shù)據(jù)必須要同步完成。
  • 我剛更新的 AccessToken 怎么就過期了(技術(shù)層面)泛领?

這些問題荒吏,歸根到底都(可能)是因?yàn)榫W(wǎng)站的并發(fā)沒有做好導(dǎo)致的低可用性。此時(shí)渊鞋,用戶的流失或客戶的失望將會(huì)是企業(yè)最大的損失绰更。

本文將會(huì)討論如何優(yōu)化網(wǎng)站的性能。

本文中提到的所有方案都是可以通過技術(shù)手段實(shí)現(xiàn)的锡宋,并且實(shí)現(xiàn)速度是較快的儡湾。本人并不認(rèn)為這種“得過且過”的方式是正確的,必要的時(shí)候請(qǐng)考慮V戳P炷啤!重構(gòu)你的系統(tǒng)或提升你的算法和數(shù)據(jù)庫(kù)優(yōu)化技能R凼住3⒇ぁ!

本文提出的解決方案可能會(huì)需要爭(zhēng)取客戶的同意才能實(shí)施

異步操作

用戶的時(shí)間是寶貴的衡奥,公司員工的時(shí)間也是寶貴的爹袁。所以對(duì)于一些費(fèi)時(shí)的操作,我們可以推薦用戶將操作異步化:比如矮固,在導(dǎo)入數(shù)據(jù)時(shí)呢簸,讓用戶先將 excel 文件上傳,然后新建一個(gè)后臺(tái)的任務(wù),在后臺(tái)進(jìn)行輪詢和插入根时。

這樣做不是沒有道理的。在生活中辰晕,我們可以讓同事取一個(gè)快遞蛤迎,取回來了之后給我打電話;點(diǎn)擊“編譯”之后含友,系統(tǒng)會(huì)在完成編譯操作之后自動(dòng)發(fā)送通知替裆;CPU有一個(gè)“中斷”的概念,用于提示外設(shè)發(fā)生了某個(gè)事件窘问;在淘寶上賣完?yáng)|西之后辆童,過兩天會(huì)有快遞給我打來電話,叫你下樓去取快遞——以上所述都是異步操作的例子惠赫。我們應(yīng)該引導(dǎo)用戶把鉴,容忍“異步操作”的存在

異步操作——實(shí)現(xiàn)方法

異步操作有很多實(shí)現(xiàn)方式儿咱。這里介紹兩種——多線程和消息隊(duì)列庭砍。

首先,你需要找到最費(fèi)時(shí)的那幾行代碼混埠,然后想辦法將其提取為方法怠缸,然后將其滯后執(zhí)行。

多線程

我們可以用多線程來處理進(jìn)程內(nèi)的異步操作钳宪。比如:

場(chǎng)景描述:
我們需要導(dǎo)入某一個(gè) Excel 中的 10000 條數(shù)據(jù)揭北,每次插入數(shù)據(jù)的時(shí)候都要花費(fèi)0.5秒

解決方案:
文件上傳后,立即新建一個(gè)線程來導(dǎo)入數(shù)據(jù)吏颖,當(dāng)前線程立即返回搔体,告知用戶“文件提交成功,正在導(dǎo)入數(shù)據(jù)”侦高。

消息隊(duì)列Message Queue, MQ

我們可以使用“發(fā)布/訂閱(pub/sub)”模式來處理進(jìn)程間的異步操作嫉柴。比如:

場(chǎng)景描述
在用戶發(fā)送一條微博時(shí),需要將這條微博推送到關(guān)注者的時(shí)間線中

解決方案
用戶發(fā)送一條微博奉呛,用戶端收到請(qǐng)求计螺,將微博推送到“發(fā)送微博”隊(duì)列(publish),負(fù)責(zé)計(jì)算時(shí)間線的應(yīng)用(另一個(gè)線程)會(huì)監(jiān)聽該隊(duì)列瞧壮,并處理時(shí)間線相關(guān)的計(jì)算(subscribe)登馒。

關(guān)于消息隊(duì)列的應(yīng)用有很多。

  • 在青矩項(xiàng)目中咆槽,使用消息隊(duì)列來發(fā)送系統(tǒng)通知和發(fā)送數(shù)據(jù)更新通知
  • 在互聯(lián)網(wǎng)公司中陈轿,經(jīng)常使用 Kafka 隊(duì)列處理日志(GB/s 級(jí)別)

優(yōu)秀的消息隊(duì)列有:MSMQKafkaRabbitMQ 睡毒。Redis也支持簡(jiǎn)單的pub/sub應(yīng)用橡伞,值得一試。

????對(duì)于 Windows版本的 Redis缆八,請(qǐng)使用 MSOpenTech/redis潜秋,請(qǐng)不要再使用 rgl/redis

數(shù)據(jù)一致性

在高并發(fā)應(yīng)用中蛔琅,我們需要保證系統(tǒng)數(shù)據(jù)的一致性,包括進(jìn)程內(nèi)數(shù)據(jù)的一致性和進(jìn)程間數(shù)據(jù)的一致性峻呛。
我們需要使用事務(wù)Transaction來保證數(shù)據(jù)的一致性罗售。

使用雙重檢查鎖(Double Check Lock)保證進(jìn)程內(nèi)數(shù)據(jù)的一致性

首先,需要摘取出系統(tǒng)的邊界資源钩述,然后在邊界資源更新時(shí)寨躁,對(duì)其應(yīng)用雙重檢查鎖。

場(chǎng)景描述
現(xiàn)在系統(tǒng)中有一個(gè)AccessToken牙勘,該 Token 需要2個(gè)小時(shí)刷新一次职恳。在刷新的過程中,由于并發(fā)問題谜悟,導(dǎo)致該變量中的值瞬間被刷新了兩次话肖,進(jìn)而導(dǎo)致系統(tǒng)中出現(xiàn)異常。

解決方案
在AccessToken更新時(shí)葡幸,為了防止有多個(gè)線程更新該變量最筒,可考慮在更新時(shí)使用“雙重檢查鎖”。

??注意事項(xiàng)
此技巧僅適用于更新操作較少的情況蔚叨。不恰當(dāng)?shù)氖褂每赡軙?huì)導(dǎo)致性能問題床蜘。

使用二階段提交(Two-phase Commit, 2PC)處理進(jìn)程間數(shù)據(jù)的一致性

圖示二階段提交 [來源](https://dzone.com/articles/xa-transactions-2-phase-commit)

二階段提交算法的成立基于以下假設(shè)(來自 WikiPedia:2PC):

該分布式系統(tǒng)中,存在一個(gè)節(jié)點(diǎn)作為協(xié)調(diào)者(Coordinator)蔑水,其他節(jié)點(diǎn)作為參與者(Cohorts)邢锯。且節(jié)點(diǎn)之間可以進(jìn)行網(wǎng)絡(luò)通信。

所有節(jié)點(diǎn)都采用預(yù)寫式日志搀别,且日志被寫入后即被保持在可靠的存儲(chǔ)設(shè)備上丹擎,即使節(jié)點(diǎn)損壞不會(huì)導(dǎo)致日志數(shù)據(jù)的消失。

所有節(jié)點(diǎn)不會(huì)永久性損壞歇父,即使損壞后仍然可以恢復(fù)蒂培。

二階段提交的工作流程是這樣的(來自 WikiPedia:2PC):

第一階段(提交請(qǐng)求階段)
協(xié)調(diào)者節(jié)點(diǎn)向所有參與者節(jié)點(diǎn)詢問是否可以執(zhí)行提交操作,并開始等待各參與者節(jié)點(diǎn)的響應(yīng)榜苫。
參與者節(jié)點(diǎn)執(zhí)行詢問發(fā)起為止的所有事務(wù)操作护戳,并將Undo信息(undo logs)Redo信息(redo logs)寫入日志。

各參與者節(jié)點(diǎn)響應(yīng)協(xié)調(diào)者節(jié)點(diǎn)發(fā)起的詢問垂睬。如果參與者節(jié)點(diǎn)的事務(wù)操作實(shí)際執(zhí)行成功媳荒,則它返回一個(gè)"同意"消息抗悍;如果參與者節(jié)點(diǎn)的事務(wù)操作實(shí)際執(zhí)行失敗,則它返回一個(gè)"中止"消息钳枕。

有時(shí)候缴渊,第一階段也被稱作投票階段,即各參與者投票是否要繼續(xù)接下來的提交操作鱼炒。


第二階段(提交執(zhí)行階段)

成功
當(dāng)協(xié)調(diào)者節(jié)點(diǎn)從所有參與者節(jié)點(diǎn)獲得的相應(yīng)消息都為"同意"時(shí):

  • 協(xié)調(diào)者節(jié)點(diǎn)向所有參與者節(jié)點(diǎn)發(fā)出"正式提交"的請(qǐng)求疟暖。
  • 參與者節(jié)點(diǎn)正式完成操作,并釋放在整個(gè)事務(wù)期間內(nèi)占用的資源田柔。
  • 參與者節(jié)點(diǎn)向協(xié)調(diào)者節(jié)點(diǎn)發(fā)送"完成"消息。
  • 協(xié)調(diào)者節(jié)點(diǎn)收到所有參與者節(jié)點(diǎn)反饋的"完成"消息后骨望,完成事務(wù)硬爆。

失敗
如果任一參與者節(jié)點(diǎn)在第一階段返回的響應(yīng)消息為"終止",或者 協(xié)調(diào)者節(jié)點(diǎn)在第一階段的詢問超時(shí)之前無法獲取所有參與者節(jié)點(diǎn)的響應(yīng)消息時(shí):

  • 協(xié)調(diào)者節(jié)點(diǎn)向所有參與者節(jié)點(diǎn)發(fā)出"回滾操作"的請(qǐng)求擎鸠。
  • 參與者節(jié)點(diǎn)利用之前寫入的Undo信息執(zhí)行回滾缀磕,并釋放在整個(gè)事務(wù)期間內(nèi)占用的資源。
  • 參與者節(jié)點(diǎn)向協(xié)調(diào)者節(jié)點(diǎn)發(fā)送"回滾完成"消息劣光。
  • 協(xié)調(diào)者節(jié)點(diǎn)收到所有參與者節(jié)點(diǎn)反饋的"回滾完成"消息后袜蚕,取消事務(wù)。

??有時(shí)候绢涡,第二階段也被稱作完成階段牲剃,因?yàn)闊o論結(jié)果怎樣,協(xié)調(diào)者都必須在此階段結(jié)束當(dāng)前事務(wù)雄可。

二階段提交的局限性(來自 WikiPedia:2PC

  • 二階段提交算法的最大缺點(diǎn)就在于 它的執(zhí)行過程中間凿傅,節(jié)點(diǎn)都處于阻塞狀態(tài)。即節(jié)點(diǎn)之間在等待對(duì)方的相應(yīng)消息時(shí)数苫,它將什么也做不了聪舒。特別是,當(dāng)一個(gè)節(jié)點(diǎn)在已經(jīng)占有了某項(xiàng)資源的情況下虐急,為了等待其他節(jié)點(diǎn)的響應(yīng)消息而陷入阻塞狀態(tài)時(shí)箱残,當(dāng)?shù)谌齻€(gè)節(jié)點(diǎn)嘗試訪問該節(jié)點(diǎn)占有的資源時(shí),這個(gè)節(jié)點(diǎn)也將連帶陷入阻塞狀態(tài)止吁。
  • 另外被辑,協(xié)調(diào)者節(jié)點(diǎn)指示參與者節(jié)點(diǎn)進(jìn)行提交等操作時(shí),如有參與者節(jié)點(diǎn)出現(xiàn)了崩潰等情況而導(dǎo)致協(xié)調(diào)者始終無法獲取所有參與者的響應(yīng)信息赏殃,這時(shí)協(xié)調(diào)者將只能依賴協(xié)調(diào)者自身的超時(shí)機(jī)制來生效敷待。但往往超時(shí)機(jī)制生效時(shí),協(xié)調(diào)者都會(huì)指示參與者進(jìn)行回滾操作仁热。這樣的策略顯得比較保守榜揖。

除了二階段提交勾哩,我們還可以用其他的提交方法。原理與其類似举哟,但是它們?cè)谒惴ㄉ蠒?huì)或多或少地優(yōu)化性能思劳。

擴(kuò)展閱讀:
關(guān)于分布式事務(wù)、兩階段提交協(xié)議妨猩、三階提交協(xié)議
分布式系統(tǒng)的事務(wù)處理

??以上所述的提交方式在各大數(shù)據(jù)庫(kù)中(應(yīng)該)都有實(shí)現(xiàn)潜叛。然而,在一些復(fù)雜的情況中(銀行轉(zhuǎn)賬壶硅,用戶退款)威兜,我們?nèi)匀恍枰约簩?shí)現(xiàn)事務(wù)功能,并對(duì)該模塊進(jìn)行嚴(yán)格的邏輯測(cè)試和壓力測(cè)試庐椒。

分離你的業(yè)務(wù)

系統(tǒng)中所選用的技術(shù)椊范妫可能會(huì)導(dǎo)致其實(shí)現(xiàn)功能的局限性。比如:如果使用了Linux 约谈,實(shí)現(xiàn) Office 文檔的預(yù)覽會(huì)很困難笔宿,要么格式不對(duì),要么體驗(yàn)不好棱诱;如果使用了 RDBMS泼橘,就不能把所有的數(shù)據(jù)放到 DB 中,否則會(huì)導(dǎo)致 IO 很慢——這些都是技術(shù)選型與限制迈勋。我并不是在說哪個(gè)技術(shù)好哪個(gè)技術(shù)壞炬灭,在公司中,技術(shù)選型一定是基于當(dāng)前人員的配置來的粪躬,并且會(huì)有妥協(xié)担败。

隨著系統(tǒng)功能的完善,上述的“局限性”終歸需要解決镰官。我建議提前,與其將就使用當(dāng)前的技術(shù)棧,用不好的實(shí)踐實(shí)現(xiàn)這些功能泳唠,還不如在其他技術(shù)棧上使用好的實(shí)踐實(shí)現(xiàn)這些功能狈网。

使用 緩存思想 提升系統(tǒng) IO 的吞吐量 (MongoDB 為例)

與 RDBMS 相比,MongoDB IO 較快笨腥。其根本原因是拓哺,MongoDB 使用的存儲(chǔ)引擎 會(huì)在存儲(chǔ)數(shù)據(jù)時(shí)將數(shù)據(jù)存至內(nèi)存中,每 60S 或存儲(chǔ)到達(dá)2GB的時(shí)候會(huì)自動(dòng)同步至硬盤中脖母。

仿照 CPU 的架構(gòu)士鸥,我們可以做一個(gè)類似緩存的東西(L1,L2谆级,L3 Cache)來緩存新添加的數(shù)據(jù)烤礁,或者仿照 CLR 的GC算法讼积,將“熱數(shù)據(jù)”的一部分放到MongoDB的緩存中。緩存有一個(gè)“命中率”的概念脚仔。當(dāng)命中率達(dá)到80%左右的時(shí)候勤众,那么這個(gè)緩存的設(shè)計(jì)就是正確的。關(guān)于緩存命中率鲤脏,這里有一篇文章

要使用緩存们颜,我們可以這樣做

場(chǎng)景描述
現(xiàn)在需要導(dǎo)入10000條招聘信息,一定要實(shí)現(xiàn)瞬間導(dǎo)入猎醇。

解決方案
用戶上傳文件 > ** 解析文件中的信息 ** > ** 放到MongoDB中** >** 后臺(tái)開線程** 窥突,將數(shù)據(jù)同步到RDBMS中(可以使用隊(duì)列來增加系統(tǒng)的容錯(cuò)性)。

如果系統(tǒng)中的一些業(yè)務(wù)可以形成閉環(huán)硫嘶,并且IO要求較高(文件波岛、附件管理相關(guān)),和其他業(yè)務(wù)關(guān)聯(lián)不大音半,可以直接將此模塊獨(dú)立出來,使用 MongoDB來提升系統(tǒng)性能贡蓖。

??在C#中曹鸠,你可以使用LINQ對(duì)MongoDB進(jìn)行查詢;你可以使用內(nèi)建的 Filter 和Update來進(jìn)行某一字段的 Update斥铺,當(dāng)然彻桃,你也可以整個(gè)對(duì)象全部更新——但筆者認(rèn)為這是不推薦的。因?yàn)?MongoDB C# 驅(qū)動(dòng)給出的 Update 語(yǔ)句已經(jīng)是強(qiáng)類型的了晾蜘,整個(gè)對(duì)象更新會(huì)讓代碼的可讀性降低邻眷。在OO設(shè)計(jì)中,每一個(gè)需要存儲(chǔ)持久化數(shù)據(jù)的方法不應(yīng)該需要保存整個(gè)實(shí)體類的——這樣做有些麻煩剔交, 也不需要這樣做肆饶。

??在Java中,同樣有優(yōu)秀的MongoDB框架岖常。雖然 Java 的驅(qū)動(dòng)本身不帶 POJO Mapper驯镊,你可以用這個(gè):Spring Data MongoDB

多說一句:筆者掃了一眼這個(gè)框架,好像還比較符合Java的設(shè)計(jì)哲學(xué)——面向?qū)ο蠼甙埃⑶以撻_源框架的GitHub上最近也有代碼正在提交板惑。值得一試

此外,還可以使用Redis來實(shí)現(xiàn)緩存機(jī)制偎快。方法類似冯乘,在此不過多贅述。

使用HTTP負(fù)載均衡(Nginx 為例)

CDN和流量分發(fā)是構(gòu)建大型網(wǎng)站應(yīng)用的常見的技術(shù)晒夹。我們可以使用Nginx來進(jìn)行流量分發(fā)(C# 和 Java)裆馒。如果是Node.js姊氓,我們可以使用PM2的機(jī)架(Cluster)模式來做負(fù)載均衡。

你可以像以下這樣設(shè)置Nginx的負(fù)載均衡:

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://myapp1;
        }
    }
}

被負(fù)載均衡的應(yīng)用應(yīng)該符合 12 Factor Apps規(guī)范领追。該規(guī)范旨在:

如今他膳,軟件通常會(huì)作為一種服務(wù)來交付,它們被稱為網(wǎng)絡(luò)應(yīng)用程序绒窑,或軟件即服務(wù)(SaaS)棕孙。12-Factor 為構(gòu)建如下的 SaaS 應(yīng)用提供了方法論:

  • 使用標(biāo)準(zhǔn)化流程自動(dòng)配置,從而使新的開發(fā)者花費(fèi)最少的學(xué)習(xí)成本加入這個(gè)項(xiàng)目些膨。
  • 和操作系統(tǒng)之間盡可能的劃清界限蟀俊,在各個(gè)系統(tǒng)中提供最大的可移植性
  • 適合部署在現(xiàn)代的云計(jì)算平臺(tái)订雾,從而在服務(wù)器和系統(tǒng)管理方面節(jié)省資源肢预。
  • 將開發(fā)環(huán)境和生產(chǎn)環(huán)境的差異降至最低,并使用持續(xù)交付實(shí)施敏捷開發(fā)洼哎。
  • 可以在工具烫映、架構(gòu)和開發(fā)流程不發(fā)生明顯變化的前提下實(shí)現(xiàn)擴(kuò)展

其中噩峦,進(jìn)程一節(jié)提到锭沟,

12-Factor 應(yīng)用的進(jìn)程必須無狀態(tài)且 無共享 任何需要持久化的數(shù)據(jù)都要存儲(chǔ)在 后端服務(wù) 內(nèi)识补,比如數(shù)據(jù)庫(kù)族淮。

根據(jù)該節(jié)的描述,如果我們使用了Session凭涂,需要實(shí)現(xiàn)服務(wù)間共享Session祝辣,才能對(duì)應(yīng)用進(jìn)行負(fù)載均衡的操作。

降低方法和程序的副作用(side effects)也是一種分離的方式切油。如果方法和程序的副作用過多蝙斜,那么說明此方法耦合度過緊(tough coupled),這時(shí)候就需要考慮該設(shè)計(jì)是否合理了澎胡。

結(jié)語(yǔ)

以上乍炉,所有知識(shí)都是我腦袋里能抽出來的知識(shí)了。有些討論可能會(huì)有謬誤滤馍。如果有岛琼,請(qǐng)指出,感激不盡巢株!
以上內(nèi)容每個(gè)分類都可以獨(dú)立出一個(gè)專題來講槐瑞,這里只是泛泛地談這些內(nèi)容。希望能幫助到你

?天職信息
[EOF]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末阁苞,一起剝皮案震驚了整個(gè)濱河市困檩,隨后出現(xiàn)的幾起案子祠挫,更是在濱河造成了極大的恐慌,老刑警劉巖悼沿,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件等舔,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡糟趾,警方通過查閱死者的電腦和手機(jī)慌植,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來义郑,“玉大人蝶柿,你說我怎么就攤上這事》峭裕” “怎么了交汤?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)劫笙。 經(jīng)常有香客問我芙扎,道長(zhǎng),這世上最難降的妖魔是什么填大? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任纵顾,我火速辦了婚禮,結(jié)果婚禮上栋盹,老公的妹妹穿的比我還像新娘。我一直安慰自己敷矫,他們只是感情好例获,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著曹仗,像睡著了一般榨汤。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上怎茫,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天收壕,我揣著相機(jī)與錄音,去河邊找鬼轨蛤。 笑死蜜宪,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的祥山。 我是一名探鬼主播圃验,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼缝呕!你這毒婦竟也來了澳窑?” 一聲冷哼從身側(cè)響起斧散,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摊聋,沒想到半個(gè)月后鸡捐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡麻裁,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年箍镜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片悲立。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鹿寨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出薪夕,到底是詐尸還是另有隱情脚草,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布原献,位于F島的核電站馏慨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏姑隅。R本人自食惡果不足惜写隶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望讲仰。 院中可真熱鬧慕趴,春花似錦、人聲如沸鄙陡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)趁矾。三九已至耙册,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毫捣,已是汗流浹背详拙。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蔓同,地道東北人饶辙。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像斑粱,于是被迫代替她去往敵國(guó)和親畸悬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

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