- 浏览: 252606 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
mabusyao:
漠北空城 写道请问下,你这个是JDK版本是多少呢?!忘记了,应 ...
HashMap 源码解读 -
漠北空城:
请问下,你这个是JDK版本是多少呢?!
HashMap 源码解读 -
schumee:
完美团队~
项目沉思录 - 1.1 -
winie:
整理下 搞成引擎嘛 国产需要这样的engine
简单工作流引擎 -
mabusyao:
某位同学给我提供的堪称完美的解决方案:1. 将三个int数组放 ...
CraneWork
本来想自己写的,结果在网上找到别人写的,概括的非常详细,就直接转过来了:
Tomcat中提供了多种处理Socket的实现:JIoEndpoint、AprEndpoint和NioEndpoint。其中JIoEndpoint是最常见的一种实现方式。
JIOEndpoint中的线程有3部分:Socket侦听线程、监控线程和Executor。
Socket侦听线程
该线程由内部类Acceptor实现其Runnable接口,使用JDK的ServerSocket类监听某个端口,当socket连接进来时,构建一个task,交给Executor来处理。
监控线程
该线程由AsyncTimeout实现其Runnable接口,不断遍历Request队列,为Timeout的Request构造一个TIMEOUT task,交给Executor来处理。
Executor
Executor负责提供工作线程用来处理侦听线程和监控线程构造的task。该task会完成对Request回应。如果用户没有指定Executor,JIoEndpoint中会自动创建org.apache.tomcat.util.threads.ThreadPoolExecutor作为默认实现。
按照工作流程的顺序介绍一下各个部分:
初始化:bind()
// Loop until we receive a shutdown command
public void bind() throws Exception {
if (acceptorThreadCount == 0) {
acceptorThreadCount = 1;
}
if (serverSocketFactory == null) {
if (isSSLEnabled()) {
ServerSocketFactory = handler.getSslImplementation().getServerSocketFactory(this);
} else {
ServerSocketFactory = new DefaultServerSocketFactory(this);
}
}
try {
if (getAddress() == null) {
serverSocket = serverSocketFactory.createSocket(getPort(),
getBacklog());
} else {
serverSocket = serverSocketFactory.createSocket(getPort(),
getBacklog(), getAddress());
}
} catch (BindException orig) {
String msg;
if (getAddress() == null)
msg = orig.getMessage() + " <null>:" + getPort();
else
msg = orig.getMessage() + " " +
getAddress().toString() + ":" + getPort();
BindException be = new BindException(msg);
be.initCause(orig);
throw be;
}
}
}
public void startInternal() throws Exception {
running = true;
paused = false;
if (getExecutor() == null) {
createExecutor();
}
initializeConnectionLatch();
for (int i = 0; i < acceptorThreadCount; i++) {
Thread acceptorThread = new Thread(new Acceptor(),
getName() + "-Acceptor-" + i);
acceptorThread.setPriority(threadPriority);
acceptorThread.setDaemon(getDaemon());
acceptorThread.start();
}
// Start async timeout thread
Thread timeoutThread = new Thread(new AsyncTimeout(),
getName() + "-AsyncTimeout");
timeoutThread.setPriority(threadPriority);
timeoutThread.setDaemon(true);
timeoutThread.start();
}
}
@Override
public void run() {
while (running) {
while (paused && running) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
break;
}
try {
//if we have reached max connections, wait
awaitConnection();
try {
// Accept the next incoming connection from the server
// socket
socket = serverSocketFactory.acceptSocket(serverSocket);
} catch (IOException ioe) {
// Introduce delay if necessary
errorDelay = handleExceptionWithDelay(errorDelay);
// re-throw
throw ioe;
}
// Successful accept, reset the error delay
errorDelay = 0;
if (setSocketOptions(socket)) {
// Hand this socket off to an appropriate processor
if (!processSocket(socket)) {
// Close socket right away
try {
socket.close();
} catch (IOException e) {
// Ignore
}
} else {
countUpConnection();
}
} else {
// Close socket right away
try {
socket.close();
} catch (IOException e) {
// Ignore
}
}
} catch (IOException x) {
if (running) {
log.error(sm.getString("endpoint.accept.fail"), x);
}
} catch (NullPointerException npe) {
if (running) {
log.error(sm.getString("endpoint.accept.fail"), npe);
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString("endpoint.accept.fail"), t);
}
// The processor will recycle itself when it finishes
}
}
}
protected boolean processSocket(Socket socket) {
// Process the request from this socket
try {
SocketWrapper<Socket> wrapper = new SocketWrapper<Socket>(socket);
wrapper.setKeepAliveLeft(getMaxKeepAliveRequests());
// During shutdown, executor may be null - avoid NPE
if (!running) {
return false;
}
getExecutor().execute(new SocketProcessor(wrapper));
} catch (RejectedExecutionException x) {
log.warn("Socket processing request was rejected for:"+socket,x);
return false;
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
// This means we got an OOM or similar creating a thread, or that
// the pool and its queue are full
log.error(sm.getString("endpoint.process.fail"), t);
return false;
}
return true;
}
protected class SocketProcessor implements Runnable {
protected SocketWrapper<Socket> socket = null;
protected SocketStatus status = null;
public SocketProcessor(SocketWrapper<Socket> socket) {
if (socket==null) throw new NullPointerException();
this.socket = socket;
}
this(socket);
this.status = status;
}
public void run() {
boolean launch = false;
synchronized (socket) {
try {
SocketState state = SocketState.OPEN;
// SSL handshake
serverSocketFactory.handshake(socket.getSocket());
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
if (log.isDebugEnabled()) {
log.debug(sm.getString("endpoint.err.handshake"), t);
}
// Tell to close the socket
state = SocketState.CLOSED;
}
if ( (state != SocketState.CLOSED) ) {
state = (status==null)?handler.process(socket):handler.process(socket,status);
}
if (state == SocketState.CLOSED) {
// Close socket
if (log.isTraceEnabled()) {
log.trace("Closing socket:"+socket);
}
countDownConnection();
try {
socket.getSocket().close();
} catch (IOException e) {
// Ignore
}
} else if (state == SocketState.ASYNC_END ||
state == SocketState.OPEN){
socket.setKeptAlive(true);
socket.access();
launch = true;
} else if (state == SocketState.LONG) {
socket.access();
waitingRequests.add(socket);
}
} finally {
if (launch) {
try {
getExecutor().execute(new SocketProcessor(socket, SocketStatus.OPEN));
} catch (NullPointerException npe) {
if (running) {
log.error(sm.getString("endpoint.launch.fail"),
npe);
}
}
}
}
}
socket = null;
// Finish up this request
}
}
protected class AsyncTimeout implements Runnable {
@Override
public void run() {
while (running) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
long now = System.currentTimeMillis();
Iterator<SocketWrapper<Socket>> sockets =
waitingRequests.iterator();
while (sockets.hasNext()) {
SocketWrapper<Socket> socket = sockets.next();
long access = socket.getLastAccess();
if ((now-access)>socket.getTimeout()) {
processSocketAsync(socket,SocketStatus.TIMEOUT);
}
}
// Loop if endpoint is paused
while (paused && running) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// Ignore
}
}
}
}
}
评论
发表评论
-
初识ThreadLocal
2015-07-07 13:15 1511最近公司在进行Java开发人员的招聘活动,其中有一道面试题 ... -
Always clean the ThreadLocal variables.
2012-05-24 09:16 1213Any variable stored in ThreadLo ... -
(转)TOMCAT源码分析
2011-10-17 16:06 2126TOMCAT源码分析(启动框架 ... -
Tomcat 源码学习 之 Http11ConnectionHandler
2011-07-14 11:31 1830Class Name org.apache.c ... -
Tomcat 源码学习 之 Connector
2011-07-12 10:14 1496类名 org.apache.catali ... -
Tomcat 源码学习 之 StandardService
2011-07-07 15:57 1687类名 org.apache.catalina. ... -
Tomcat 源码学习 之 AprLifecycleListener
2011-06-30 16:52 4011类名 org.apache.catalina ... -
Tomcat 源码学习 之 StandardServer
2011-06-29 14:59 2342类名 StandardServer 继承关系 ... -
Tomcat 源码学习 之 Catalina
2011-06-12 18:06 1569类名 Catalina ... -
Tomcat 源码学习 之 Bootstrap
2011-06-08 09:57 4479类名 Bootstrap 继承关系 ... -
Tomcat整体架构图(转)
2011-06-06 10:35 1388从前辈那里转过来的: -
如何在关闭时进行清理工作
2011-05-27 15:11 1059我们常常会遇到这样的情况,当程序运行结束的时候,要将一些资源连 ... -
Tomcat 中的有状态线程池
2011-05-19 10:09 2764Tomcat中的connector负责将从客户端发出的请求封装 ... -
Tomcat中的Request & Response 设计结构
2011-05-18 10:22 5541老版Tomcat使用catalina作为其连接器和容器的架构, ...
相关推荐
### Tomcat7源码手撕过程详解 #### Tomcat初始化流程分析 Tomcat是一个流行的Java Servlet容器,用于部署和运行Web应用程序。理解Tomcat的工作原理对于优化应用性能、解决部署问题至关重要。以下是对Tomcat7启动...
Apache Tomcat是Java开发人员最常用的Web服务器之一,它不仅能够作为独立的应用程序运行Servlet和JavaServer Pages(JSP),还可以作为一个内嵌的容器来运行Web应用。Tomcat的核心设计遵循了模块化原则,这使得其...
chm文件,方便查找,包含tomcat6.0核心类,如Connector,Lifecycle,http11Protocal,JIoEndPoint,javax包等。
请求处理是Tomcat的核心功能之一,涉及到HTTP请求的接收、解析以及最终的Servlet执行。 - **请求处理流程**: - 接收客户端发送的HTTP请求。 - 解析HTTP请求。 - 根据URL映射到相应的Servlet。 - 执行Servlet...
在BIO模式下,Tomcat使用JIoEndpoint组件监听指定端口,每当有新的连接请求到达,它会将请求放入线程池进行处理。线程池中的线程会调用Http11Processor组件解析HTTP协议,并通过适配器(Adapter)将请求映射到相应的...
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:624) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
- **创建Socket连接**:Tomcat通过调用`JIoEndpoint.java`的`run()`方法创建socket连接。 - **解析HTTP协议**:通过`processor.process(socket)`方法解析HTTP请求并返回响应内容。`processor`是`HttpProcessor`的一...
java.lang.SecurityException: class "org.apache.commons.collections.SequencedHashMap... at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447) at java.lang.Thread.run(Unknown Source)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:662) 网络解决办法: (虽然该办法可行,但是本人并不提倡。具体原因在之后解释。) 在...