Scalable IO in Java(Java可伸缩IO)

翻译一下Doug Lea所写的Scalable IO in Java(Java可伸缩IO)

大多数的网络服务有着同样的处理流程:

  • Read request 请求数据读取
  • Decode request 请求数据解码
  • Process service 业务处理
  • Encode reply 响应编码
  • Send reply     响应发送

但是每一步的本质和代价是不一样的。

Scalable IO in Java(Java可伸缩IO)_第1张图片

Scalable IO in Java(Java可伸缩IO)_第2张图片

经典的服务器端套接字循环实现,每来一个客户端启动一个新的线程处理,但是这种方式第一个问题是无限的创建线程,第二个问题是IO阻塞。

Scalable IO in Java(Java可伸缩IO)_第3张图片

                                                          可伸缩性目标 

负载增加时优雅的降级(更多客户端)

资源(CPU,内存,磁盘,带宽)增加时持续提高

面临可用性和性能目标

    更少的延时

    满足高峰需求

    服务质量可调

分治法是通常实现任何可伸缩性目标的最佳方法。

Scalable IO in Java(Java可伸缩IO)_第4张图片

                                                           分治法

分成小任务处理

    每个任务执行一个非阻塞的操作

当每个任务就绪的时候执行

   这里的IO事件通常作为触发器

在java.nio的基本机制

   非阻塞的读和写

   任务的分发与感知IO事件相关联

无尽可能的变种

   基于事件驱动的家族

Scalable IO in Java(Java可伸缩IO)_第5张图片

                                                           事件驱动设计

 

通常比其他的更高效

更少的资源

      通常不需要一个客户端一个线程

更少的开销

    更少的上下文切换,更少的锁

但是更慢的分发

   必须手工的绑定行为到事件

通常编程更困难

    必须分成非阻塞的行为

       类似于GUI事件驱动行为

       必须清除所有的阻塞:GC,缺页等

必须保持跟踪服务的逻辑状态

Scalable IO in Java(Java可伸缩IO)_第6张图片

                                                    背景:AWT中的事件

事件驱动的IO使用相似的想法但是设计上不同

Scalable IO in Java(Java可伸缩IO)_第7张图片

                                                       Reactor模式

Reactor(反应器) 通过分发给合适的处理器来响应IO事件,类似于AWT线程

Handlers(处理器) 执行非阻塞的行为,类似与AWT的行为监听器

通过给事件绑定处理器,类似与AWT中添加行为监听器

 

Scalable IO in Java(Java可伸缩IO)_第8张图片

            单线程版本的基本反应器设计

Scalable IO in Java(Java可伸缩IO)_第9张图片

                                                           java.nio支持

Channels (通道)

    连接文件、套接字等,支持非阻塞读

Buffers(缓冲区)

    类数组对象能被通道直接读或写

Selectors(选择器)

   告诉通道的哪些集合有了IO事件

SelectionKeys(选择键)

   维护IO事件的状态和绑定关系

 

Scalable IO in Java(Java可伸缩IO)_第10张图片

 

Scalable IO in Java(Java可伸缩IO)_第11张图片

Scalable IO in Java(Java可伸缩IO)_第12张图片

Scalable IO in Java(Java可伸缩IO)_第13张图片

Scalable IO in Java(Java可伸缩IO)_第14张图片

 

Scalable IO in Java(Java可伸缩IO)_第15张图片

Scalable IO in Java(Java可伸缩IO)_第16张图片                                                      多线程的设计

有策略的为可伸缩性添加线程

       主要适用于多处理器

工作线程

反应器应当快速触发处理器

      处理器的处理拖慢了反应器

将非IO处理卸载到其他线程

多反应器线程

     反应器线程可以饱和IO

     将负载分配给其他反应器

         匹配CPU和IO的负载均衡

Scalable IO in Java(Java可伸缩IO)_第17张图片

                                                         工作线程 

卸载非IO处理加速Reactor线程

         类似于POSA2 Proactor设计

比将计算绑定处理重做为事件驱动形式更简单

          应当入仍然单纯非阻塞计算

                  足够处理超负载

 但是更难并行处理IO

           最好第一次将所有输入读进一个缓冲区

使用线程池调节和控制

           通常比客户端需要更少的线程

Scalable IO in Java(Java可伸缩IO)_第18张图片

 

Scalable IO in Java(Java可伸缩IO)_第19张图片

Scalable IO in Java(Java可伸缩IO)_第20张图片

                                                          协调任务 

Handoffs(速传)

       每个任务就绪,触发或调用下一个

       通常更快但是可能不友好

Callbacks(回调)

       状态集合,附件等

       一个GoF中介者模式的变种   

Queues (队列)

       例如,通过阶段跨过缓冲区

Futures(未来结果)

       每一个任务产生一个结果

      协调底层之上的join或者wait/notify

Scalable IO in Java(Java可伸缩IO)_第21张图片

                                                   PooledExecutor 的使用

一个可控制的工作线程池

主函数execue(Runnable r)

控制:

       任务队列的类型(任何通道)

      最大数量的线程

      最小数量的线程

       热点对战按需线程

      保活间隔直到空闲线程死亡

            如果需要后面可以被新的一个取代

      饱和政策

           阻塞,丢弃,生产者运行等

Scalable IO in Java(Java可伸缩IO)_第22张图片

                                                        多 Reactor线程

使用Reactor池

      用于匹配CPU和IO速率

      静态或动态构建

           每个有自己的Selector(选择器),Thread(线程),dispatch loop(分发循环)

       Main acceptor分配给其他Reactor

Scalable IO in Java(Java可伸缩IO)_第23张图片

 

   

你可能感兴趣的:(Netty)