Netty編程

那麼Netty到底是何方神聖?
用一句簡單的話來說就是:Netty封裝了JDK的NIO,讓你用得更爽,你不用再寫一大堆複雜的代碼了。

用官方正式的話來說就是:Netty是一個異步事件驅動的網絡應用框架,用於快速開發可維護的高性能服務器和客戶端。

下面是我總結的使用Netty不使用JDK原生NIO的原因

  1. 使用JDK自帶的NIO需要了解太多的概念,編程複雜,一不小心bug橫飛
  2. Netty底層IO模型隨意切換,而這一切只需要做微小的改動,改改參數,Netty可以直接從NIO模型變身爲IO模型
  3. Netty自帶的拆包解包,異常檢測等機制讓你從NIO的繁重細節中脫離出來,讓你只需要關心業務邏輯
  4. Netty解決了JDK的很多包括空輪詢在內的bug
  5. Netty底層對線程,selector做了很多細小的優化,精心設計的reactor線程模型做到非常高效的併發處理
  6. 自帶各種協議棧讓你處理任何一種通用協議都幾乎不用親自動手
  7. Netty社區活躍,遇到問題隨時郵件列表或者issue
  8. Netty已經歷各大rpc框架,消息中間件,分佈式通信中間件線上的廣泛驗證,健壯性無比強大

看不懂沒有關係,這些我們在後續的課程中我們都可以學到,接下來我們用Netty的版本來重新實現一下本文開篇的功能吧


 首先,引入Maven依賴


<dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.6.Final</version>
</dependency>

然後,下面是服務端實現部分


NettyServer.java 


/**
 * @author 閃電俠
 */
public class NettyServer {
    public static void main(String[] args) {
        ServerBootstrap serverBootstrap = new ServerBootstrap();

        NioEventLoopGroup boos = new NioEventLoopGroup();
        NioEventLoopGroup worker = new NioEventLoopGroup();
        serverBootstrap
                .group(boos, worker)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    protected void initChannel(NioSocketChannel ch) {
                        ch.pipeline().addLast(new StringDecoder());
                        ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext ctx, String msg) {
                                System.out.println(msg);
                            }
                        });
                    }
                })
                .bind(8000);
    }
}

這麼一小段代碼就實現了我們前面NIO編程中的所有的功能,包括服務端啓動,接受新連接,打印客戶端傳來的數據,怎麼樣,是不是比JDK原生的NIO編程優雅許多?

初學Netty的時候,由於大部分人對NIO編程缺乏經驗,因此,將Netty裏面的概念與IO模型結合起來可能更好理解

1.boos對應,IOServer.java中的接受新連接線程,主要負責創建新連接
2.worker對應 IOClient.java中的負責讀取數據的線程,主要用於讀取數據以及業務邏輯處理

然後剩下的邏輯我在後面的系列文章中會詳細分析,你可以先把這段代碼拷貝到你的IDE裏面,然後運行main函數

然後下面是客戶端NIO的實現部分


NettyClient.java


 

/**
 * @author 閃電俠
 */
public class NettyClient {
    public static void main(String[] args) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();

        bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<Channel>() {
                    @Override
                    protected void initChannel(Channel ch) {
                        ch.pipeline().addLast(new StringEncoder());
                    }
                });

        Channel channel = bootstrap.connect("127.0.0.1", 8000).channel();

        while (true) {
            channel.writeAndFlush(new Date() + ": hello world!");
            Thread.sleep(2000);
        }
    }
}

在客戶端程序中,group對應了我們IOClient.java中main函數起的線程,剩下的邏輯我在後面的文章中會詳細分析,現在你要做的事情就是把這段代碼拷貝到你的IDE裏面,然後運行main函數,最後回到NettyServer.java的控制檯,你會看到效果。

使用Netty之後是不是覺得整個世界都美好了,一方面Netty對NIO封裝得如此完美,寫出來的代碼非常優雅,另外一方面,使用Netty之後,網絡通信這塊的性能問題幾乎不用操心,盡情地讓Netty榨乾你的CPU吧。

目前我負責的兩大長連接項目均峯值QPS在50W左右,單機連接數10W左右,集羣規模在千萬級別,底層均使用了Netty作爲通信框架。Netty如此高性能及穩定的特性讓我幾乎不用爲性能而擔憂,所以,如果你工作中需要接觸到網絡編程,Netty必將是你的最佳選擇!

Netty 入門與實戰:仿寫微信 IM 即時通訊系統

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章