您的位置:首页 > 运维架构 > Tomcat

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线程拉取
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