真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

七天慢慢學(xué)Netty(第三天)-創(chuàng)新互聯(lián)

Bootstrap
  • Bootstrap是引導(dǎo)的意思,它的作用是配置整個(gè)Netty程序,將各個(gè)組件都串起來,最后綁定端口、啟動(dòng) Netty服務(wù)
  • Netty中提供了2種類型的引導(dǎo)類,一種用于客戶端(Bootstrap),而另一種(ServerBootstrap)用于服務(wù)器 ,區(qū)別在于: 1、ServerBootstrap 將綁定到一個(gè)端口,因?yàn)榉?wù)器必須要監(jiān)聽連接,而 Bootstrap 則是由想要連接 到遠(yuǎn)程節(jié)點(diǎn)的客戶端應(yīng)用程序所使用的 2、引導(dǎo)一個(gè)客戶端只需要一個(gè)EventLoopGroup,但是一個(gè)ServerBootstrap則需要兩個(gè)
Channel

? Netty中的Channel是與網(wǎng)絡(luò)套接字相關(guān)的,可以理解為是socket連接,在客戶端與服務(wù)端連接的時(shí)候就會(huì) 建立一個(gè)Channel,它負(fù)責(zé)基本的IO操作,比如:bind()、connect(),read(),write() 等 ? 主要作用:

站在用戶的角度思考問題,與客戶深入溝通,找到鶴慶網(wǎng)站設(shè)計(jì)與鶴慶網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、空間域名、網(wǎng)站空間、企業(yè)郵箱。業(yè)務(wù)覆蓋鶴慶地區(qū)。

1. 通過Channel可獲得當(dāng)前網(wǎng)絡(luò)連接的通道狀態(tài)。

2. 通過Channel可獲得網(wǎng)絡(luò)連接的配置參數(shù)(緩沖區(qū)大小等)。

3. Channel提供異步的網(wǎng)絡(luò)I/O操作,比如連接的建立、數(shù)據(jù)的讀寫、端口的綁定等。

? 不同協(xié)議、不同的I/O類型的連接都有不同的 Channel 類型與之對(duì)

EventLoopGroup&EventLoop

? Netty是基于事件驅(qū)動(dòng)的,比如:連接注冊(cè),連接激活;數(shù)據(jù)讀?。划惓J录鹊?,有了事件,就需要一 個(gè)組件去監(jiān)控事件的產(chǎn)生和事件的協(xié)調(diào)處理,這個(gè)組件就是EventLoop(事件循環(huán)/EventExecutor),在 Netty 中每個(gè)Channel 都會(huì)被分配到一個(gè) EventLoop。一個(gè) EventLoop 可以服務(wù)于多個(gè) Channel。每個(gè) EventLoop 會(huì)占用一個(gè) Thread,同時(shí)這個(gè) Thread 會(huì)處理 EventLoop 上面發(fā)生的所有 IO 操作和事件。

? EventLoopGroup 是用來生成 EventLoop 的,包含了一組EventLoop(可以初步理解成Netty線程池)

eventLoopThreads 是多少?

EventLoopGroup 是接口,我們采用的實(shí)現(xiàn)是NioEventLoopGroup

// 主線程,不處理任何業(yè)務(wù)邏輯,只是接收客戶的連接請(qǐng)求

EventLoopGroup boss = new NioEventLoopGroup();

// 工作線程,處理注冊(cè)其上Channel的I/O事件及其他

Task EventLoopGroup worker = new NioEventLoopGroup();

?核心線程數(shù)默認(rèn):cpu核數(shù)*2

?核心線程數(shù)在創(chuàng)建時(shí)可通過構(gòu)造函數(shù)指定

?對(duì)于boss group,我們其實(shí)也 只用到了其中的一個(gè)線程因?yàn)榉?wù)端一般只會(huì)綁定一個(gè)端口啟動(dòng)

ChannelHandler&ChannelHandlerContext&ChannelPipeline

(這些組件比較重要,單獨(dú)在netty從入門到精通(中)詳細(xì)做了介紹)

netty從入門到精通(中)http://t.csdn.cn/DDMaA

ChannelHandler復(fù)用

每個(gè)客戶端Channel創(chuàng)建后初始化時(shí), 均會(huì)向與該Channel綁定的Pipeline中 添加handler,此種模式下,每個(gè) Channel享有的是各自獨(dú)立的Handler

@Sharable注解可以解決這個(gè)問題

備注:handler被復(fù)用可能導(dǎo)致線程安全問題,比如在handler中操作成員變量。線程安全的問題需要開發(fā)者自行保證。

ChannelInboundHandlerAdapter&SimpleChannelInboundHandler

對(duì)于編寫Netty數(shù)據(jù)入站處理器,可以選擇繼承 ChannelInboundHandlerAdapter,也可以選擇繼承 SimpleChannelInboundHandler,區(qū)別是什么?

ByteBuf

概念和作用:

? Java NIO 提供了ByteBuffer 作為它的字節(jié)容器,但是這個(gè)類使用起來過于復(fù)雜,而且也有些繁瑣。Netty 使用ByteBuf來替代ByteBuffer,它是一個(gè)強(qiáng)大的實(shí)現(xiàn),既解決了JDK API 的局限性, 又為網(wǎng)絡(luò)應(yīng)用程序的 開發(fā)者提供了更好的API

? 從結(jié)構(gòu)上來說,ByteBuf 由一串字節(jié)數(shù)組構(gòu)成。數(shù)組中每個(gè)字節(jié)用來存放信息,ByteBuf提供了兩個(gè)索引, 一個(gè)用于讀取數(shù)據(jù)(readerIndex ),一個(gè)用于寫入數(shù)據(jù)(writerIndex)。這兩個(gè)索引通過在字節(jié)數(shù)組中 移動(dòng),來定位需要讀或者寫信息的位置。而JDK的ByteBuffer只有一個(gè)索引,因此需要使用flip方法進(jìn)行讀 寫切換

ByteBuf的三個(gè)指針

? readerIndex:指示讀取的起始位置, 每讀取一個(gè)字節(jié), readerIndex自增累加1。 如果readerIndex 與 writerIndex 相等,ByteBuf 不可讀。

? writerIndex:指示寫入的起始位置, 每寫入一個(gè)字節(jié), writeIndex自增累加1。如果增加到 writerIndex 與 capacity() 容量相等,表示 ByteBuf 已經(jīng)不可寫,但是這個(gè)時(shí)候,并不代表不能往 ByteBuf 中寫數(shù)據(jù)了, 如果 發(fā)現(xiàn)往ByteBuf 中寫數(shù)據(jù)寫不進(jìn)去的話,Netty 會(huì)自動(dòng)擴(kuò)容 ByteBuf,直到擴(kuò)容到底層的內(nèi)存大小為 maxCapacity

? maxCapacity:指示ByteBuf 可以擴(kuò)容的大容量, 如果向ByteBuf寫入數(shù)據(jù)時(shí), 容量不足, 可以進(jìn)行擴(kuò)容的最 大容量

常用API

容量API:

  1. ? capacity():表示 ByteBuf 底層占用了多少字節(jié)的內(nèi)存(包括丟棄的字節(jié)、可讀字節(jié)、可寫字節(jié)),不同的底層實(shí) 現(xiàn)機(jī)制有不同的計(jì)算方式。
  2. ? maxCapacity(): ByteBuf 底層大能夠占用多少字節(jié)的內(nèi)存,當(dāng)向 ByteBuf 中寫數(shù)據(jù)的時(shí)候,如果發(fā)現(xiàn)容量不 足,則進(jìn)行擴(kuò)容,直到擴(kuò)容到 maxCapacity,超過這個(gè)數(shù),就拋異常。
  3. ? readableBytes() 與 isReadable():readableBytes() 表示 ByteBuf 當(dāng)前可讀的字節(jié)數(shù),它的值等于 writerIndex-readerIndex,如果兩者相等,則不可讀,isReadable() 方法返回 false
  4. ? writableBytes()、 isWritable() 、maxWritableBytes():writableBytes() 表示 ByteBuf 當(dāng)前可寫的字節(jié)數(shù),它的 值等于 capacity()-writerIndex,如果兩者相等,則表示不可寫,isWritable() 返回 false,但是這個(gè)時(shí)候,并不代 表不能往 ByteBuf 中寫數(shù)據(jù)了, 如果發(fā)現(xiàn)往ByteBuf 中寫數(shù)據(jù)寫不進(jìn)去的話,Netty 會(huì)自動(dòng)擴(kuò)容 ByteBuf,直到擴(kuò) 容到底層的內(nèi)存大小為 maxCapacity,而 maxWritableBytes() 就表示可寫的大字節(jié)數(shù),它的值等于 maxCapacity-writerIndex。

讀寫指針相關(guān)的API:

  1. ? readerIndex() 與 readerIndex(int readerIndex):前者表示返回當(dāng)前的讀指針 readerIndex, 后者表示設(shè)置讀指針
  2. ? writeIndex() 與 writeIndex(int writerIndex):前者表示返回當(dāng)前的寫指針 writerIndex, 后者表示設(shè)置寫指針
  3. ? markReaderIndex() 與markWriterIndex():表示把當(dāng)前的讀指針/寫指針保存起來,操作形式為: markedReaderIndex = readerIndex / markedWriterIndex = writerIndex;

讀寫操作API:

  1. ? writeBytes(byte[] src): 表示把字節(jié)數(shù)組 src 里面的數(shù)據(jù)全部寫到 ByteBuf,src字節(jié)數(shù)組大小的長(zhǎng)度通常小于等于 writableBytes()
  2. ? readBytes(byte[] dst):把 ByteBuf 里面的數(shù)據(jù)全部讀取到 dst,dst 字節(jié)數(shù)組的大小通常等于 readableBytes()
  3. ? writeByte(int value)、readByte():writeByte() 表示往 ByteBuf 中寫一個(gè)字節(jié),而 readByte() 表示從 ByteBuf 中讀 取一個(gè)字節(jié),類似的 API 還有 writeBoolean()、writeChar()、writeShort()、writeInt()、writeLong()、 writeFloat()、writeDouble() 與 readBoolean()、readChar()、readShort()、readInt()、readLong()、 readFloat()、readDouble() 等等

丟棄、清理,釋放:

  1. ? discardReadBytes(): 丟棄已讀取的字節(jié)空間,可寫空間變多
  2. ? clear():重置readerIndex 、 writerIndex 為0,需要注意的是,重置并沒有刪除真正的內(nèi)容
  3. ? release():真正去釋放bytebuf中的數(shù)據(jù),
  4. ? ReferenceCountUtil.release(buf):工具方法,內(nèi)部還是調(diào)用release()

wrap:

通過Wrap操作可以快速轉(zhuǎn)換或得到一個(gè)ByteBuf對(duì)象,Unpooled 工具類中提供了很多重載的wrappedBuffer方法

理解:wrappedBuffer相當(dāng)于剪切粘貼,copiedBuffer相當(dāng)于復(fù)制粘貼

ByteBuf分類

1.按照內(nèi)存位置劃分:分為Heap 和 Direct?

? 堆緩沖區(qū)(HeapByteBuf):內(nèi)存分配在jvm堆,分配和回收速度比較快,可以被JVM自動(dòng)回收,缺點(diǎn)是,如果進(jìn)行 socket的IO讀寫,需要額外做一次內(nèi)存復(fù)制,將堆內(nèi)存對(duì)應(yīng)的緩沖區(qū)復(fù)制到內(nèi)核Channel中,性能會(huì)有一定程度的下 降。由于在堆上被 JVM 管理,在不被使用時(shí)可以快速釋放。可以通過 ByteBuf.array() 來獲取 byte[] 數(shù)據(jù)。

? 直接緩沖區(qū)(DirectByteBuf):內(nèi)存分配的是堆外內(nèi)存(系統(tǒng)內(nèi)存),相比堆內(nèi)存,它的分配和回收速度會(huì)慢一些, 但是將它寫入或從Socket Channel中讀取時(shí),由于減少了一次內(nèi)存拷貝,速度比堆內(nèi)存塊。

? 復(fù)合緩沖區(qū)(CompositeByteBuf):顧名思義就是將兩個(gè)不同的緩沖區(qū)從邏輯上合并,讓使用更加方便。

Netty默認(rèn)使用的是DirectByteBuf,如果需要使用HeapByteBuf模式,則需要進(jìn)行系統(tǒng)參數(shù)的設(shè)置

堆外內(nèi)存

2.根據(jù)內(nèi)存結(jié)構(gòu):Pooled 池化內(nèi)存和 Unpooled 非池化內(nèi)存

? 對(duì)于Pooled類型的ByteBuf,不管是PooledDirectByteBuf還是PooledHeapByteBuf都只能由Netty內(nèi)部自己使用(構(gòu)造是私有和受保護(hù)的)。 ? Netty提供Unpooled工具類創(chuàng)建的ByteBuf都是unpooled類型,默認(rèn)采用的Allocator是direct類型;當(dāng)然用戶可以自己選擇創(chuàng)建UnpooledDirectByteBuf和UnpooledHeapByteBuf

3.Unsafe 和非 Unsafe

Unsafe:是 JDK 底層的一個(gè)負(fù)責(zé) IO 操作的對(duì)象,可以直接拿到對(duì)象的內(nèi)存地址,基于內(nèi)存地址進(jìn)行讀寫操作。

ByteBuf 的釋放 ByteBuf如果采用的是堆緩沖區(qū)模式的話,可以由GC回收,但是如果采用的是直接緩沖區(qū),就不受GC的管理,就得手 動(dòng)釋放,否則會(huì)發(fā)生內(nèi)存泄露,Netty自身引入了引用計(jì)數(shù),提供了ReferenceCounted接口,當(dāng)對(duì)象的引用計(jì)數(shù)>0 時(shí)要保證對(duì)象不被釋放,當(dāng)為0時(shí)需要被釋放

關(guān)于ByteBuf的釋放,分為手動(dòng)釋放與自動(dòng)釋放: ? 手動(dòng)釋放 ,就是在使用完成后,調(diào)用ReferenceCountUtil.release(byteBuf); 進(jìn)行釋放,這種方式的弊端就是一旦忘 記釋放就可能會(huì)造成內(nèi)存泄露 ? 自動(dòng)釋放有三種方式 ,分別是: ? TailContext:Inbound流水線的末端,如果前面的handler都把消息向后傳遞最終由TailContext釋放該消息,需 要注意的是,如果沒有進(jìn)行向下傳遞,是不會(huì)進(jìn)行釋放操作的 ? SimpleChannelInboundHandler:自定義的InboundHandler繼承自SimpleChannelInboundHandler,在 SimpleChannelInboundHandler中自動(dòng)釋放 ? HeadContext:outbound流水線的末端,出站消息一般是由應(yīng)用所申請(qǐng),到達(dá)最后一站時(shí),經(jīng)過一輪復(fù)雜的調(diào) 用,在flush完成后終將被release掉

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧


新聞名稱:七天慢慢學(xué)Netty(第三天)-創(chuàng)新互聯(lián)
文章位置:http://weahome.cn/article/gjdjs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部