zoukankan      html  css  js  c++  java
  • 高扩展的基于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的服务器架构(二)

  • 相关阅读:
    截取字符串
    VC++ PathFindFileName函数,由文件路径获得文件名
    获取GetOpenFileName多选文件名
    WideCharToMultiByte和MultiByteToWideChar函数的用法(转载)
    map set iterator not incrementable 解决办法
    定义c/c++全局变量/常量几种方法的区别(转载)
    如何禁止同IP站点查询和同IP站点查询的原理分析 Robots.txt屏蔽BINGBOT
    JavaScript 文件操作方法详解
    nginx日志配置
    php的strip_tags,htmlspecialchars,htmlentities,stripslashes,addslashes解释
  • 原文地址:https://www.cnblogs.com/fuhaots2009/p/3429176.html
Copyright © 2011-2022 走看看