二、跟随源码读netty

2019-11-15  本文已影响0人  一直想上树的猪

一、Reactor模式

Netty是典型的Reactor模型结构,关于Reactor的详尽阐释,本文站在巨人的肩膀上,借助 Doug Lea(就是那位让人无限景仰的大爷)的“Scalable IO in Java”中讲述的Reactor模式。

“Scalable IO in Java”的地址是:http://gee.cs.oswego.edu/dl/cpjslides/nio.pdf

Reactor模式也叫反应器模式,大多数IO相关组件如Netty、Redis在使用的IO模式,为什么需要这种模式,它是如何设计来解决高性能并发的呢?

二、多线程IO的致命缺陷

最最原始的网络编程思想就是服务器用一个while循环,不断监听端口是否有新的socket连接,如果有,那么就用一个处理函数处理。

while(true){
  socket = accept();
  handle(socket);
}

这种方法最大的问题就是无法并发,效率太低,如果当前的请求没有处理完,那么后面的请求只能被阻塞,服务器的吞吐量太低。
用多线程改进
很经典的connection pre thread,每一个连接用一个线程处理

package com.tinner.thread;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @Author: Tinner
 * @create: 2019/11/15 10:20
 * @Description: 使用多线程处理IO请求,每一个连接用一个线程处理
 */
public class testNIO1 {

    public void run(){
        try{
            ServerSocket ss =
                    new ServerSocket(8043);
            while (!Thread.interrupted()){
                new Thread(new Handler(ss.accept())).start();
            }
        }catch (IOException ex){
            ex.printStackTrace();
        }
    }

    static class Handler implements Runnable{
        final Socket socket;
        Handler(Socket s){
            socket = s;
        }

        public void run(){
            try{
                byte[] input = new byte[1024];
                socket.getInputStream().read(input);
                byte[] output = process(input);
                socket.getOutputStream().write(output);
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        private byte[] process(byte[] input){
            byte[] output = null;
            //TODO
            return output;
        }
    }

}

对于每个请求都分发给一个线程,每个线程中都独立处理上面的流程。
Tomcat服务器的早期版本确实是这样实现的。

上一篇下一篇

猜你喜欢

热点阅读