高扩展的基于NIO的服务器架构

当你考虑写一个扩展性良好的基于Java的服务器时,相信你会毫不犹豫地使用Java的NIO包。为了确保你的服务器能够健壮、稳定地运行,你可能会花大量的时间阅读博客和教程来了解线程同步的NIO selector 类和处理常见的陷阱上。本篇文章介绍了一个基本的、面向连接的基于NIO的服务器架构。在介绍之前,让我们先来看一下该它首选的线程模型和它的基本组件。

线程架构模型
最先想到的实现多线程服务器程序的方法是每个线程负责一个连接。这是传统的,JDK1.4版本以前的解决方案,因为老版本的JDK缺少非阻塞支持。这种方式为每一个连接创建一个工作线程。由创建的工作线程等待新传入的数据,处理请求,返回相应数据,并在此调用阻塞套接字的读数据的相关方法。

public class Server {

	private ExecutorService executors = Executors.newFixedThreadPool(10);
	
	private boolean isRunning = true;
	
	public static void main(string[] args) {
	
		new server().launch(Integer.parseInt(args[0]));
	
	}
	
	public void launch(int port) {
	
		ServerSocket sso = new ServerSocket(port);
		
		while(isRunning) {
		
			Socket s = sso.accept();
			executors.execute(new Worker(s));
		
		}
	
	}
	
	private class Worker implements Runnable {
	
		private LineNumberReader in = null;
		...
		
		Worker(Socket s) {
		
			in = new LineNumberReader(new InputStreamReader(...));
			out = ...
		
		}
		
		public void run() {
		
			while(isRunning) {
			
				try {
				
					// blocking read of a request (line)
					String request = in.readLine();
					
					// processing the request
					...
					out.write(response);
					out.flush();
				
				} catch(Exception e) {
				
					...
				
				}
			
			}
			
			in.close();
			...
		}
	
	}

}


客户端的并发的连接和工作线程之间是一一对应的,每个连接所关联的线程等待在服务器端的响应。这样每个客户端的连接的响应时间都比较短。但是当并发量较大时,数百个甚至上千个线程浪费了大量的堆栈空间,系统效率大大下降。

如果服务器端需要处理高并发的、持续时间长的连接请求时,传统的一个连接对应一个工作线程的方式显然是行不通的。线程与事件对应的模型是一种有效的方式,工作线程独立于连接,只会用来处理特定的事件。例如,如果一个接收到的数据事件发生时,一个工作线程将会从线程池中拿出来处理该事件,处理完后,工作线程返回线程池。这种线程与事件对应的模型执行socketI/O的非阻塞方式。这种由事件驱动的I/O系统设计被称为Reactor模式

见下文高扩展的基于NIO的服务器架构(二)

原文地址:https://www.cnblogs.com/fuhaots2009/p/3429176.html