Tomcat请求处理
2018-01-04 09:58
363 查看
1.用浏览器直接请求http://localhost:8080/,tomcat使用Acceptor监听端口,countUpOrAwaitConnection();控制最大连接数,接收请求socket = serverSock.accept();,获取缓存nioChannels中的NioChannel ,清空原有的buffer,给Socket 设置相应的属性,
protected boolean setSocketOptions(SocketChannel socket) {
// Process the connection
try {
//disable blocking, APR style, we are gonna be polling it
socket.configureBlocking(false);
Socket sock = socket.socket();
socketProperties.setProperties(sock);
NioChannel channel = nioChannels.pop();
if (channel == null) {
SocketBufferHandler bufhandler = new SocketBufferHandler(
socketProperties.getAppReadBufSize(),
socketProperties.getAppWriteBufSize(),
socketProperties.getDirectBuffer());
if (isSSLEnabled()) {
channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
} else {
channel = new NioChannel(socket, bufhandler);
}
} else {
channel.setIOChannel(socket);
channel.reset();
}
getPoller0().register(channel);
}
return true;
}顺序选择初始化时创建的两个Poller中的其中一个,创建NioSocketWrapper(注册SelectionKey.OP_READ)和socket,Poller绑定在一起,从缓存eventCache取出PollerEvent或者新建一个进行包装,设置相应的监听事件OP_REGISTER,
public void register(final NioChannel socket) {
socket.setPoller(this);
NioSocketWrapper ka = new NioSocketWrapper(socket, NioEndpoint.this);
socket.setSocketWrapper(ka);
ka.setPoller(this);
ka.setReadTimeout(getSocketProperties().getSoTimeout());
ka.setWriteTimeout(getSocketProperties().getSoTimeout());
ka.setKeepAliveLeft(NioEndpoint.this.getMaxKeepAliveRequests());
ka.setSecure(isSSLEnabled());
ka.setReadTimeout(getConnectionTimeout());
ka.setWriteTimeout(getConnectionTimeout());
PollerEvent r = eventCache.pop();
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);
}放入SynchronizedQueue,并且通知selector,然后等待Poller线程拉取
public boolean events() {
boolean result = false;
PollerEvent pe = null;
for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++ ) {
result = true;
try {
pe.run();
pe.reset();
if (running && !paused) {
eventCache.push(pe);
}
} catch ( Throwable x ) {
log.error("",x);
}
}
return result;
}从SynchronizedQueue中poll()取出请求,并且pe.run();清空后放入缓存eventCache.push(pe);以待下次请求直接使用,他主要是把SelectionKey和socketWrapper绑定在一起
socket.getIOChannel().register(
socket.getPoller().getSelector(), SelectionKey.OP_READ, socketWrapper);
最后selector.selectedKeys()取出前面放入的NioSocketWrapper,这种方式类似一种缓冲机制
Iterator<SelectionKey> iterator =
keyCount > 0 ? selector.selectedKeys().iterator() : null;
// Walk through the collection of ready keys and dispatch
// any active event.
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();
// Attachment may be null if another thread has called
// cancelledKey()
if (attachment == null) {
iterator.remove();
} else {
iterator.remove();
processKey(sk, attachment);
}
}//while进行处理processKey(sk, attachment);处理isReadable事件,
unreg(sk, attachment, sk.readyOps());
boolean closeSocket = false;
// Read goes before write
if (sk.isReadable()) {
if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
closeSocket = true;
}
}
创建或从缓存取出SocketProcessor,把相关信息设置完毕后放入线程池异步执行,
public boolean processSocket(SocketWrapperBase<S> socketWrapper,SocketEvent event, boolean dispatch) {
try {
SocketProcessorBase<S> sc = processorCache.pop();
if (sc == null) {
sc = createSocketProcessor(socketWrapper, event);
} else {
sc.reset(socketWrapper, event);
}
Executor executor = getExecutor();
if (dispatch && executor != null) {
executor.execute(sc);
} else {
sc.run();
}
}
return true;
}3.处理Socket请求SocketProcessor .doRun()。先确认三次握手成功socket.isHandshakeComplete(),开始处理state = getHandler().process(socketWrapper, event);-》ConnectionHandler.process(),设置当前线程标志ContainerThreadMarker.set();创建getProtocol().createProcessor();或者从缓存recycledProcessors.pop();中取出Http11Processor,添加jmx属性register(processor);将处理器与连接关联 connections.put(socket,
processor);-》state = processor.process(wrapper, status);-》 state =
Http11Processor.service(socketWrapper);请求信息会有8个不同的状态
RequestInfo rp = request.getRequestProcessor();
rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
// Setting up the I/O
setSocketWrapper(socketWrapper);
inputBuffer.init(socketWrapper);
outputBuffer.init(socketWrapper);
解析请求头Http11InputBuffer.parseHeaders(),请求前处理prepareRequest();
rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
prepareRequest();适配器CoyoteAdapter创建服务
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
getAdapter().service(request, response);创建具体传到业务端的request,response,最后用HttpServletRequest包装一下,就是我们开发业务系统时常用的属性
// Create objects
request = connector.createRequest();
request.setCoyoteRequest(req);
response = connector.createResponse();
response.setCoyoteResponse(res);
// Link objects
request.setResponse(resp
4000
onse);
response.setRequest(request);解析设置具体配置请求参数postParseSuccess = postParseRequest(req, request, res, response);查找对应的各级容器,设置sessionID等信息
connector.getService().getMapper().map(serverName, decodedURI, version, request.getMappingData());
// Virtual host mapping
MappedHost[] hosts = this.hosts;
MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
开始依次通过各级容器的管道invoke处理
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
StandardEngineValve-》AccessLogValve父类AbstractAccessLogValve-》ErrorReportValve-》StandardHostValve-》StandardContextValve这里会更改类加载器系统加载器为自定义加载器ParallelWebappClassLoader-》StandardWrapperValve分配servlet实例来处理此请求servlet = wrapper.allocate();为这个请求创建过滤器链,过滤器链需要从context容器获取FilterMap
filterMaps[] = context.findFilterMaps();
ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
4.在ApplicationFilterChain类中执行具体请求,传递HttpServletRequest和HttpServletResponse
filterChain.doFilter(request.getRequest(), response.getResponse());如果有过滤器依次执行filter.doFilter(request, response, this);
最后调用 servlet.service(request, response);-》HttpServlet.service(request, response);SpringMVC的DispatcherServlet就是实现的这个地方,执行完之后清理ThreadLocal中的缓存,以及一些其他的对象使用wrapper.deallocate(servlet);
protected boolean setSocketOptions(SocketChannel socket) {
// Process the connection
try {
//disable blocking, APR style, we are gonna be polling it
socket.configureBlocking(false);
Socket sock = socket.socket();
socketProperties.setProperties(sock);
NioChannel channel = nioChannels.pop();
if (channel == null) {
SocketBufferHandler bufhandler = new SocketBufferHandler(
socketProperties.getAppReadBufSize(),
socketProperties.getAppWriteBufSize(),
socketProperties.getDirectBuffer());
if (isSSLEnabled()) {
channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
} else {
channel = new NioChannel(socket, bufhandler);
}
} else {
channel.setIOChannel(socket);
channel.reset();
}
getPoller0().register(channel);
}
return true;
}顺序选择初始化时创建的两个Poller中的其中一个,创建NioSocketWrapper(注册SelectionKey.OP_READ)和socket,Poller绑定在一起,从缓存eventCache取出PollerEvent或者新建一个进行包装,设置相应的监听事件OP_REGISTER,
public void register(final NioChannel socket) {
socket.setPoller(this);
NioSocketWrapper ka = new NioSocketWrapper(socket, NioEndpoint.this);
socket.setSocketWrapper(ka);
ka.setPoller(this);
ka.setReadTimeout(getSocketProperties().getSoTimeout());
ka.setWriteTimeout(getSocketProperties().getSoTimeout());
ka.setKeepAliveLeft(NioEndpoint.this.getMaxKeepAliveRequests());
ka.setSecure(isSSLEnabled());
ka.setReadTimeout(getConnectionTimeout());
ka.setWriteTimeout(getConnectionTimeout());
PollerEvent r = eventCache.pop();
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);
}放入SynchronizedQueue,并且通知selector,然后等待Poller线程拉取
private void addEvent(PollerEvent event) { events.offer(event); if ( wakeupCounter.incrementAndGet() == 0 ) selector.wakeup(); }2.Poller线程一直在执行keyCount = selector.select(selectorTimeout);,默认间隔时间是一秒,当收到通知后,这里就会返回1,而且他会一直执行events()
public boolean events() {
boolean result = false;
PollerEvent pe = null;
for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++ ) {
result = true;
try {
pe.run();
pe.reset();
if (running && !paused) {
eventCache.push(pe);
}
} catch ( Throwable x ) {
log.error("",x);
}
}
return result;
}从SynchronizedQueue中poll()取出请求,并且pe.run();清空后放入缓存eventCache.push(pe);以待下次请求直接使用,他主要是把SelectionKey和socketWrapper绑定在一起
socket.getIOChannel().register(
socket.getPoller().getSelector(), SelectionKey.OP_READ, socketWrapper);
最后selector.selectedKeys()取出前面放入的NioSocketWrapper,这种方式类似一种缓冲机制
Iterator<SelectionKey> iterator =
keyCount > 0 ? selector.selectedKeys().iterator() : null;
// Walk through the collection of ready keys and dispatch
// any active event.
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();
// Attachment may be null if another thread has called
// cancelledKey()
if (attachment == null) {
iterator.remove();
} else {
iterator.remove();
processKey(sk, attachment);
}
}//while进行处理processKey(sk, attachment);处理isReadable事件,
unreg(sk, attachment, sk.readyOps());
boolean closeSocket = false;
// Read goes before write
if (sk.isReadable()) {
if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
closeSocket = true;
}
}
创建或从缓存取出SocketProcessor,把相关信息设置完毕后放入线程池异步执行,
public boolean processSocket(SocketWrapperBase<S> socketWrapper,SocketEvent event, boolean dispatch) {
try {
SocketProcessorBase<S> sc = processorCache.pop();
if (sc == null) {
sc = createSocketProcessor(socketWrapper, event);
} else {
sc.reset(socketWrapper, event);
}
Executor executor = getExecutor();
if (dispatch && executor != null) {
executor.execute(sc);
} else {
sc.run();
}
}
return true;
}3.处理Socket请求SocketProcessor .doRun()。先确认三次握手成功socket.isHandshakeComplete(),开始处理state = getHandler().process(socketWrapper, event);-》ConnectionHandler.process(),设置当前线程标志ContainerThreadMarker.set();创建getProtocol().createProcessor();或者从缓存recycledProcessors.pop();中取出Http11Processor,添加jmx属性register(processor);将处理器与连接关联 connections.put(socket,
processor);-》state = processor.process(wrapper, status);-》 state =
Http11Processor.service(socketWrapper);请求信息会有8个不同的状态
RequestInfo rp = request.getRequestProcessor();
rp.setStage(org.apache.coyote.Constants.STAGE_PARSE);
// Setting up the I/O
setSocketWrapper(socketWrapper);
inputBuffer.init(socketWrapper);
outputBuffer.init(socketWrapper);
解析请求头Http11InputBuffer.parseHeaders(),请求前处理prepareRequest();
rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
prepareRequest();适配器CoyoteAdapter创建服务
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
getAdapter().service(request, response);创建具体传到业务端的request,response,最后用HttpServletRequest包装一下,就是我们开发业务系统时常用的属性
// Create objects
request = connector.createRequest();
request.setCoyoteRequest(req);
response = connector.createResponse();
response.setCoyoteResponse(res);
// Link objects
request.setResponse(resp
4000
onse);
response.setRequest(request);解析设置具体配置请求参数postParseSuccess = postParseRequest(req, request, res, response);查找对应的各级容器,设置sessionID等信息
connector.getService().getMapper().map(serverName, decodedURI, version, request.getMappingData());
// Virtual host mapping
MappedHost[] hosts = this.hosts;
MappedHost mappedHost = exactFindIgnoreCase(hosts, host);
// Context mapping ContextList contextList = mappedHost.contextList; MappedContext[] contexts = contextList.contexts; int pos = find(contexts, uri);
// Wrapper mapping if (!contextVersion.isPaused()) { internalMapWrapper(contextVersion, uri, mappingData); }
开始依次通过各级容器的管道invoke处理
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);
StandardEngineValve-》AccessLogValve父类AbstractAccessLogValve-》ErrorReportValve-》StandardHostValve-》StandardContextValve这里会更改类加载器系统加载器为自定义加载器ParallelWebappClassLoader-》StandardWrapperValve分配servlet实例来处理此请求servlet = wrapper.allocate();为这个请求创建过滤器链,过滤器链需要从context容器获取FilterMap
filterMaps[] = context.findFilterMaps();
ApplicationFilterChain filterChain = ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
4.在ApplicationFilterChain类中执行具体请求,传递HttpServletRequest和HttpServletResponse
filterChain.doFilter(request.getRequest(), response.getResponse());如果有过滤器依次执行filter.doFilter(request, response, this);
最后调用 servlet.service(request, response);-》HttpServlet.service(request, response);SpringMVC的DispatcherServlet就是实现的这个地方,执行完之后清理ThreadLocal中的缓存,以及一些其他的对象使用wrapper.deallocate(servlet);
相关文章推荐
- 了解tomcat 2 -- tomcat是怎么处理一个请求的
- 关于spring boot 内嵌tomcat 在window上启动,处理请求卡死---阿里云服务器有瑕疵
- Tomcat处理一个HTTP请求的过程
- 用tomcat处理n个请求来说明,什么是进程,什么是线程
- tomcat的结构 以及处理请求的流程
- tomcat原理,一个客户端请求的处理过程
- 什么是多线程?以tomcat处理n个请求为例
- Tomcat Server处理一个http请求的过程
- Tomcat源码解读系列(三)——Tomcat对HTTP请求处理的整体流程
- Day06 4000 Ajax中跨域请求,域名处理,forward与redirect区别,tomcat中配置虚拟主机
- Tomcat在处理GET和POST请求时产生的乱码问题
- [Tomcat6.0源码]请求的处理三Mapper、JMX
- tomcat原理解析(五):http请求处理
- tomcat处理一个请求的过程
- Tomcat在处理GET和POST请求时产生的乱码问题
- 解析Tomcat处理请求的类Connector<1>
- Apache+tomcat+jk处理请求的简单流程
- tomcat、Oracle为例,解释是它们是怎么处理大量并发请求的?
- 字符集编码问题(get/post请求,tomcat有不同的处理)
- Tomcat在处理GET和POST请求时产生的乱码问题