首頁>技術>

JDK 程式設計

感受了上面的 java 中的 BIO/NIO/AIO 詳解,不知道你是否覺得 jdk 直接程式設計非常麻煩?

還有很多情況需要去考慮處理,還有效能相關的問題、穩定性問題,拓展性問題。

不選擇Java原生NIO程式設計的原因

現在我們總結一下為什麼不建議開發者直接使用JDK的NIO類庫進行開發,具體原因如下。

(1) NIO的類庫和API繁雜,使用麻煩,你需要熟練掌握Selector、ServerSocketChannel、SocketChannel、ByteBuffer等

(2) 需要具備其他的額外技能做鋪墊,例如熟悉Java多執行緒程式設計。

這是因為NIO程式設計涉及到Reactor模式,你必須對多執行緒和網路程式設計非常熟悉,才能編寫出高質量的NIO程式。

(3) 可靠效能力補齊,工作量和難度都非常大。

例如客戶端面臨斷連重連、網路閃斷、半包讀寫、失敗快取、網路擁塞和異常碼流的處理等問題,NIO程式設計的特點是功能開發相對容易,但是可靠效能力補齊的工作量和難度都非常大。

(4) JDK NIO的BUG, 例如臭名昭著的epollbug,它會導致Selector空輪詢, 最終導致CPU 100%。

官方聲稱在JDK1.6版本的update18修復了該問題, 但是直到JDK1.7版本該問題仍舊存在, 只不過該BUG發生機率降低了一些而已,它並沒有得到根本性解決。

為什麼選擇 netty

Netty是業界最流行的NIO框架之一, 它的健壯性、功能、效能、可定製性和可擴充套件性在同類框架中都是首屈一指的, 它已經得到成百上千的商用專案驗證, 例如Hadoop的RPC框架Avro就使用了Netty作為底層通訊框架, 其他還有業界主流的RPC框架, 也使用Netty來構建高效能的非同步通訊能力。

透過對Netty的分析,我們將它的優點總結如下。

API使用簡單, 開發門檻低;功能強大,預置了多種編解碼功能,支援多種主流協議;定製能力強, 可以透過ChannelHandler對通訊框架進行靈活地擴充套件;效能高, 透過與其他業界主流的NIO框架對比,Netty的綜合性能最優;成熟、穩定,Netty修復了已經發現的所有JDKNIOBUG, 業務開發人員不需要再為NIO的BUG而煩惱;社群活躍, 版本迭代週期短, 發現的BUG可以被及時修復,同時, 更多的新功能會加入;經歷了大規模的商業應用考驗, 質量得到驗證。Netty在網際網路、大資料、網路遊戲、企業應用、電信軟體等眾多行業已經得到了成功商用,證明它已經完全能夠滿足不同行業的商業應用了。

正是因為這些優點,Netty 逐漸成為了 Java NIO 程式設計的首選框架。

Netty

Netty 是一個NIO客戶端伺服器框架,可以快速輕鬆地開發協議伺服器和客戶端等網路應用程式。

它極大地簡化並簡化了TCP和UDP套接字伺服器等網路程式設計。

“快速簡便”並不意味著最終的應用程式會受到可維護性或效能問題的影響。

Netty經過精心設計,具有豐富的協議,如FTP,SMTP,HTTP以及各種二進位制和基於文字的傳統協議。

因此,Netty成功地找到了一種在不妥協的情況下實現易於開發,效能,穩定性和靈活性的方法。

components.png

快速入門

本章透過簡單的示例瀏覽Netty的核心結構,以便您快速入門。

當您在本章末尾時,您將能夠立即在Netty上編寫客戶端和伺服器。

入門之前

本章中執行示例的最低要求僅為兩個:最新版本的Netty和JDK 1.6或更高版本。

maven 引入
<dependency>    <groupId>io.netty</groupId>    <artifactId>netty-all</artifactId>    <version>4.1.17.Final</version></dependency>
例項程式碼編寫丟棄伺服器

世界上最簡單的協議不是'Hello,World!',而是丟棄。

它是一種在沒有任何響應的情況下丟棄任何接收資料的協議。

要實現DISCARD協議,您唯一需要做的就是忽略所有收到的資料。

讓我們直接從處理程式實現開始,它處理由Netty生成的I/O事件。

package com.github.houbb.netty.learn.four.discard;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelOption;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;public class DiscardServer {    public static void main(String[] args) {        EventLoopGroup bossGroup = new NioEventLoopGroup();        EventLoopGroup workGroup = new NioEventLoopGroup();        try {            ServerBootstrap serverBootstrap = new ServerBootstrap();            serverBootstrap.group(bossGroup, workGroup)                    //在這裡,我們指定使用NioServerSocketChannel類,該類用於例項化新Channel以接受傳入連線。                    .channel(NioServerSocketChannel.class)                    //此處指定的處理程式將始終由新接受的Channel評估。                    .childHandler(new DiscardServerHandler())                    // 設定套接字選項資訊                    .option(ChannelOption.SO_BACKLOG, 128)//            option()用於接受傳入連線的NioServerSocketChannel。//            childOption()用於父ServerChannel接受的Channels,在這種情況下是NioServerSocketChannel。                    .childOption(ChannelOption.SO_KEEPALIVE, true);            //bind            ChannelFuture channelFuture = serverBootstrap.bind(8888).syncUninterruptibly();            // Wait until the server socket is closed.            // In this example, this does not happen, but you can do that to gracefully            // shut down your server.            channelFuture.channel().closeFuture().syncUninterruptibly();        } finally {            workGroup.shutdownGracefully();            bossGroup.shutdownGracefully();        }    }}

EventLoopGroup 可以理解為執行緒池。

列印資訊

我們如果啟動程式,最簡單的方式是使用 telnet localhost 8888 進行驗證。

public class EchoServerHandler extends ChannelInboundHandlerAdapter {    @Override    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {        // 寫入並且重新整理        ctx.writeAndFlush(msg);    }    @Override    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {        cause.printStackTrace();        ctx.close();    }}
測試驗證

將 server 的 handler 換成這個類。

啟動服務端。

啟動客戶端

客戶端日誌
Client receive time: 1568812068058Process finished with exit code 0
感受

Netty 真的是非常的強大,api 也封裝的非常優雅,很值得深入學習。

我是老馬,期待與你的下次相遇。

14
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 雲計算Openstack搭建教程第一篇:基礎環境配置