Tomcat启动过程(二):EndPoint解析
EndPoint提供基础的网络IO服务,用来实现网络连接和控制,它是服务器对外I/O操作的接入点。主要任务是管理对外的socket连接,同时将建立好的socket连接交到合适的工作线程中去。
里面两个主要的属性类是Acceptor和Poller、SocketProcessor
Acceptor
Acceptor类实现了Runnable接口,主要用于接收网络请求,建立连接,连接建立之后,将一个SocketChannel对象包装成一个NioChannel,并注册到Poller中。由Poller来负责执行数据的读取和业务执行。
我们看一下Acceptor的run方法:
public void run() {
     SocketChannel socket = serverSock.accept();//从监听的serversocket中获取新的连接
     setSocketOptions(socket);//设置通道的属性
     ……
}
protected boolean setSocketOptions(SocketChannel socket) {
    NioChannel = channel = new NioChannel(socket, bufhandler);//将通道包装成NioChannel
    getPoller0().register(channel);//从poller数组中选择一个poller,将channel注册到poller中
    ……
}
Poller
Poller实现了Runnable接口,在NioEndpoint的时候,会初始化pollers数组,同时启动pollers数组中的线程,让pollers开始工作。
封装后socketchannel的放入Poller线程内部维护的一个PollerEvent队列中,然后在Poller线程运行时处理队列,将socketchannel注册到这个Poller的Selector上。
当事件到来的时候,Selector发现要处理的事件,通过selector.select系列方法来获取数据,然后经由processKey到processSocket方法,封装成一个SocketProcessor对象后,放在EndPoint的线程池中执行。
SocketChannel是如何注册到Poller中的?
protected ConcurrentLinkedQueue<Runnable> events = new ConcurrentLinkedQueue<Runnable>();//内部维护的事件队列
public void register(final NioChannel socket)
{
socket.setPoller(this);
KeyAttachment key = keyCache.poll();
final KeyAttachment ka = key!=null?key:new KeyAttachment();
ka.reset(this,socket,getSocketProperties().getSoTimeout());
PollerEvent r = eventCache.poll();
ka.interestOps(SelectionKey.OP_READ);//this is what OP_REGISTER turns into.
if ( r==null) r = new PollerEvent(socket,ka,OP_REGISTER);
else r.reset(socket,ka,OP_REGISTER);
addEvent(r);//socketchannel、key一同加入到了events队列
}
SocketChannel是如何注册到每个Poller的selector中的?答案在event()方法中,在该方法中遍历events队列,依次执行run方法
public boolean events() {
    while ( (r = (Runnable)events.poll()) != null ) {
        result = true;
        r.run();
    }
    ……
}
public void run() {
    if ( interestOps == OP_REGISTER ) {
        socket.getIOChannel().register(socket.getPoller().getSelector(), SelectionKey.OP_READ, key);//注册到selector中
    }
    else {
        final SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
        int ops = key.interestOps() | interestOps;
        att.interestOps(ops);
        key.interestOps(ops);
        att.setCometOps(ops);//另外一种注册方法?
    }
   ……
}
Poller的执行在其run方法中,主要是将请求封装成SocketProcessor对象,交给线程池处理。
public void run() {
    if ( keyCount == 0 ) hasEvents = (hasEvents | events());//通过事件机制监控感兴趣的网络事件,见上面的events()分析
    //遍历渠道上到来的key,交给processor去处理
    Iterator iterator = keyCount > 0 ? selector.selectedKeys().iterator() : null;
    for()
    {
        SelectionKey sk = (SelectionKey) iterator.next();
        KeyAttachment attachment = (KeyAttachment)sk.attachment();
        processKey(sk, attachment);
    }
}
//processKey(sk, attachment)调用processSocket(channel, SocketStatus.OPEN),最终使用Endpoint的线程池执行请求
protected boolean processSocket(NioChannel socket, SocketStatus status, boolean dispatch) {
    KeyAttachment attachment = (KeyAttachment)socket.getAttachment(false);
    attachment.setCometNotify(false); //will get reset upon next reg
    sc = new SocketProcessor(socket,status);
    if ( dispatch ) executor.execute(sc);=====>任务被封装成SocketProcessor对象,在成功获取线程池后,则通过线程池来进行socket数据数据的读写操作。
    else sc.run();
    ……
} 
SocketProcessor
请求到达socketProcess之后,首先执行其run方法,请求被转移到handler.process,根据上下文,我们知道这了的hander指的是Http11ConnectionHandler
public void run() {
    (status==null)?(handler.process(socket)==Handler.SocketState.CLOSED) :
                    (handler.event(socket,status)==Handler.SocketState.CLOSED);
}

参考文献:
http://blog.csdn.net/yanlinwang/
Tomcat启动过程(二):EndPoint解析的更多相关文章
- Tomcat源码分析 (七)----- Tomcat 启动过程(二)
		
在上一篇文章中,我们分析了tomcat的初始化过程,是由Bootstrap反射调用Catalina的load方法完成tomcat的初始化,包括server.xml的解析.实例化各大组件.初始化组件等逻 ...
 - Tomcat架构解析(二)-----Connector、Tomcat启动过程以及Server的创建过程
		
Connector用于跟客户端建立连接,获取客户端的Socket,交由Container处理.需要解决的问题有监听.协议以及处理器映射等等. 一.Connector设计 Connector要实现的 ...
 - CentOS7 Tomcat 启动过程很慢,JVM上的随机数与熵池策略
		
1. CentOS7 Tomcat 启动过程很慢 在centos启动官方的tomcat时,启动过程很慢,需要几分钟,经过查看日志,发现耗时在这里:是session引起的随机数问题导致的: <co ...
 - Tomcat启动过程原理详解 -- 非常的报错:涉及了2个web.xml等文件的加载流程
		
Tomcat启动过程原理详解 发表于: Tomcat, Web Server, 旧文存档 | 作者: 谋万世全局者 标签: Tomcat,原理,启动过程,详解 基于Java的Web 应用程序是 ser ...
 - 转:Tomcat启动过程中找不到JAVA_HOME JRE_HOME的解决方法
		
转自:http://blog.sina.com.cn/s/blog_61c006ea0100l1u6.html 原文: 在XP上明明已经安装了JDK1.5并设置好了JAVA_HOME,可偏偏Tomca ...
 - Tomcat启动过程中找不到JAVA_HOME解决方法
		
在XP上明明已经安装了JDK1.5并设置好了JAVA_HOME,可偏偏Tomcat在启动过程中找不到. 报错信息如下:Neither the JAVA_HOME nor the JRE_HOME en ...
 - Tomcat启动过程中找不到JAVA_HOME JRE_HOME的解决方法
		
转自:http://blog.sina.com.cn/s/blog_61c006ea0100l1u6.html 原文: 在XP上明明已经安装了JDK1.5并设置好了JAVA_HOME,可偏偏Tomca ...
 - 浅读tomcat架构设计和tomcat启动过程(1)
		
一图甚千言,这张图真的是耽搁我太多时间了: 下面的tomcat架构设计代码分析,和这张图息息相关. 使用maven搭建本次的环境,贴出pom.xml完整内容: <?xml version=&qu ...
 - Tomcat源码分析 (六)----- Tomcat 启动过程(一)
		
说到Tomcat的启动,我们都知道,我们每次需要运行tomcat/bin/startup.sh这个脚本,而这个脚本的内容到底是什么呢?我们来看看. 启动脚本 startup.sh 脚本 #!/bin/ ...
 
随机推荐
- JS 中的 Window 对象
			
窗口对象的属性和方法: 在js最外层写的function可以还可以理解为window对象的一个方法.定义的变量也可以称之为window对象的一个属性.例如:window.alert("--- ...
 - by which, in which, from which 语法区别
			
(1)Here is Beijing,where I grow up.where其实也是指代北京,不过where是在北京的意思,也就是 in Beijing (2)Here is Beijing,in ...
 - NPM使用
			
安装路径修改: 4.配置npm的全局模块存放路径和cache路径 输入以下命令 npm config set prefix “D:\Program Files\node\node-global” n ...
 - 无法创建spool文件
			
是因为没有用管理员运行CMD,并且数据库不需要使用超级管理员登录.
 - java获取本机IP地址和MAC地址的方法
			
// 获取ip地址 public static String getIpAddress() { try { Enumeration<NetworkInterface> allNetInte ...
 - [ActionScript 3.0]  Away3D 天空盒(skybox)例子2
			
所谓skybox就是六个面即六张图能够无缝的拼成一个正方体的盒子. package { import away3d.cameras.Camera3D; import away3d.cameras.le ...
 - So Hard (水题)
			
题目网址:http://acm.fzu.edu.cn/problem.php?pid=2193 Problem Description 请将有限小数化为最简分数. Input 一个整数n 表示需要转化 ...
 - java内省机制Introspector
			
访问JavaBean属性的两种方式 1)直接调用bean的setXXX或getXXX方法: 2)通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式: a)通过P ...
 - 未完全关闭数据库导致ORA-01012: not logged的解决
			
首先使用SHUTDOWN 没加任何参数方式关闭数据库,在数据库未关闭时CTRL+Z停止执行,退出用SQLPLUS重登陆,出现报错:ORA-01012: not logged on SQL> st ...
 - TesCase-GUI(图形用户界面)测试
			
GUI测试是功能测试的一种表现形式.不仅要考虑GUI本身的测试,也要考虑GUI所表现的系统功能的测试. GUI应具有的要素 1.符合标准和规范 2.直观性 (1)用户界面是否洁净.不唐突.不拥挤? ...