自頂向下深入分析Netty(六)--Channel總述

Netty架構(gòu)模式

回顧這幅圖爪幻,目前為止菱皆,我們明白了兩個(gè)Reactor、acceptor以及異步結(jié)果的原理挨稿。在這一章中仇轻,我們將分析圖中的箭頭部分,將各部件連接起來奶甘。進(jìn)行連接的關(guān)鍵部件正是本章的主角Channel篷店,Channel是網(wǎng)絡(luò)Socket進(jìn)行聯(lián)系的紐帶,可以完成諸如讀臭家、寫疲陕、連接、綁定等I/O操作钉赁。

6.1 總述

6.1.1 Channel

JDK中的Channel是通訊的載體蹄殃,而Netty中的Channel在此基礎(chǔ)上進(jìn)行封裝從而賦予了Channel更多的能力,用戶可以使用Channel進(jìn)行以下操作:

  • 查詢Channel的狀態(tài)你踩。
  • 配置Channel的參數(shù)窃爷。
  • 進(jìn)行Channel支持的I/O操作(read,write姓蜂,connect,bind)医吊。
  • 獲取對(duì)應(yīng)的ChannelPipeline钱慢,從而可以自定義處理I/O事件或者其他請(qǐng)求。

為了保證在使用Channel或者處理I/O操作時(shí)不出現(xiàn)錯(cuò)誤卿堂,以下幾點(diǎn)需要特別注意:

  1. 所有的I/O操作都是異步的
    由于采用事件驅(qū)動(dòng)的機(jī)制束莫,所以Netty中的所有IO操作都是異步的。這意味著當(dāng)我們調(diào)用一個(gè)IO操作時(shí)草描,方法會(huì)立即返回并不保證操作已經(jīng)完成览绿。由上一章Future的講解中,我們知道穗慕,這些IO操作會(huì)返回一個(gè)ChannelFuture對(duì)象饿敲,我們需要通過添加監(jiān)聽者的方式執(zhí)行操作完成后需執(zhí)行的代碼。
  2. Channel是有等級(jí)的
    如果一個(gè)Channel由另一個(gè)Channel創(chuàng)建逛绵,那么他們之間形成父子關(guān)系怀各。比如說倔韭,當(dāng)ServerSocketChannel通過accept()方法接受一個(gè)SocketChannel時(shí),那么SocketChannel的父親是ServerSocketChannel瓢对,調(diào)用SocketChannel的parent()方法返回該ServerSocketChannel對(duì)象寿酌。
  3. 可以使用向下轉(zhuǎn)型獲取子類的特定操作
    某些子類Channel會(huì)提供一些所需的特定操作,可以向下轉(zhuǎn)型到這樣的子類硕蛹,從而獲得特定操作醇疼。比如說,對(duì)于UDP的數(shù)據(jù)報(bào)的傳輸法焰,有特定的join()和leave()操作秧荆,我們可以向下轉(zhuǎn)型到DatagramChannel從而使用這些操作。
  4. 釋放資源
    當(dāng)一個(gè)Channel不再使用時(shí)壶栋,須調(diào)用close()或者close(ChannelPromise)方法釋放資源辰如。

6.1.2 Channel配置參數(shù)

(1).通用參數(shù)

CONNECT_TIMEOUT_MILLIS
????????Netty參數(shù),連接超時(shí)毫秒數(shù)贵试,默認(rèn)值30000毫秒即30秒琉兜。

MAX_MESSAGES_PER_READ
????????Netty參數(shù),一次Loop讀取的最大消息數(shù)毙玻,對(duì)于ServerChannel或者NioByteChannel豌蟋,默認(rèn)值為16,其他Channel默認(rèn)值為1桑滩。默認(rèn)值這樣設(shè)置梧疲,是因?yàn)椋篠erverChannel需要接受足夠多的連接,保證大吞吐量运准,NioByteChannel可以減少不必要的系統(tǒng)調(diào)用select幌氮。

WRITE_SPIN_COUNT
????????Netty參數(shù),一個(gè)Loop寫操作執(zhí)行的最大次數(shù)胁澳,默認(rèn)值為16该互。也就是說,對(duì)于大數(shù)據(jù)量的寫操作至多進(jìn)行16次韭畸,如果16次仍沒有全部寫完數(shù)據(jù)宇智,此時(shí)會(huì)提交一個(gè)新的寫任務(wù)給EventLoop,任務(wù)將在下次調(diào)度繼續(xù)執(zhí)行胰丁。這樣随橘,其他的寫請(qǐng)求才能被響應(yīng)不會(huì)因?yàn)閱蝹€(gè)大數(shù)據(jù)量寫請(qǐng)求而耽誤。

ALLOCATOR
????????Netty參數(shù)锦庸,ByteBuf的分配器机蔗,默認(rèn)值為ByteBufAllocator.DEFAULT,4.0版本為UnpooledByteBufAllocator,4.1版本為PooledByteBufAllocator蜒车。該值也可以使用系統(tǒng)參數(shù)io.netty.allocator.type配置讳嘱,使用字符串值:"unpooled","pooled"酿愧。

RCVBUF_ALLOCATOR
????????Netty參數(shù)沥潭,用于Channel分配接受Buffer的分配器,默認(rèn)值為AdaptiveRecvByteBufAllocator.DEFAULT嬉挡,是一個(gè)自適應(yīng)的接受緩沖區(qū)分配器钝鸽,能根據(jù)接受到的數(shù)據(jù)自動(dòng)調(diào)節(jié)大小∨痈郑可選值為FixedRecvByteBufAllocator拔恰,固定大小的接受緩沖區(qū)分配器。

AUTO_READ
????????Netty參數(shù)基括,自動(dòng)讀取颜懊,默認(rèn)值為True。Netty只在必要的時(shí)候才設(shè)置關(guān)心相應(yīng)的I/O事件风皿。對(duì)于讀操作河爹,需要調(diào)用channel.read()設(shè)置關(guān)心的I/O事件為OP_READ,這樣若有數(shù)據(jù)到達(dá)才能讀取以供用戶處理桐款。該值為True時(shí)咸这,每次讀操作完畢后會(huì)自動(dòng)調(diào)用channel.read(),從而有數(shù)據(jù)到達(dá)便能讀饶д!媳维;否則,需要用戶手動(dòng)調(diào)用channel.read()遏暴。需要注意的是:當(dāng)調(diào)用config.setAutoRead(boolean)方法時(shí)侄刽,如果狀態(tài)由false變?yōu)閠rue,將會(huì)調(diào)用channel.read()方法讀取數(shù)據(jù)朋凉;由true變?yōu)閒alse唠梨,將調(diào)用config.autoReadCleared()方法終止數(shù)據(jù)讀取。

WRITE_BUFFER_HIGH_WATER_MARK
????????Netty參數(shù)侥啤,寫高水位標(biāo)記,默認(rèn)值64KB茬故。如果Netty的寫緩沖區(qū)中的字節(jié)超過該值盖灸,Channel的isWritable()返回False。

WRITE_BUFFER_LOW_WATER_MARK
????????Netty參數(shù)磺芭,寫低水位標(biāo)記赁炎,默認(rèn)值32KB。當(dāng)Netty的寫緩沖區(qū)中的字節(jié)超過高水位之后若下降到低水位,則Channel的isWritable()返回True徙垫。寫高低水位標(biāo)記使用戶可以控制寫入數(shù)據(jù)速度讥裤,從而實(shí)現(xiàn)流量控制。推薦做法是:每次調(diào)用channl.write(msg)方法首先調(diào)用channel.isWritable()判斷是否可寫姻报。

MESSAGE_SIZE_ESTIMATOR
????????Netty參數(shù)己英,消息大小估算器,默認(rèn)為DefaultMessageSizeEstimator.DEFAULT吴旋。估算ByteBuf损肛、ByteBufHolder和FileRegion的大小,其中ByteBuf和ByteBufHolder為實(shí)際大小荣瑟,F(xiàn)ileRegion估算值為0治拿。該值估算的字節(jié)數(shù)在計(jì)算水位時(shí)使用,F(xiàn)ileRegion為0可知FileRegion不影響高低水位笆焰。

SINGLE_EVENTEXECUTOR_PER_GROUP
????????Netty參數(shù)劫谅,單線程執(zhí)行ChannelPipeline中的事件,默認(rèn)值為True嚷掠。該值控制執(zhí)行ChannelPipeline中執(zhí)行ChannelHandler的線程捏检。如果為Trye,整個(gè)pipeline由一個(gè)線程執(zhí)行叠国,這樣不需要進(jìn)行線程切換以及線程同步未檩,是Netty4的推薦做法;如果為False粟焊,ChannelHandler中的處理過程會(huì)由Group中的不同線程執(zhí)行冤狡。

(2).SocketChannel參數(shù)

SO_RCVBUF
????????Socket參數(shù),TCP數(shù)據(jù)接收緩沖區(qū)大小项棠。該緩沖區(qū)即TCP接收滑動(dòng)窗口悲雳,linux操作系統(tǒng)可使用命令:cat /proc/sys/net/ipv4/tcp_rmem查詢其大小。一般情況下香追,該值可由用戶在任意時(shí)刻設(shè)置合瓢,但當(dāng)設(shè)置值超過64KB時(shí),需要在連接到遠(yuǎn)端之前設(shè)置透典。

SO_SNDBUF
????????Socket參數(shù)晴楔,TCP數(shù)據(jù)發(fā)送緩沖區(qū)大小。該緩沖區(qū)即TCP發(fā)送滑動(dòng)窗口峭咒,linux操作系統(tǒng)可使用命令:cat /proc/sys/net/ipv4/tcp_smem查詢其大小税弃。

TCP_NODELAY
????????TCP參數(shù),立即發(fā)送數(shù)據(jù)凑队,默認(rèn)值為Ture(Netty默認(rèn)為True而操作系統(tǒng)默認(rèn)為False)则果。該值設(shè)置Nagle算法的啟用,改算法將小的碎片數(shù)據(jù)連接成更大的報(bào)文來最小化所發(fā)送的報(bào)文的數(shù)量,如果需要發(fā)送一些較小的報(bào)文西壮,則需要禁用該算法遗增。Netty默認(rèn)禁用該算法,從而最小化報(bào)文傳輸延時(shí)款青。

SO_KEEPALIVE
????????Socket參數(shù)做修,連接保活可都,默認(rèn)值為False缓待。啟用該功能時(shí),TCP會(huì)主動(dòng)探測(cè)空閑連接的有效性渠牲⌒矗可以將此功能視為TCP的心跳機(jī)制,需要注意的是:默認(rèn)的心跳間隔是7200s即2小時(shí)签杈。Netty默認(rèn)關(guān)閉該功能瘫镇。

SO_REUSEADDR
????????Socket參數(shù),地址復(fù)用答姥,默認(rèn)值False铣除。有四種情況可以使用:(1).當(dāng)有一個(gè)有相同本地地址和端口的socket1處于TIME_WAIT狀態(tài)時(shí),而你希望啟動(dòng)的程序的socket2要占用該地址和端口鹦付,比如重啟服務(wù)且保持先前端口尚粘。(2).有多塊網(wǎng)卡或用IP Alias技術(shù)的機(jī)器在同一端口啟動(dòng)多個(gè)進(jìn)程,但每個(gè)進(jìn)程綁定的本地IP地址不能相同敲长。(3).單個(gè)進(jìn)程綁定相同的端口到多個(gè)socket上郎嫁,但每個(gè)socket綁定的ip地址不同。(4).完全相同的地址和端口的重復(fù)綁定祈噪。但這只用于UDP的多播泽铛,不用于TCP。

SO_LINGER
???????? Netty對(duì)底層Socket參數(shù)的簡(jiǎn)單封裝辑鲤,關(guān)閉Socket的延遲時(shí)間盔腔,默認(rèn)值為-1,表示禁用該功能月褥。-1以及所有<0的數(shù)表示socket.close()方法立即返回弛随,但OS底層會(huì)將發(fā)送緩沖區(qū)全部發(fā)送到對(duì)端。0表示socket.close()方法立即返回宁赤,OS放棄發(fā)送緩沖區(qū)的數(shù)據(jù)直接向?qū)Χ税l(fā)送RST包撵幽,對(duì)端收到復(fù)位錯(cuò)誤。非0整數(shù)值表示調(diào)用socket.close()方法的線程被阻塞直到延遲時(shí)間到或發(fā)送緩沖區(qū)中的數(shù)據(jù)發(fā)送完畢礁击,若超時(shí),則對(duì)端會(huì)收到復(fù)位錯(cuò)誤。

IP_TOS
????????IP參數(shù)哆窿,設(shè)置IP頭部的Type-of-Service字段链烈,用于描述IP包的優(yōu)先級(jí)和QoS選項(xiàng)。

ALLOW_HALF_CLOSURE
????????Netty參數(shù)挚躯,一個(gè)連接的遠(yuǎn)端關(guān)閉時(shí)本地端是否關(guān)閉强衡,默認(rèn)值為False。值為False時(shí)码荔,連接自動(dòng)關(guān)閉漩勤;為True時(shí),觸發(fā)ChannelInboundHandler的userEventTriggered()方法缩搅,事件為ChannelInputShutdownEvent越败。

(3).ServerSocketChannel參數(shù)

SO_RCVBUF
????????已說明,需要注意的是:當(dāng)設(shè)置值超過64KB時(shí)硼瓣,需要在綁定到本地端口前設(shè)置究飞。該值設(shè)置的是由ServerSocketChannel使用accept接受的SocketChannel的接收緩沖區(qū)。

SO_REUSEADDR
????????已說明

SO_BACKLOG
????????Socket參數(shù)堂鲤,服務(wù)端接受連接的隊(duì)列長(zhǎng)度亿傅,如果隊(duì)列已滿,客戶端連接將被拒絕瘟栖。默認(rèn)值葵擎,Windows為200,其他為128半哟。

(4).DatagramChannel參數(shù)

SO_BROADCAST
????????Socket參數(shù)酬滤,設(shè)置廣播模式。

SO_RCVBUF
????????已說明

SO_SNDBUF
????????已說明

SO_REUSEADDR
????????已說明

IP_MULTICAST_LOOP_DISABLED
????????對(duì)應(yīng)IP參數(shù)IP_MULTICAST_LOOP镜沽,設(shè)置本地回環(huán)接口的多播功能敏晤。由于IP_MULTICAST_LOOP返回True表示關(guān)閉,所以Netty加上后綴_DISABLED防止歧義缅茉。

IP_MULTICAST_ADDR
????????對(duì)應(yīng)IP參數(shù)IP_MULTICAST_IF嘴脾,設(shè)置對(duì)應(yīng)地址的網(wǎng)卡為多播模式。

IP_MULTICAST_IF
????????對(duì)應(yīng)IP參數(shù)IP_MULTICAST_IF2蔬墩,同上但支持IPV6译打。

IP_MULTICAST_TTL
????????IP參數(shù),多播數(shù)據(jù)報(bào)的time-to-live即存活跳數(shù)拇颅。

IP_TOS
????????已說明

DATAGRAM_CHANNEL_ACTIVE_ON_REGISTRATION
????????Netty參數(shù)奏司,DatagramChannel注冊(cè)的EventLoop即表示已激活。


6.1.3 Channel接口

Channel接口中含有大量的方法樟插,我們先對(duì)這些方法分類:

  1. 狀態(tài)查詢
    boolean isOpen(); // 是否開放
    boolean isRegistered(); // 是否注冊(cè)到一個(gè)EventLoop
    boolean isActive(); // 是否激活
    boolean isWritable();   // 是否可寫

open表示Channel的開放狀態(tài)韵洋,True表示Channel可用竿刁,F(xiàn)alse表示Channel已關(guān)閉不再可用。registered表示Channel的注冊(cè)狀態(tài)搪缨,True表示已注冊(cè)到一個(gè)EventLoop食拜,F(xiàn)alse表示沒有注冊(cè)到EventLoop。active表示Channel的激活狀態(tài)副编,對(duì)于ServerSocketChannel负甸,True表示Channel已綁定到端口;對(duì)于SocketChannel痹届,表示Channel可用(open)且已連接到對(duì)端呻待。Writable表示Channel的可寫狀態(tài),當(dāng)Channel的寫緩沖區(qū)outboundBuffer非null且可寫時(shí)返回True队腐。
一個(gè)正常結(jié)束的Channel狀態(tài)轉(zhuǎn)移有以下兩種情況:

    REGISTERED->CONNECT/BIND->ACTIVE->CLOSE->INACTIVE->UNREGISTERED 
    REGISTERED->ACTIVE->CLOSE->INACTIVE->UNREGISTERED

其中第一種是服務(wù)端用于綁定的Channel或者客戶端用于發(fā)起連接的Channel蚕捉,第二種是服務(wù)端接受的SocketChannel。一個(gè)異常關(guān)閉的Channel則不會(huì)服從這樣的狀態(tài)轉(zhuǎn)移香到。

  1. getter方法
    EventLoop eventLoop();  // 注冊(cè)到的EventLoop
    Channel parent();   // 父類Channel
    ChannelConfig config(); // 配置參數(shù)
    ChannelMetadata metadata(); // 元數(shù)據(jù)
    SocketAddress localAddress();   // 本地地址
    SocketAddress remoteAddress();  // 遠(yuǎn)端地址
    Unsafe unsafe();    // Unsafe對(duì)象
    ChannelPipeline pipeline(); // 事件管道鱼冀,用于處理IO事件
    ByteBufAllocator alloc();   // 字節(jié)緩存分配器
    ChannelFuture closeFuture();    // Channel關(guān)閉時(shí)的異步結(jié)果
    ChannelPromise voidPromise();   
  1. 異步結(jié)果生成
    ChannelPromise newPromise();
    ChannelFuture newSucceededFuture();
    ChannelFuture newFailedFuture(Throwable cause);
  1. I/O事件處理
    ChannelFuture bind(SocketAddress localAddress);
    ChannelFuture connect(SocketAddress remoteAddress);
    ChannelFuture disconnect();
    ChannelFuture close();
    ChannelFuture deregister();
    Channel read();
    ChannelFuture write(Object msg);
    Channel flush();
    ChannelFuture writeAndFlush(Object msg);

這里的I/O事件都是outbound出站事件,表示由用戶發(fā)起悠就,即用戶可以調(diào)用這些方法產(chǎn)生響應(yīng)的事件千绪。對(duì)應(yīng)地,有inbound入站事件梗脾,將在ChnanelPipeline一節(jié)中詳述荸型。


6.1.4 Unsafe

Unsafe?直譯中文為不安全炸茧,這曾給我?guī)順O大的困擾瑞妇。如果你是第一次遇到這種接口,一定會(huì)和我感同身受梭冠。一個(gè)Unsafe對(duì)象是不安全的辕狰?這里說的不安全,是相對(duì)于用戶程序員而言的控漠,也就是說蔓倍,用戶程序員使用Netty進(jìn)行編程時(shí)不會(huì)接觸到這個(gè)接口和相關(guān)類。為什么不會(huì)接觸到呢盐捷?因?yàn)轭愃频慕涌诤皖愂荖etty的大量?jī)?nèi)部實(shí)現(xiàn)細(xì)節(jié)偶翅,不會(huì)暴露給用戶程序員。然而我們的目標(biāo)是自頂向下深入分析Netty碉渡,所以有必要深入U(xiǎn)nsafe雷區(qū)聚谁。我們先看Unsafe接口中的方法:

    SocketAddress localAddress();   // 本地地址
    SocketAddress remoteAddress();  // 遠(yuǎn)端地址
    ChannelPromise voidPromise();   // 不關(guān)心結(jié)果的異步Promise?
    ChannelOutboundBuffer outboundBuffer(); // 寫緩沖區(qū)
    void register(EventLoop eventLoop, ChannelPromise promise);
    void bind(SocketAddress localAddress, ChannelPromise promise);
    void connect(SocketAddress remoteAddress, SocketAddress localAddress, 
                              ChannelPromise promise);
    void disconnect(ChannelPromise promise);
    void close(ChannelPromise promise);
    void closeForcibly();
    void deregister(ChannelPromise promise);
    void beginRead();
    void write(Object msg, ChannelPromise promise);
    void flush();

也許你已經(jīng)發(fā)現(xiàn)Unsafe接口和Channel接口中都有register滞诺、bind等I/O事件相關(guān)的方法形导,它們有什么區(qū)別呢环疼?回憶一下EventLoop線程實(shí)現(xiàn),當(dāng)一個(gè)selectedKey就緒時(shí)朵耕,對(duì)I/O事件的處理委托給unsafe對(duì)象實(shí)現(xiàn)秦爆,代碼類似如下:

    if ((readyOps & SelectionKey.OP_CONNECT) != 0) {
        k.interestOps(k.interestOps() & ~SelectionKey.OP_CONNECT); 
        unsafe.finishConnect(); 
    }
    if ((readyOps & (SelectionKey.OP_READ | SelectionKey.OP_ACCEPT)) != 0
                  || readyOps == 0) {
        unsafe.read(); 
    }
    if ((readyOps & SelectionKey.OP_WRITE) != 0) {
        ch.unsafe().forceFlush();
    }

也就是說,Unsafe的子類作為Channel的內(nèi)部類憔披,負(fù)責(zé)處理底層NIO相關(guān)的I/O事件。Channel則使用責(zé)任鏈的方式通過ChannelPipeline將事件提供給用戶自定義處理爸吮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末芬膝,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子形娇,更是在濱河造成了極大的恐慌锰霜,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件桐早,死亡現(xiàn)場(chǎng)離奇詭異癣缅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)哄酝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門友存,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人陶衅,你說我怎么就攤上這事屡立。” “怎么了搀军?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵膨俐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我罩句,道長(zhǎng)焚刺,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任门烂,我火速辦了婚禮乳愉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘诅福。我一直安慰自己匾委,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布氓润。 她就那樣靜靜地躺著赂乐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪咖气。 梳的紋絲不亂的頭發(fā)上挨措,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天挖滤,我揣著相機(jī)與錄音,去河邊找鬼浅役。 笑死斩松,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的觉既。 我是一名探鬼主播惧盹,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼瞪讼!你這毒婦竟也來了钧椰?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤符欠,失蹤者是張志新(化名)和其女友劉穎嫡霞,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體希柿,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诊沪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了曾撤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片端姚。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖盾戴,靈堂內(nèi)的尸體忽然破棺而出寄锐,到底是詐尸還是另有隱情,我是刑警寧澤尖啡,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布橄仆,位于F島的核電站,受9級(jí)特大地震影響衅斩,放射性物質(zhì)發(fā)生泄漏盆顾。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一畏梆、第九天 我趴在偏房一處隱蔽的房頂上張望您宪。 院中可真熱鬧,春花似錦奠涌、人聲如沸宪巨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)捏卓。三九已至,卻和暖如春慈格,著一層夾襖步出監(jiān)牢的瞬間怠晴,已是汗流浹背遥金。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒜田,地道東北人稿械。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冲粤,于是被迫代替她去往敵國(guó)和親美莫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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