IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> Reactor 和 Proactor 到底是什么玩意 -> 正文阅读

[系统运维]Reactor 和 Proactor 到底是什么玩意

网络编程中出了 IO 模型之外,另一个被经常提到的就是 Reactor 模型和 Proactor 模型, 其实这两个模型和 IO 模型有着重要的关系,看完本文你就知道了.

如果你对 IO 模型还不清楚,请先移步下面的文章后再回头来看本文.《到底什么是IO》icon-default.png?t=M1L8https://mp.weixin.qq.com/s/OkIajg8aDlkLtsE81NP5jQ

在网络编程中,服务器设计的好坏直接影响到能支持的最大并发数,通常会考虑两种方式,一种是通过 线程的方式,另一种就是通过事件的方式.?

单线程

网络通信中, 客户端向服务器请求数据时,服务器通常有两种方式处理,一种就是单线程,这样做的话所有的客户端都需要排队等待, 如果服务端处理逻辑比较简单快速的话, 针对少量的客户端还是可以的,但是一旦客户端数量增加,服务端处理时间会线性增加, 如果处理逻辑复杂并且还涉及到 IO ,简直不可想象.

于是多线程模型出来了.

多线程

为了解决但线程带来的处理慢,延迟大的问题,引入了多线程. 服务器没收到一个客户端的连接就分配一个线程来处理, 当然分配的方式你可以选择 new 也可以选择线程池的方式,通常为了避免反复创建导致的资源浪费和性能低下问题而采用线程池的方式.

看似完美了,但是如果某些客户端连接在处理时比较耗时(由于各种原因,比如网络慢、数据量大处理复杂等),就会长期占用线程,导致其他客户端连接没办法获取线程处理.

事件模式

多线程的方式看似完美,但是有个问题就是, 线程利用率不高, 每来一个连接就分配一个线程,可能这个连接压根就没发数据,这岂不是白占着坑位吗?

基于事件模式就是连一个连接,服务端并不会立刻分配线程,而是监听事件(读、写、请求连接),有事件再分配线程进行处理.在实际工程中通常会将事件分发器(dispatcher)、处理器(handler)分开设计.

Reactor?

reactor “反应堆”, 对于所有来自客户端的事件作出反应,其实就是基于 NIO 的多路复用实现的一种方式.

根据 dispatcher、handler 线程模型可以分为 4种: 单?dispatcher 单?handler, 单?dispatcher 多?handler, 多?dispatcher 单?handler 以及多?dispatcher 多?handler, 但是?多?dispatcher 单?handler 对性能提升并没有太大价值,所以下面就讨论 3 种.

1.?单?dispatcher 单?handler

?

(1) 客户端连接过来, dispatcher 通过 select 轮询事件

(2) 如果是连接事件,交由 AcceptHandler 处理, 并向 select 注册 ready for reading(可读)?事件到 BusinessHandler

(3) 如果是 ready for?reading 事件, 交由?BusinessHandler 处理,并返回结果

如果业务处理比较耗时的话,就会因为处理不过来而导致延迟.

2.?单?dispatcher 多?handler

?

工作过程类似,只是在收到?ready for?reading 事件时, 交由一个单独的线程使用?BusinessHandler 处理.业务处理能力提高了,但是面对高并发时, 单线程的 dispatcher 成了瓶颈, 需要分发所有的事件.

3. 多?dispatcher 多?handler

也叫主从 Reactor 模式, 主线程中的 Dispatcher 只负责处理连接事件, 将成功的连接传给从 Reactor, 从 Reactor 处理调用业务处理器处理读写事件, 业务处理器又使用 worker 线程池进行业务处理.

?

?变种:

上图中 BusinessHandler 只负责读写调用,具体的业务处理在线程池中去做, 业务处理完后还得返回给 BusinessHandler 返回给客户端,涉及到数据共享问题,于是出现了变种:

所有的业务处理,包括 read 、业务处理、write 都在BusinessHandler 中的线程池中操作.

?

Netty 就是基于 reactor? 的多 dispatcher 多handler 实现的.

Proactor

先看下 wiki 中的定义:

Proactor is a software design pattern for event handling in which long running activities are running in an asynchronous part.?A completion handler is called after the asynchronous part has terminated. The proactor pattern can be considered to be an asynchronous variant of the synchronous reactor pattern.

Proactor 是一种用于事件处理的软件设计模式,其中长时间运行的活动(IO)在异步部分运行。异步部分终止后,将调用完成处理程序。前置器模式可以被认为是同步 reactor 模式的异步变体。

?

上面的图只是介绍了 proactor 的工作原理,实际编写代码时,可能非常简单, 比如 Java 中:


        AsynchronousServerSocketChannel  ssc = AsynchronousServerSocketChannel.open();

        // Bind the server socket to the local host and port
        InetAddress lh = InetAddress.getLocalHost();
        InetSocketAddress isa = new InetSocketAddress(lh, port);
        ssc.bind(isa);

        ssc.accept(this, new CompletionHandler<AsynchronousSocketChannel, AIOTimeServer>() {
            @Override
            public void completed(AsynchronousSocketChannel result, AIOTimeServer attachment) {
                // 读取客户端数据
                ByteBuffer byteBuffer = ByteBuffer.allocate(2000);
                result.read(byteBuffer);
  

                String responseDocument = ("<html><body>" +
                        "AIO Server: " +  System.currentTimeMillis() + "</body></html>");

                String responseHeader = ("HTTP/1.1 200 OK\r\n" +
                        "Content-Type: text/html; charset=UTF-8\r\n" +
                        "Content-Length: " + responseDocument.length() +
                        "\r\n\r\n");

                try {
                    // 响应客户端数据
                    result.write(encoder.encode(CharBuffer.wrap(responseHeader)));
                    result.write(encoder.encode(CharBuffer.wrap(responseDocument)));
                } catch (IOException e) {
                    e.printStackTrace();
                }


                try {
                    // 关闭连接
                    result.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void failed(Throwable exc, AIOTimeServer attachment) {
                System.out.println("failed");
            }
        });
    

?

所以 Proactor 也是基于事件处理的软件设计模式, 对 OS 的数据ready 事件作出反应, 所以依赖于操作系统的 AIO , windows 对?AIO 支持较好, POSIX 中已经定义了接口 aio_read/aio_write , 但是Linux 中一直没有实现, 直到 2.6 才真正实现可能还不完美.


如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~

?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-03-04 16:00:29  更:2022-03-04 16:02:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 4:40:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码