Java IO模型与Netty线程模型

目录

 

一、概念介绍

1、同步与异步

2、阻塞与非阻塞

3、同步阻塞io

4、同步非阻塞io

5、IO多路复用

6、异步IO

二、BIO(同步阻塞IO)

三、伪异步IO

四、NIO(同步阻塞IO)

五、Netty线程模型

1、Reactor单线程模型

2、Reactor多线程模型

3、主从Reactor多线程模型

4、Netty线程模型实现


一、概念介绍

1、同步与异步

从字面的意思可以看出:同步IO即 如果一个线程请求进行IO操作,在IO操作完成之前,该线程会被阻塞;而异步IO为 如果一个线程请求进行IO操作,IO操作不会导致请求线程被阻塞。

事实上,同步IO和异步IO模型是针对用户线程和内核的交互来说的:

linux系统IO分为内核准备数据和将数据从内核拷贝到用户空间两个阶段。

  对于同步IO:当用户发出IO请求操作之后,如果数据没有就绪,需要通过用户线程或者内核不断地去轮询数据是否就绪,当数据就绪时,再将数据从内核拷贝到用户线程;

  而异步IO:只有IO请求操作的发出是由用户线程来进行的,IO操作的两个阶段都是由内核自动完成(等待数据就绪阶段和数据拷贝阶段),然后发送通知告知用户线程IO操作已经完成。也就是说在异步IO中,不会对用户线程产生任何阻塞。

  这是同步IO和异步IO关键区别所在,同步IO和异步IO的关键区别反映在数据拷贝阶段是由用户线程完成还是内核完成。所以说异步IO必须要有操作系统的底层支持。

2、阻塞与非阻塞

  阻塞IO和非阻塞IO是反映在当用户请求IO操作时,如果数据没有就绪,是用户线程一直等待数据就绪,还是会收到一个标志信息这一点上面的。也就是说,阻塞IO和非阻塞IO是反映在IO操作的第一个阶段,在查看数据是否就绪时是如何处理的

3、同步阻塞io

4、同步非阻塞io

5、IO多路复用

IO多路复用模型是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题。

6、异步IO

二、BIO(同步阻塞IO)

通常由一个独立的线程Acceptor负责客户端的连接,接收到客户端的连接请求之后,为每个客户端创建一个新的线程进行链路处理,完成之后,通过输出流返回给客户端,线程销毁。

一个连接一个线程,客户端有连接请求时,服务端就启动一个线程来执行。

三、伪异步IO

对BIO进行了优化,后端通过一个线程池来处理多个客户端的请求,行程客户端个数M:线程池最大线程数N的比例关系,防止海量并发接入导致线程耗尽。

四、NIO(同步阻塞IO)

一个io请求一个线程,客户端发送的连接请求都会注册到多路复用器上,多路复用器轮询到有连接的io请求时才会启动一个线程来处理。

五、Netty线程模型

高性能 IO 模型: Reactor,它是一种异步、非阻塞的事件驱动模型。

1、Reactor单线程模型

所有的IO操作都在同一个NIO线程上面完成,它是由一个线程来接收客户端的连接,并将该请求分发到对应的事件处理 handler 中,整个过程完全是异步非阻塞的;并且完全不存在共享资源的问题。所以理论上来说吞吐量也还不错。

2、Reactor多线程模型

一个线程负责接收TCP连接请求,有一组NIO线程负责IO操作

瓶颈点:一个NIO线程负责监听和处理所有的客户端连接,可能会存在性能问题。比如百万客户端连接,或者服务端需要对客户端进行安全认证等。

3、主从Reactor多线程模型

服务端用于接收客户端连接的不再是一个单独的NIO线程,而是一个独立的NIO线程池。

4、Netty线程模型实现

    private EventLoopGroup boss = new NioEventLoopGroup();
    private EventLoopGroup work = new NioEventLoopGroup();


    /**
     * 启动 Netty
     *
     * @return
     * @throws InterruptedException
     */
    @PostConstruct
    public void start() throws InterruptedException {

        ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss, work)
                .channel(NioServerSocketChannel.class)
                .localAddress(new InetSocketAddress(nettyPort))
                //保持长连接
                .childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new HeartbeatInitializer());

        ChannelFuture future = bootstrap.bind().sync();
        if (future.isSuccess()) {
            LOGGER.info("启动 Netty 成功");
        }
    }

单线程模型:

private EventLoopGroup group = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
                .group(group)
                .childHandler(new HeartbeatInitializer());

多线程模型:

private EventLoopGroup boss = new NioEventLoopGroup(1);
private EventLoopGroup work = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss,work)
                .childHandler(new HeartbeatInitializer());

主从多线程模型:

private EventLoopGroup boss = new NioEventLoopGroup();
private EventLoopGroup work = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap()
                .group(boss,work)
                .childHandler(new HeartbeatInitializer());

猜你喜欢

转载自blog.csdn.net/weixin_43599368/article/details/84934374
今日推荐