Java Netty 学习笔记(一)初识Netty

妖狐艹你老母 2022-06-15 01:44 337阅读 0赞

记得前段时间面试,有些主攻java的公司总会问“你对网络编程比较熟,那java的AIO BIO NIO”知道么,答曰,确实对java不熟。在陈硕muduo中多次提到与netty都是用的one loop per thread,于是找了一个做Java后台的大佬借了一本Netty权威指南,开始学习。

代码:https://github.com/NearXdu/NettyLearn

1. BIO

B阻塞,传统的同步阻塞式IO,在UNP中,这种IO是 one connection per thread/process,在Java中似乎Listen Fd 和 Accept Fd 分别有各自的封装ServerSocketSocket.编程框架也是比较简单的:

  1. server = new ServerSocket(port);
  2. while (true){
  3. socket = server.accept();
  4. new Thread(new ServerHandler(socket)).start();
  5. }
  6. //
  7. ServerHandler implements Runnable {
  8. private Socket socket;
  9. public void run(){
  10. //...
  11. }
  12. }

主线程在loop中阻塞在accept调用,当新连接的到来的时候,将connfd扔进handle线程中,主线程继续等待连接.


2.伪异步

不用每次的创建线程,因为这样开销很大,用任务队列+线程池的方式,实现伪异步。
具体:
将Socket封装成一个Task,该Task实现Runnable接口,投递到任务队列中,后端的线程池进行处理。线程池中的线程有限,当任务数比较多时,将阻塞在任务队列里面(blocking queue),同样当任务队列为空时,线程池的线程也将挂起。这些java都封装好了,用起来还是很方便的:

  1. executor = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
  2. maxPoolSize,//线程池大小
  3. 120L,
  4. TimeUnit.SECONDS,//最大空闲实现
  5. new ArrayBlockingQueue<java.lang.Runnable>(queueSize));//blocking Queue Size
  6. while(true)
  7. {
  8. socket=server.accept();
  9. executor.execute(new task(socket));
  10. }

3.NIO编程

也就是Reactor,在netty中,有几个重要的组件:Buffer读写缓冲,Channel对描述符的封装,Selector多路复用选择器。
使用NIO编程的步骤如下:

  1. //监听套接字
  2. ServerSocketChannel acceptorSvr=ServerSocketChannel.open();
  3. bind;
  4. acceptorSvr.configureBlocking(false);
  5. //创建selecto并启动线程
  6. Selector selector = Selector.open();
  7. new Thread(new ReactorTask()).start();
  8. //将监听套接字注册到selector上
  9. SelectionKey key=acceptorSvr.register(selector,OP_ACCEPT,ioHandler);
  10. //在Reactor线程中轮询
  11. int num=selector.select();
  12. Set selectedKey=selector.selectedKeys();
  13. Iterator it = selectdKey.iterator();
  14. while(it.hasNext()){
  15. SelectionKey key = (SelectionKey)it.next();
  16. //...
  17. }
  18. //accept新连接
  19. SocketChannel channel= svrChannel.accept();
  20. //为已连接套接字注册IO事件
  21. SelectionKey key=socketChannel.register(selector,SelectionKey.OP_READ,ioHandler)

4.AIO

异步编程,有点类似boost.asio,每次需要注册完成回调,并在完成回调中调用异步操作来驱动,最终形
成一个循环。需要程序员实现一个CompletionHandler接口,相比同步Selector,AIO是真正的异步调用
例如

  1. public class AcceptCompletionHandler implements
  2. CompletionHandler<AsynchronousSocketChannel, AsyncTimeServerHandler> {
  3. @Override
  4. public void completed(AsynchronousSocketChannel asynchronousSocketChannel, AsyncTimeServerHandler asyncTimeServerHandler) {
  5. asyncTimeServerHandler.asynchronousServerSocketChannel.accept();
  6. ByteBuffer buffer = ByteBuffer.allocate(1024);
  7. asynchronousSocketChannel.read(buffer,buffer,new ReadCompletionHandler(asynchronousSocketChannel));
  8. }
  9. @Override
  10. public void failed(Throwable throwable, AsyncTimeServerHandler asyncTimeServerHandler) {
  11. throwable.printStackTrace();
  12. asyncTimeServerHandler.latch.countDown();
  13. }
  14. }

发表评论

表情:
评论列表 (有 0 条评论,337人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Netty自学-Netty学习()

    什么Netty? Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客

    相关 netty学习笔记

    netty是基于nio(非阻塞io)的高性能网络通信框架 什么是阻塞 ? 一直等待在那里,知道有返回值才会处理 例如: i. Socket socket = serve

    相关 Netty

    Netty是什么? Netty是由[JBOSS][]提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络