日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

netty开发教程(一)

發布時間:2023/12/13 综合教程 28 生活家
生活随笔 收集整理的這篇文章主要介紹了 netty开发教程(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


Netty介紹

Netty isan asynchronous event-driven network application framework

for rapid development of maintainable high performance protocol servers & clients.

netty 官網如是說。大概意思是netty 是一個異步的事件驅動的網絡應用框架,能夠高速開發可維護的高性能網絡server、client應用。

asynchronous異步,netty中非常大一部分方法都是異步的,配合事件驅動模型可以處理很多其它請求。

netty的一致性API相比于JDK的API有非常高的用戶體驗,

使用起來也非常方便。netty使我們不用考慮太多底層問題和各種各樣的bug。讓開發人員可以更專注于業務邏輯。

netty現狀

這是netty在github的主頁https://github.com/netty/netty。眼下已經有5000+的star

非常多知名公司和項目在使用netty,包含facebook、IBM、RedHat等大公司和Spark、Finagle、Nifty等項目。

很多其它的adaptor在http://netty.io/wiki/adopters.html。

眼下netty的主要維護版本號有3.x 、4.x 、5.x。

我接觸比較多的是5.x,非常多框架是基于3.x開發的。3 4 5之間有一些區別,

我覺得新的版本號是在以往的經驗和教訓上開發出來的。用的基本的5。

netty做什么事情

http://netty.io/images/components.png

netty對JDK的NIO進行了封裝,為開發人員提供了一致性和良好的API。

netty提供了非常多更好的"JDK API"實現。比方它的ByteBuf。

快的定義是什么

快, 我想盡快得到一個東西和我想盡快得到全部的東西。

在ServerClient編程中。前者能夠覺得是low latency, 更低的延遲, 盡快完畢一個請求; 而后者是high throughput。更大的系統吞吐量。

可擴展性scalability

我們須要系統在大量請求時可以平滑的減少性能而且當我們提升硬件配置時可以獲得對應的性能提升。

不同paradigm的Server

1.單線程模式

handle假設沒有在新線程中運行那么while循環將會block在handle處理上,一次僅僅能處理一個請求。

</pre></h3><h3 style="margin:30px 0px 0px; font-size:16px; line-height:1.5; color:rgb(51,51,51); font-family:Arial,sans-serif"><pre name="code" class="java">ServerSocket serverSocket = new ServerSocket(port);
while(true){
 Socket socket = serverSocket.accept();
 handle(socket);
}
private void handle(Socket socket){
   try(
         InputStream inputStream = socket.getInputStream();
         PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
         BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
   ){
      String line;
      while((line = br.readLine()) != null){
         System.out.println("Read line : " + line);
         writer.println(line);
      }
   } catch (IOException e) {
      e.printStackTrace();
   }
}

2.多線程運行

一個請求相應一個線程。當涌現大量請求時線程的創建、銷毀、ContextSwitch的overhead都回影響系統性能

ServerSocket serverSocket = new ServerSocket(port);
while(true){
   Socket socket = serverSocket.accept();
   new Thread(){
      @Override
      public void run(){
         handle(socket);
      }
   }.start();
} 

3.線程池

線程池并沒有解決一請求一線程的問題。僅僅能有限降低線程創建的開銷和控制線程的創建。

Executor executor = Executors.newFixedThreadPool(100);
ServerSocket serverSocket = new ServerSocket(port);
while(true){
   Socket socket = serverSocket.accept();
   executor.execute(new Runnable() {
      @Override
      public void run() {
         handle(socket);
      }
   });
}

4.JDK NIO

思考一下。問題出在handle(socket)上。InputStream 和OutputStream的基于字節的讀寫方式,的read write操作都是block操作,當沒有bytes能夠read或者write時運行線程都會block。

graph
from 《netty in action》

JDK1.4 提供了nio實現, nio當時有兩種說法,new io 和non blocking io, 如今過去這么多年了。已經不再new了,大家都稱之為non blocking io。

介紹幾個核心java.nio包中包含一些Buffer,核心是ByteBuffer,程序與網絡層交互還是以byte流的形式。ByteBuffer有heap buffer 和direct buffer(non heap buffer)兩種。head buffer 在Java heap 堆中。

使用byte數組作為其內部數據結構,direct buffer 在Java 堆內存之外。

java.nio.channels中有Channel和Selector兩個比較重要的類。Channel代表了一個和能夠讀寫的目標的通道,實現類有FileChannel、ServerSocketChannel、SocketChannel等,Selector用于注冊Channel感興趣的事件。這樣我們就能夠實現asynchronous event-driven了,實現一個線程處理多個請求,多路復用(multiplexing)

<img class="confluence-embedded-image" title="劉正陽 > netty概覽 > image2015-8-2 17:52:19.png" src="http://wiki.sankuai.com/download/attachments/262799469/image2015-8-2%2017%3A52%3A19.png?

version=1&modificationDate=1438509139496&api=v2" alt="">

ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.bind(new InetSocketAddress(port));
serverChannel.configureBlocking(false);
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while(true){
   selector.select();
   Set<SelectionKey> selectionKeySet = selector.selectedKeys();
   Iterator<SelectionKey> iterator = selectionKeySet.iterator();
   while(iterator.hasNext()){
      SelectionKey selectionKey = iterator.next();
      iterator.remove();
      if(selectionKey.isAcceptable()){
         ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel();
         SocketChannel client = server.accept();
         client.configureBlocking(false);
         client.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE, ByteBuffer.allocate(BUFFER_SIZE));
      }
      if(selectionKey.isReadable()){
         SocketChannel client = (SocketChannel) selectionKey.channel();
         ByteBuffer buf = (ByteBuffer) selectionKey.attachment();
         client.read(buf);
      }
      if(selectionKey.isWritable()){
         SocketChannel client = (SocketChannel) selectionKey.channel();
         ByteBuffer buf = (ByteBuffer) selectionKey.attachment();
         buf.flip();
         client.write(buf);
         buf.compact();
      }
   }
}

這個CPU占用比較嚴重

5. netty nio

為了演示把功能放到了一個塊里。netty中我們的byte解析業務實現都能夠用ChannelHandler來實現,ChannelHandler串聯在ChannelPipeline形成了一種類插件的形式。通過Filter chain使各個邏輯相互獨立可復用。

int port = 8090;
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
try{
   serverBootstrap.group(bossGroup, workerGroup)
         .channel(NioServerSocketChannel.class)
         .childHandler(new ChannelInitializer<io.netty.channel.socket.SocketChannel>() {
            @Override
            protected void initChannel(io.netty.channel.socket.SocketChannel ch) throws Exception {
               ch.pipeline().addLast("echoHandler", new ChannelHandlerAdapter() {
                  @Override
                  public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
                     ctx.flush();
                  }

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

                  @Override
                  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
                     cause.printStackTrace();
                     ctx.close();
                  }
               });
            }
         });
   ChannelFuture f = serverBootstrap.bind(new InetSocketAddress(port)).sync();
   f.channel().closeFuture().sync();
} catch (InterruptedException e) {
   e.printStackTrace();
} finally {
   bossGroup.shutdownGracefully();
   workerGroup.shutdownGracefully();
}

未完待續。。

continuning...

很多其它推薦資料

netty in action

http://g.oswego.edu/

總結

以上是生活随笔為你收集整理的netty开发教程(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。