小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Netty原理和使用

 知識(shí)存儲(chǔ)館 2014-07-24

性能主題

Netty原理和使用

  Netty是一個(gè)高性能 事件驅(qū)動(dòng)的異步的非堵塞的IO(NIO)框架,用于建立TCP等底層的連接,基于Netty可以建立高性能的Http服務(wù)器。支持HTTP、 WebSocket 、Protobuf、 Binary TCP |和UDP,Netty已經(jīng)被很多高性能項(xiàng)目作為其Socket底層基礎(chǔ),如HornetQ Infinispan Vert.x
Play Framework Finangle和 Cassandra。其競(jìng)爭(zhēng)對(duì)手是:Apache MINA和 Grizzly。

   傳統(tǒng)堵塞的IO讀取如下:

InputStream is = new FileInputStream("input.bin");
int byte = is.read(); // 當(dāng)前線程等待結(jié)果到達(dá)直至錯(cuò)誤

   而使用NIO如下:

while (true) {
 selector.select(); // 從多個(gè)通道請(qǐng)求事件
 Iterator it = selector.selectedKeys().iterator();
 while (it.hasNext()) {
  SelectorKey key = (SelectionKey) it.next();
  handleKey(key);
  it.remove();
 }

堵塞與非堵塞原理

  傳統(tǒng)硬件的堵塞如下,從內(nèi)存中讀取數(shù)據(jù),然后寫到磁盤,而CPU一直等到磁盤寫完成,磁盤的寫操作是慢的,這段時(shí)間CPU被堵塞不能發(fā)揮效率。

  使用非堵塞的DMA如下圖:CPU只是發(fā)出寫操作這樣的指令,做一些初始化工作,DMA具體執(zhí)行,從內(nèi)存中讀取數(shù)據(jù),然后寫到磁盤,當(dāng)完成寫后發(fā)出一個(gè)中斷事件給CPU。這段時(shí)間CPU是空閑的,可以做別的事情。這個(gè)原理稱為Zero.copy零拷貝。

  Netty底層基于上述Java NIO的零拷貝原理實(shí)現(xiàn):

比較

  • Tomcat是一個(gè)Web服務(wù)器,它是采取一個(gè)請(qǐng)求一個(gè)線程,當(dāng)有1000客戶端時(shí),會(huì)耗費(fèi)很多內(nèi)存。通常一個(gè)線程將花費(fèi) 256kb到1mb的stack空間。
  • Node.js是一個(gè)線程服務(wù)于所有請(qǐng)求,在錯(cuò)誤處理上有限制
  • Netty是一個(gè)線程服務(wù)于很多請(qǐng)求,如下圖,當(dāng)從Java NIO獲得一個(gè)Selector事件,將激活通道Channel。

演示

Netty的使用代碼如下:

Channel channel = ...
ChannelFuture cf = channel.write(data);
cf.addListener(
  new ChannelFutureListener() {
   @Override
   public void operationComplete(ChannelFuture future) throws Exception {
     if(!future.isSuccess() {
        future.cause().printStacktrace();
        ...
     }
     ...
   }
});
...
cf.sync();

通過引入觀察者監(jiān)聽,當(dāng)有數(shù)據(jù)時(shí),將自動(dòng)激活監(jiān)聽者中的代碼運(yùn)行。

我們使用Netty建立一個(gè)服務(wù)器代碼:

public class EchoServer {

    private final int port;

    public EchoServer(int port) {
        this.port = port;
    }

    public void run() throws Exception {
        // Configure the server.
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 100)
                   .handler(new LoggingHandler(LogLevel.INFO)).childHandler(new ChannelInitializer<SocketChannel>() {
                       @Override
                       public void initChannel(SocketChannel ch) throws Exception {
                           ch.pipeline().addLast(
                           // new LoggingHandler(LogLevel.INFO),
                                   new EchoServerHandler());
                       }
                   });

            // Start the server.
            ChannelFuture f = b.bind(port).sync();

            // Wait until the server socket is closed.
            f.channel().closeFuture().sync();
        } finally {
            // Shut down all event loops to terminate all threads.
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

   
}

這段代碼調(diào)用:在9999端口啟動(dòng)

new EchoServer(9999).run();

我們需要完成的代碼是EchoServerHandler

public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = Logger.getLogger(EchoServerHandler.class.getName());

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.write(msg);
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        logger.log(Level.WARNING, "Unexpected exception from downstream.", cause);
        ctx.close();
    }
}

原理

   一個(gè)Netty服務(wù)器的原理如下:

  圖中每次請(qǐng)求的讀取是通過UpStream來實(shí)現(xiàn),然后激活我們的服務(wù)邏輯如EchoServerHandler,而服務(wù)器向外寫數(shù)據(jù),也就是響應(yīng)是通過DownStream實(shí)現(xiàn)的。每個(gè)通道Channel包含一對(duì)UpStream和DownStream,以及我們的handlers(EchoServerHandler),如下圖,這些都是通過channel pipeline封裝起來的,數(shù)據(jù)流在管道里流動(dòng),每個(gè)Socket對(duì)應(yīng)一個(gè)ChannelPipeline。

 

   CHANNELPIPELINE是關(guān)鍵,它類似Unix的管道,有以下作用:

  • 為每個(gè)Channel 保留 ChannelHandlers ,如EchoServerHandler
  • 所有的事件都要通過它
  • 不斷地修改:類似unix的SH管道: echo "Netty is shit...." | sed -e 's/is /is the /'
  • 一個(gè)Channel對(duì)應(yīng)一個(gè) ChannelPipeline
  • 包含協(xié)議編碼解碼 安全驗(yàn)證SSL/TLS和應(yīng)用邏輯

 

客戶端代碼

  前面我們演示了服務(wù)器端代碼,下面是客戶端代碼:

public class EchoClient {
    private final String host;
    private final int port;
    private final int firstMessageSize;

    public EchoClient(String host, int port, int firstMessageSize) {
        this.host = host;
        this.port = port;
        this.firstMessageSize = firstMessageSize;
    }

    public void run() throws Exception {
        // Configure the client.
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
           b.group(group).channel(NioSocketChannel.class).option(ChannelOption.TCP_NODELAY, true).handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                   ch.pipeline().addLast(
                   // new LoggingHandler(LogLevel.INFO),
                           new EchoClientHandler(firstMessageSize));
                }
            });

            // Start the client.
            ChannelFuture f = b.connect(host, port).sync();

            // Wait until the connection is closed.
            f.channel().closeFuture().sync();
        } finally {
            // Shut down the event loop to terminate all threads.
            group.shutdownGracefully();
        }
    }
}

客戶端的應(yīng)用邏輯EchoClientHandler

public class EchoClientHandler extends ChannelInboundHandlerAdapter {

    private static final Logger logger = Logger.getLogger(EchoClientHandler.class.getName());

    private final ByteBuf firstMessage;

    /**
     * Creates a client-side handler.
     */
    public EchoClientHandler(int firstMessageSize) {
        if (firstMessageSize <= 0) {
            throw new IllegalArgumentException("firstMessageSize: " + firstMessageSize);
        }
        firstMessage = Unpooled.buffer(firstMessageSize);
        for (int i = 0; i < firstMessage.capacity(); i++) {
            firstMessage.writeByte((byte) i);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        ctx.writeAndFlush(firstMessage);
        System.out.print("active");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ctx.write(msg);
        System.out.print("read");
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.flush();
        System.out.print("readok");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        logger.log(Level.WARNING, "Unexpected exception from downstream.", cause);
        ctx.close();
    }

}

 

Java NIO原理和使用

NodeJS入門

vertx入門教程

Netty作者談Java性能優(yōu)化要點(diǎn)

2

banq   2014-07-22    1討論    180瀏覽

Orleans 是微軟推出的類似Scala Akka的Actor模型,可用于實(shí)現(xiàn) DDD +EventSourcing/CQRS系統(tǒng)。 Orlea....

banq   2014-07-20    0討論    699瀏覽

國(guó)內(nèi)大部分號(hào)稱 云計(jì)算 的產(chǎn)品基本是主機(jī)托管+數(shù)據(jù)中心,很多人認(rèn)為 ....

banq   2014-07-16    1討論    722瀏覽

這是一篇討論客戶端MVC和服務(wù)器端MVC的比較文章。 首先分離關(guān)注是架構(gòu)設(shè)計(jì)的一個(gè)基本原則,多層架構(gòu)中:數(shù)據(jù)存儲(chǔ) 服務(wù)層 API層和表現(xiàn)層各層之間應(yīng)該最小依賴,服務(wù)層只需要知道在哪里存儲(chǔ)數(shù)據(jù),A....

banq   2014-07-08    0討論    1127瀏覽

一位Node.js guru大牛 TJ Holowaychuk最近發(fā)表了 再會(huì)Node.js ,他曾經(jīng)是Empress, Mocha, Jade, Stylus Koa等參與者,TJ在這篇宣言中首先強(qiáng)....

banq   2014-07-05    8討論    1300瀏覽

這是來自ScalaDays 2014大會(huì)上有關(guān)如何使用 DDD EventSourcing/CQRS和Akka構(gòu)建一個(gè)reactive的微服務(wù)應(yīng)用系統(tǒng)的演講,大意如下, ..




    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多