Netty5序章之BIO NIO AIO演变
Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能、高可靠的网络服务器和客户端程序。Netty简化了网络程序的开发,是很多框架和公司都在使用的技术。更是面试的加分项。Netty并非横空出世,它是在BIO,NIO,AIO演变中的产物,是一种NIO框架。而BIO,NIO,AIO更是笔试中要考,面试中要问的技术。也是一个很好的加分项,加分就是加工资,你还在等什么?本章带你细细品味三者的不同!
流程图:
技术:BIO,NIO,AIO
说明:github上有更全的源码。
源码:https://github.com/ITDragonBlog/daydayup/tree/master/Netty/socket-io
BIO 全称Block-IO 是一种阻塞同步的通信模式。我们常说的Stock IO 一般指的是BIO。是一个比较传统的通信方式,模式简单,使用方便。但并发处理能力低,通信耗时,依赖网速。
BIO 设计原理:
服务器通过一个Acceptor线程负责监听客户端请求和为每个客户端创建一个新的线程进行链路处理。典型的一请求一应答模式。若客户端数量增多,频繁地创建和销毁线程会给服务器打开很大的压力。后改良为用线程池的方式代替新增线程,被称为伪异步IO。
服务器提供IP地址和监听的端口,客户端通过TCP的三次握手与服务器连接,连接成功后,双放才能通过套接字(Stock)通信。
小结:BIO模型中通过Socket和ServerSocket完成套接字通道的实现。阻塞,同步,建立连接耗时。
BIO服务器代码,负责启动服务,阻塞服务,监听客户端请求,新建线程处理任务。
import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /** * IO 也称为 BIO,Block IO 阻塞同步的通讯方式 * 比较传统的技术,实际开发中基本上用Netty或者是AIO。熟悉BIO,NIO,体会其中变化的过程。作为一个web开发人员,stock通讯面试经常问题。 * BIO最大的问题是:阻塞,同步。 * BIO通讯方式很依赖于网络,若网速不好,阻塞时间会很长。每次请求都由程序执行并返回,这是同步的缺陷。 * BIO工作流程: * 第一步:server端服务器启动 * 第二步:server端服务器阻塞监听client请求 * 第三步:server端服务器接收请求,创建线程实现任务 */ public class ITDragonBIOServer { private static final Integer PORT = 8888; // 服务器对外的端口号 public static void main(String[] args) { ServerSocket server = null; Socket socket = null; ThreadPoolExecutor executor = null; try { server = new ServerSocket(PORT); // ServerSocket 启动监听端口 System.out.println("BIO Server 服务器启动........."); /*--------------传统的新增线程处理----------------*/ /*while (true) { // 服务器监听:阻塞,等待Client请求 socket = server.accept(); System.out.println("server 服务器确认请求 : " + socket); // 服务器连接确认:确认Client请求后,创建线程执行任务 。很明显的问题,若每接收一次请求就要创建一个线程,显然是不合理的。 new Thread(new ITDragonBIOServerHandler(socket)).start(); } */ /*--------------通过线程池处理缓解高并发给程序带来的压力(伪异步IO编程)----------------*/ executor = new ThreadPoolExecutor(10, 100, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(50)); while (true) { socket = server.accept(); // 服务器监听:阻塞,等待Client请求 ITDragonBIOServerHandler serverHandler = new ITDragonBIOServerHandler(socket); executor.execute(serverHandler); } } catch (IOException e) { e.printStackTrace(); } finally { try { if (null != socket) { socket.close(); socket = null; } if (null != server) { server.close(); server = null; System.out.println("BIO Server 服务器关闭了!!!!"); } executor.shutdown(); } catch (IOException e) { e.printStackTrace(); } } } }