淺談分布式消息技術(shù):Kafka

Kafka的基本介紹

Kafka是最初由Linkedin公司開(kāi)發(fā)很魂,是一個(gè)分布式、分區(qū)的檐涝、多副本的遏匆、多訂閱者法挨,基于zookeeper協(xié)調(diào)的分布式日志系統(tǒng)(也可以當(dāng)做MQ系統(tǒng)),常見(jiàn)可以用于web/nginx日志幅聘、訪問(wèn)日志凡纳,消息服務(wù)等等,Linkedin于2010年貢獻(xiàn)給了Apache基金會(huì)并成為頂級(jí)開(kāi)源項(xiàng)目帝蒿。

主要應(yīng)用場(chǎng)景是:日志收集系統(tǒng)和消息系統(tǒng)荐糜。

Kafka主要設(shè)計(jì)目標(biāo)如下:

以時(shí)間復(fù)雜度為O(1)的方式提供消息持久化能力,即使對(duì)TB級(jí)以上數(shù)據(jù)也能保證常數(shù)時(shí)間的訪問(wèn)性能葛超。

高吞吐率暴氏。即使在非常廉價(jià)的商用機(jī)器上也能做到單機(jī)支持每秒100K條消息的傳輸。

支持Kafka Server間的消息分區(qū)绣张,及分布式消費(fèi)答渔,同時(shí)保證每個(gè)partition內(nèi)的消息順序傳輸。

同時(shí)支持離線數(shù)據(jù)處理和實(shí)時(shí)數(shù)據(jù)處理侥涵。

Kafka的設(shè)計(jì)原理分析

一個(gè)典型的kafka集群中包含若干producer沼撕,若干broker,若干consumer芜飘,以及一個(gè)Zookeeper集群务豺。Kafka通過(guò)Zookeeper管理集群配置,選舉leader燃箭,以及在consumer group發(fā)生變化時(shí)進(jìn)行rebalance冲呢。producer使用push模式將消息發(fā)布到broker,consumer使用pull模式從broker訂閱并消費(fèi)消息招狸。

Kafka專用術(shù)語(yǔ):

Broker:消息中間件處理結(jié)點(diǎn)敬拓,一個(gè)Kafka節(jié)點(diǎn)就是一個(gè)broker,多個(gè)broker可以組成一個(gè)Kafka集群裙戏。

Topic:一類消息乘凸,Kafka集群能夠同時(shí)負(fù)責(zé)多個(gè)topic的分發(fā)。

Partition:topic物理上的分組累榜,一個(gè)topic可以分為多個(gè)partition营勤,每個(gè)partition是一個(gè)有序的隊(duì)列。

Segment:partition物理上由多個(gè)segment組成壹罚。

offset:每個(gè)partition都由一系列有序的葛作、不可變的消息組成,這些消息被連續(xù)的追加到partition中猖凛。partition中的每個(gè)消息都有一個(gè)連續(xù)的序列號(hào)叫做offset赂蠢,用于partition唯一標(biāo)識(shí)一條消息。

Producer:負(fù)責(zé)發(fā)布消息到Kafka broker辨泳。

Consumer:消息消費(fèi)者虱岂,向Kafka broker讀取消息的客戶端玖院。

Consumer Group:每個(gè)Consumer屬于一個(gè)特定的Consumer Group。

Kafka數(shù)據(jù)傳輸?shù)氖聞?wù)特點(diǎn)

at most once:最多一次第岖,這個(gè)和JMS中”非持久化”消息類似难菌,發(fā)送一次,無(wú)論成敗蔑滓,將不會(huì)重發(fā)郊酒。消費(fèi)者fetch消息,然后保存offset烫饼,然后處理消息猎塞;當(dāng)client保存offset之后,但是在消息處理過(guò)程中出現(xiàn)了異常杠纵,導(dǎo)致部分消息未能繼續(xù)處理荠耽。那么此后”未處理”的消息將不能被fetch到,這就是”at most once”比藻。

at least once:消息至少發(fā)送一次铝量,如果消息未能接受成功,可能會(huì)重發(fā)银亲,直到接收成功慢叨。消費(fèi)者fetch消息,然后處理消息务蝠,然后保存offset拍谐。如果消息處理成功之后,但是在保存offset階段zookeeper異常導(dǎo)致保存操作未能執(zhí)行成功馏段,這就導(dǎo)致接下來(lái)再次fetch時(shí)可能獲得上次已經(jīng)處理過(guò)的消息轩拨,這就是”at least once”,原因offset沒(méi)有及時(shí)的提交給zookeeper院喜,zookeeper恢復(fù)正常還是之前offset狀態(tài)亡蓉。

exactly once:消息只會(huì)發(fā)送一次。kafka中并沒(méi)有嚴(yán)格的去實(shí)現(xiàn)(基于2階段提交)喷舀,我們認(rèn)為這種策略在kafka中是沒(méi)有必要的砍濒。

通常情況下”at-least-once”是我們首選。

Kafka消息存儲(chǔ)格式

Topic & Partition

一個(gè)topic可以認(rèn)為一個(gè)一類消息硫麻,每個(gè)topic將被分成多個(gè)partition爸邢,每個(gè)partition在存儲(chǔ)層面是append log文件。

在Kafka文件存儲(chǔ)中拿愧,同一個(gè)topic下有多個(gè)不同partition杠河,每個(gè)partition為一個(gè)目錄,partiton命名規(guī)則為topic名稱+有序序號(hào),第一個(gè)partiton序號(hào)從0開(kāi)始感猛,序號(hào)最大值為partitions數(shù)量減1。

每個(gè)partion(目錄)相當(dāng)于一個(gè)巨型文件被平均分配到多個(gè)大小相等segment(段)數(shù)據(jù)文件中奢赂。但每個(gè)段segment file消息數(shù)量不一定相等陪白,這種特性方便old segment file快速被刪除。

每個(gè)partiton只需要支持順序讀寫(xiě)就行了膳灶,segment文件生命周期由服務(wù)端配置參數(shù)決定咱士。

這樣做的好處就是能快速刪除無(wú)用文件,有效提高磁盤(pán)利用率轧钓。

segment file組成:由2大部分組成序厉,分別為index file和data file,此2個(gè)文件一一對(duì)應(yīng)毕箍,成對(duì)出現(xiàn)弛房,后綴”.index”和“.log”分別表示為segment索引文件、數(shù)據(jù)文件而柑。

segment文件命名規(guī)則:partion全局的第一個(gè)segment從0開(kāi)始文捶,后續(xù)每個(gè)segment文件名為上一個(gè)segment文件最后一條消息的offset值。數(shù)值最大為64位long大小媒咳,19位數(shù)字字符長(zhǎng)度粹排,沒(méi)有數(shù)字用0填充。

segment中index與data file對(duì)應(yīng)關(guān)系物理結(jié)構(gòu)如下:

上圖中索引文件存儲(chǔ)大量元數(shù)據(jù)涩澡,數(shù)據(jù)文件存儲(chǔ)大量消息顽耳,索引文件中元數(shù)據(jù)指向?qū)?yīng)數(shù)據(jù)文件中message的物理偏移地址。

其中以索引文件中元數(shù)據(jù)3,497為例妙同,依次在數(shù)據(jù)文件中表示第3個(gè)message(在全局partiton表示第368772個(gè)message)射富,以及該消息的物理偏移地址為497。

了解到segment data file由許多message組成渐溶,下面詳細(xì)說(shuō)明message物理結(jié)構(gòu)如下:

副本(replication)策略

Kafka的高可靠性的保障來(lái)源于其健壯的副本(replication)策略辉浦。

1) 數(shù)據(jù)同步

kafka在0.8版本前沒(méi)有提供Partition的Replication機(jī)制,一旦Broker宕機(jī)茎辐,其上的所有Partition就都無(wú)法提供服務(wù)宪郊,而Partition又沒(méi)有備份數(shù)據(jù),數(shù)據(jù)的可用性就大大降低了拖陆。所以0.8后提供了Replication機(jī)制來(lái)保證Broker的failover弛槐。

引入Replication之后,同一個(gè)Partition可能會(huì)有多個(gè)Replica依啰,而這時(shí)需要在這些Replication之間選出一個(gè)Leader乎串,Producer和Consumer只與這個(gè)Leader交互,其它Replica作為Follower從Leader中復(fù)制數(shù)據(jù)速警。

2) 副本放置策略

為了更好的做負(fù)載均衡叹誉,Kafka盡量將所有的Partition均勻分配到整個(gè)集群上鸯两。Kafka分配Replica的算法如下:

將所有存活的N個(gè)Brokers和待分配的Partition排序

將第i個(gè)Partition分配到第(i mod n)個(gè)Broker上,這個(gè)Partition的第一個(gè)Replica存在于這個(gè)分配的Broker上长豁,并且會(huì)作為partition的優(yōu)先副本

將第i個(gè)Partition的第j個(gè)Replica分配到第((i + j) mod n)個(gè)Broker上

假設(shè)集群一共有4個(gè)brokers钧唐,一個(gè)topic有4個(gè)partition,每個(gè)Partition有3個(gè)副本匠襟。下圖是每個(gè)Broker上的副本分配情況钝侠。

3) 同步策略

Producer在發(fā)布消息到某個(gè)Partition時(shí),先通過(guò)ZooKeeper找到該P(yáng)artition的Leader酸舍,然后無(wú)論該Topic的Replication Factor為多少帅韧,Producer只將該消息發(fā)送到該P(yáng)artition的Leader。Leader會(huì)將該消息寫(xiě)入其本地Log啃勉。每個(gè)Follower都從Leader pull數(shù)據(jù)忽舟。這種方式上,F(xiàn)ollower存儲(chǔ)的數(shù)據(jù)順序與Leader保持一致璧亮。Follower在收到該消息并寫(xiě)入其Log后萧诫,向Leader發(fā)送ACK。一旦Leader收到了ISR中的所有Replica的ACK枝嘶,該消息就被認(rèn)為已經(jīng)commit了帘饶,Leader將增加HW并且向Producer發(fā)送ACK。

為了提高性能群扶,每個(gè)Follower在接收到數(shù)據(jù)后就立馬向Leader發(fā)送ACK及刻,而非等到數(shù)據(jù)寫(xiě)入Log中。因此竞阐,對(duì)于已經(jīng)commit的消息缴饭,Kafka只能保證它被存于多個(gè)Replica的內(nèi)存中,而不能保證它們被持久化到磁盤(pán)中骆莹,也就不能完全保證異常發(fā)生后該條消息一定能被Consumer消費(fèi)颗搂。

Consumer讀消息也是從Leader讀取,只有被commit過(guò)的消息才會(huì)暴露給Consumer幕垦。

Kafka Replication的數(shù)據(jù)流如下圖所示:

對(duì)于Kafka而言丢氢,定義一個(gè)Broker是否“活著”包含兩個(gè)條件:

一是它必須維護(hù)與ZooKeeper的session(這個(gè)通過(guò)ZooKeeper的Heartbeat機(jī)制來(lái)實(shí)現(xiàn))。

二是Follower必須能夠及時(shí)將Leader的消息復(fù)制過(guò)來(lái)先改,不能“落后太多”疚察。

Leader會(huì)跟蹤與其保持同步的Replica列表,該列表稱為ISR(即in-sync Replica)仇奶。如果一個(gè)Follower宕機(jī)貌嫡,或者落后太多,Leader將把它從ISR中移除。這里所描述的“落后太多”指Follower復(fù)制的消息落后于Leader后的條數(shù)超過(guò)預(yù)定值或者Follower超過(guò)一定時(shí)間未向Leader發(fā)送fetch請(qǐng)求岛抄。

Kafka只解決fail/recover别惦,一條消息只有被ISR里的所有Follower都從Leader復(fù)制過(guò)去才會(huì)被認(rèn)為已提交。這樣就避免了部分?jǐn)?shù)據(jù)被寫(xiě)進(jìn)了Leader夫椭,還沒(méi)來(lái)得及被任何Follower復(fù)制就宕機(jī)了步咪,而造成數(shù)據(jù)丟失(Consumer無(wú)法消費(fèi)這些數(shù)據(jù))。而對(duì)于Producer而言益楼,它可以選擇是否等待消息commit。這種機(jī)制確保了只要ISR有一個(gè)或以上的Follower点晴,一條被commit的消息就不會(huì)丟失感凤。

4) leader選舉

Leader選舉本質(zhì)上是一個(gè)分布式鎖,有兩種方式實(shí)現(xiàn)基于ZooKeeper的分布式鎖:

節(jié)點(diǎn)名稱唯一性:多個(gè)客戶端創(chuàng)建一個(gè)節(jié)點(diǎn)粒督,只有成功創(chuàng)建節(jié)點(diǎn)的客戶端才能獲得鎖

臨時(shí)順序節(jié)點(diǎn):所有客戶端在某個(gè)目錄下創(chuàng)建自己的臨時(shí)順序節(jié)點(diǎn)陪竿,只有序號(hào)最小的才獲得鎖

Majority Vote的選舉策略和ZooKeeper中的Zab選舉是類似的,實(shí)際上ZooKeeper內(nèi)部本身就實(shí)現(xiàn)了少數(shù)服從多數(shù)的選舉策略屠橄。kafka中對(duì)于Partition的leader副本的選舉采用了第一種方法:為Partition分配副本族跛,指定一個(gè)ZNode臨時(shí)節(jié)點(diǎn),第一個(gè)成功創(chuàng)建節(jié)點(diǎn)的副本就是Leader節(jié)點(diǎn)锐墙,其他副本會(huì)在這個(gè)ZNode節(jié)點(diǎn)上注冊(cè)Watcher監(jiān)聽(tīng)器礁哄,一旦Leader宕機(jī),對(duì)應(yīng)的臨時(shí)節(jié)點(diǎn)就會(huì)被自動(dòng)刪除溪北,這時(shí)注冊(cè)在該節(jié)點(diǎn)上的所有Follower都會(huì)收到監(jiān)聽(tīng)器事件桐绒,它們都會(huì)嘗試創(chuàng)建該節(jié)點(diǎn),只有創(chuàng)建成功的那個(gè)follower才會(huì)成為L(zhǎng)eader(ZooKeeper保證對(duì)于一個(gè)節(jié)點(diǎn)只有一個(gè)客戶端能創(chuàng)建成功)之拨,其他follower繼續(xù)重新注冊(cè)監(jiān)聽(tīng)事件茉继。

Kafka消息分組,消息消費(fèi)原理

同一Topic的一條消息只能被同一個(gè)Consumer Group內(nèi)的一個(gè)Consumer消費(fèi)蚀乔,但多個(gè)Consumer Group可同時(shí)消費(fèi)這一消息烁竭。

這是Kafka用來(lái)實(shí)現(xiàn)一個(gè)Topic消息的廣播(發(fā)給所有的Consumer)和單播(發(fā)給某一個(gè)Consumer)的手段。一個(gè)Topic可以對(duì)應(yīng)多個(gè)Consumer Group吉挣。如果需要實(shí)現(xiàn)廣播派撕,只要每個(gè)Consumer有一個(gè)獨(dú)立的Group就可以了。要實(shí)現(xiàn)單播只要所有的Consumer在同一個(gè)Group里听想。用Consumer Group還可以將Consumer進(jìn)行自由的分組而不需要多次發(fā)送消息到不同的Topic腥刹。

Push vs. Pull

作為一個(gè)消息系統(tǒng),Kafka遵循了傳統(tǒng)的方式汉买,選擇由Producer向broker push消息并由Consumer從broker pull消息衔峰。

push模式很難適應(yīng)消費(fèi)速率不同的消費(fèi)者,因?yàn)橄l(fā)送速率是由broker決定的。push模式的目標(biāo)是盡可能以最快速度傳遞消息垫卤,但是這樣很容易造成Consumer來(lái)不及處理消息威彰,典型的表現(xiàn)就是拒絕服務(wù)以及網(wǎng)絡(luò)擁塞。而pull模式則可以根據(jù)Consumer的消費(fèi)能力以適當(dāng)?shù)乃俾氏M(fèi)消息穴肘。

對(duì)于Kafka而言歇盼,pull模式更合適。pull模式可簡(jiǎn)化broker的設(shè)計(jì)评抚,Consumer可自主控制消費(fèi)消息的速率豹缀,同時(shí)Consumer可以自己控制消費(fèi)方式——即可批量消費(fèi)也可逐條消費(fèi),同時(shí)還能選擇不同的提交方式從而實(shí)現(xiàn)不同的傳輸語(yǔ)義慨代。

Kafak順序?qū)懭肱c數(shù)據(jù)讀取

生產(chǎn)者(producer)是負(fù)責(zé)向Kafka提交數(shù)據(jù)的邢笙,Kafka會(huì)把收到的消息都寫(xiě)入到硬盤(pán)中,它絕對(duì)不會(huì)丟失數(shù)據(jù)侍匙。為了優(yōu)化寫(xiě)入速度Kafak采用了兩個(gè)技術(shù)氮惯,順序?qū)懭牒蚆MFile。

順序?qū)懭?/p>

因?yàn)橛脖P(pán)是機(jī)械結(jié)構(gòu)想暗,每次讀寫(xiě)都會(huì)尋址妇汗,寫(xiě)入,其中尋址是一個(gè)“機(jī)械動(dòng)作”说莫,它是最耗時(shí)的杨箭。所以硬盤(pán)最“討厭”隨機(jī)I/O,最喜歡順序I/O储狭。為了提高讀寫(xiě)硬盤(pán)的速度告唆,Kafka就是使用順序I/O。

每條消息都被append到該P(yáng)artition中晶密,屬于順序?qū)懘疟P(pán)擒悬,因此效率非常高。

對(duì)于傳統(tǒng)的message queue而言稻艰,一般會(huì)刪除已經(jīng)被消費(fèi)的消息懂牧,而Kafka是不會(huì)刪除數(shù)據(jù)的,它會(huì)把所有的數(shù)據(jù)都保留下來(lái)尊勿,每個(gè)消費(fèi)者(Consumer)對(duì)每個(gè)Topic都有一個(gè)offset用來(lái)表示讀取到了第幾條數(shù)據(jù)僧凤。

即便是順序?qū)懭胗脖P(pán),硬盤(pán)的訪問(wèn)速度還是不可能追上內(nèi)存元扔。所以Kafka的數(shù)據(jù)并不是實(shí)時(shí)的寫(xiě)入硬盤(pán)躯保,它充分利用了現(xiàn)代操作系統(tǒng)分頁(yè)存儲(chǔ)來(lái)利用內(nèi)存提高I/O效率。

在Linux Kernal 2.2之后出現(xiàn)了一種叫做“零拷貝(zero-copy)”系統(tǒng)調(diào)用機(jī)制澎语,就是跳過(guò)“用戶緩沖區(qū)”的拷貝途事,建立一個(gè)磁盤(pán)空間和內(nèi)存空間的直接映射验懊,數(shù)據(jù)不再?gòu)?fù)制到“用戶態(tài)緩沖區(qū)”系統(tǒng)上下文切換減少2次,可以提升一倍性能尸变。

通過(guò)mmap义图,進(jìn)程像讀寫(xiě)硬盤(pán)一樣讀寫(xiě)內(nèi)存(當(dāng)然是虛擬機(jī)內(nèi)存)。使用這種方式可以獲取很大的I/O提升召烂,省去了用戶空間到內(nèi)核空間復(fù)制的開(kāi)銷(調(diào)用文件的read會(huì)把數(shù)據(jù)先放到內(nèi)核空間的內(nèi)存中碱工,然后再?gòu)?fù)制到用戶空間的內(nèi)存中。)

消費(fèi)者(讀取數(shù)據(jù))

試想一下奏夫,一個(gè)Web Server傳送一個(gè)靜態(tài)文件怕篷,如何優(yōu)化?答案是zero copy酗昼。傳統(tǒng)模式下我們從硬盤(pán)讀取一個(gè)文件是這樣的匙头。

先復(fù)制到內(nèi)核空間(read是系統(tǒng)調(diào)用,放到了DMA仔雷,所以用內(nèi)核空間),然后復(fù)制到用戶空間(1舔示、2)碟婆;從用戶空間重新復(fù)制到內(nèi)核空間(你用的socket是系統(tǒng)調(diào)用,所以它也有自己的內(nèi)核空間)惕稻,最后發(fā)送給網(wǎng)卡(3竖共、4)。

Zero Copy中直接從內(nèi)核空間(DMA的)到內(nèi)核空間(Socket的)俺祠,然后發(fā)送網(wǎng)卡公给。這個(gè)技術(shù)非常普遍,Nginx也是用的這種技術(shù)蜘渣。

實(shí)際上淌铐,Kafka把所有的消息都存放在一個(gè)一個(gè)的文件中,當(dāng)消費(fèi)者需要數(shù)據(jù)的時(shí)候Kafka直接把“文件”發(fā)送給消費(fèi)者蔫缸。當(dāng)不需要把整個(gè)文件發(fā)出去的時(shí)候腿准,Kafka通過(guò)調(diào)用Zero Copy的sendfile這個(gè)函數(shù),這個(gè)函數(shù)包括:

out_fd作為輸出(一般及時(shí)socket的句柄)

in_fd作為輸入文件句柄

off_t表示in_fd的偏移(從哪里開(kāi)始讀仁奥怠)

size_t表示讀取多少個(gè)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吐葱,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子校翔,更是在濱河造成了極大的恐慌弟跑,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異网杆,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)桥温,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門扑浸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烧给,“玉大人,你說(shuō)我怎么就攤上這事喝噪〈〉眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵酝惧,是天一觀的道長(zhǎng)榴鼎。 經(jīng)常有香客問(wèn)我,道長(zhǎng)晚唇,這世上最難降的妖魔是什么巫财? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮哩陕,結(jié)果婚禮上平项,老公的妹妹穿的比我還像新娘。我一直安慰自己悍及,他們只是感情好闽瓢,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著心赶,像睡著了一般扣讼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缨叫,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天椭符,我揣著相機(jī)與錄音,去河邊找鬼耻姥。 笑死销钝,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琐簇。 我是一名探鬼主播曙搬,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼鸽嫂!你這毒婦竟也來(lái)了纵装?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤据某,失蹤者是張志新(化名)和其女友劉穎橡娄,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體癣籽,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挽唉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年滤祖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓶籽。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡匠童,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出塑顺,到底是詐尸還是另有隱情汤求,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布严拒,位于F島的核電站扬绪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏裤唠。R本人自食惡果不足惜挤牛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望种蘸。 院中可真熱鬧墓赴,春花似錦、人聲如沸航瞭。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)沧奴。三九已至,卻和暖如春长窄,著一層夾襖步出監(jiān)牢的瞬間滔吠,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工挠日, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疮绷,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓嚣潜,卻偏偏與公主長(zhǎng)得像冬骚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子懂算,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

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

  • 沒(méi)有選擇的選擇也是選擇 這兩天讀了陳海賢老師的自我發(fā)展心理學(xué)只冻,我感覺(jué)挺有意思的,其中有一個(gè)是沒(méi)有選擇的選擇也是選擇...
    Dflower閱讀 342評(píng)論 1 0
  • 祖國(guó).我愛(ài)您 (2009國(guó)慶獻(xiàn)歌) 作者/田子 祖國(guó) 我愛(ài)您 我愛(ài)您五千年的燦爛歷史文明 愛(ài)您像巨龍一樣屹立在世界...
    狼煙詩(shī)影閱讀 196評(píng)論 0 4
  • 控制內(nèi)心的不安 不再猜忌 愿意相信 活得太清醒 不如睜一只眼 閉一只眼 人生的單選題太多 選擇就代表放棄 放棄總有無(wú)奈
    CarmenQ閱讀 162評(píng)論 0 0