抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Tomcat请求流程

Tomcat请求过程

  1. Connector组件的Acceptor监听客户端套接字连接并接收Socket。
  2. 将连接交给线程池Executor处理,开始执行请求响应任务。
  3. Processor组件读取消息报文,解析请求行、请求体、请求头,封装成Request对象。
  4. Mapper组件根据请求行的URL值和请求头的Host值匹配由哪个Host容器、Context容器、Wrapper容器处理请求。
  5. CoyoteAdaptor组件负责将Connector组件和Engine容器关联起来,把生成的Request对象和响应对象Response传递到Engine容器中,调用 Pipeline。
  6. Engine容器的管道开始处理,管道中包含若干个Valve、每个Valve负责部分处理逻辑。执行完Valve后会执行基础的 Valve–StandardEngineValve,负责调用Host容器的Pipeline。
  7. Host容器的管道开始处理,流程类似,最后执行 Context容器的Pipeline。
  8. Context容器的管道开始处理,流程类似,最后执行 Wrapper容器的Pipeline。
  9. Wrapper容器的管道开始处理,流程类似,最后执行 Wrapper容器对应的Servlet对象的 处理方法

Connector

1
2
3
4
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

​ Connector用于接收请求并将请求封装成Request和Response来具体处理。最底层使用的是 Socket。Request和Response封装后交给Container(Servlet的容器)处理请求,Container处理后返回给Connector,最后由Socket返回给客户端。

结构

Connector中具体是用 ProtocolHandler处理请求的,代表不同的连接类型。Http11Protocol使用普通Socket连接,Http11NioProtocol使用NioSocket连接。

ProtocolHandler中有三个重要的组件:

  • Endpoint:处理底层的Socket网络连接;
  • Processor:将Endpoint接收的Socket封装成Request;
  • Adapter:将封装后的Request交给Container处理;

Endpoint的抽象类 AbstractEndpoint定义了 Acceptor和 AsyncTimeout两个内部类 和 Handler接口。

  • Acceptor:监听请求;
  • AsyncTimeout:检查异步Request请求的超时;
  • Handler:处理接收的Socket,内部调用 Processor进行处理;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class Connector extends LifecycleMBeanBase  {
public Connector() { this(null); }
public Connector(String protocol) {
// 根据 server.xml 中 Connector 属性 protocol 的值找合适的 className
// 此处返回 org.apache.coyote.http11.Http11NioProtocol
// 赋值给 ProtocolHandler
setProtocol(protocol);
ProtocolHandler p = null;
try {
Class<?> clazz = Class.forName(protocolHandlerClassName);
// 反射生成 Http11NioProtocol 时,在构造函数中 生成了 NioEndpoint。
p = (ProtocolHandler) clazz.getConstructor().newInstance();
} finally {
this.protocolHandler = p;
}
// 设置编码集
if (Globals.STRICT_SERVLET_COMPLIANCE) {
uriCharset = StandardCharsets.ISO_8859_1;
} else {
uriCharset = StandardCharsets.UTF_8;
}
}
// 初始化操作
@Override
protected void initInternal() throws LifecycleException {
super.initInternal();
// 初始化是配置 CoyoteAdapter(Connector 作为参数)
adapter = new CoyoteAdapter(this);
// 协议处理器绑定 适配器
protocolHandler.setAdapter(adapter);
// 执行 协议处理器初始化操作
protocolHandler.init();
}
// 使用此 连接器处理 请求
@Override
protected void startInternal() {
// 验证端口
if (getPort() < 0) { }
// 设置生命周期状态值
setState(LifecycleState.STARTING);
// 调用 协议处理器 start 方法
protocolHandler.start();
}
}

Http11NioProtocol

主要包含 NioEndpoint组件和 Http11NioProcessor组件。启动时由NioEndpoint组件启动端口监听,连接到来被注册到NioChannel队列中,由Poller轮询器负责检测Channel的读写事件,并在创建任务后放入线程池中,线程池进行任务处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class Http11NioProtocol extends AbstractHttp11JsseProtocol<NioChannel> {
// 创建了 NioEndpoint 类
public Http11NioProtocol() {
// 最终调用 AbstractProtocol 类
super(new NioEndpoint());
}
}

// 父类 AbstractProtocol
public abstract class AbstractProtocol implements ProtocolHandler,MBeanRegistration {
@Override
public void init() throws Exception {
// endpointName---"http-nio-8080": http-nio + 8080 组成。
String endpointName = getName();
// 去掉 双引号
endpoint.setName(endpointName.substring(1, endpointName.length()-1));
// domain == catalina
endpoint.setDomain(domain);
// Endpoint的初始化操作
// serverSocketChannel 绑定端口
endpoint.init();
}
@Override
public void start() throws Exception {
// Endpoint 的 start 方法,重点
// 创建 Executor、最大连接、开启 Poller thread
endpoint.start();
// 异步超时 线程,
asyncTimeout = new AsyncTimeout();
Thread timeoutThread = new Thread(asyncTimeout, getNameInternal() + "-AsyncTimeout");
int priority = endpoint.getThreadPriority();
if (priority < Thread.MIN_PRIORITY || priority > Thread.MAX_PRIORITY) {
priority = Thread.NORM_PRIORITY;
}
timeoutThread.setPriority(priority);
timeoutThread.setDaemon(true);
timeoutThread.start();
}
}

// AsyncTimeout 实现 Runnable 接口
protected class AsyncTimeout implements Runnable {
private volatile boolean asyncTimeoutRunning = true;
// 后台线程检查异步请求并在没有活动时触发超时。
@Override
public void run() {
// 死循环,直到接收到 shutdown 命令
while (asyncTimeoutRunning) {
Thread.sleep(1000);
long now = System.currentTimeMillis();
for (Processor processor : waitingProcessors) {
processor.timeoutAsync(now);
}
// 循环,直到 Endpoint pause
while (endpoint.isPaused() && asyncTimeoutRunning) {
Thread.sleep(1000);
}
}
}
}

NioEndpoint

NioEndpoint是非阻塞IO的一个抽象,包含了:

  • LimitLatch:连接数控制器。
  • Acceptor:套接字连接并注册到Channel队列中。
  • Poller:轮询检查事件列表。
  • SocketProcessor:任务定义器。
  • Executor:负责处理套接字。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// AbstractEndpoint
public void init() throws Exception {
if (bindOnInit) {
bind();
bindState = BindState.BOUND_ON_INIT;
}
}
public final void start() throws Exception {
// 判断是否绑定过
if (bindState == BindState.UNBOUND) {
bind();
bindState = BindState.BOUND_ON_START;
}
startInternal();
}

// NioEndpoint
@Override
public void bind() throws Exception {
// 绑定 设置的端口
if (!getUseInheritedChannel()) {
serverSock = ServerSocketChannel.open();
socketProperties.setProperties(serverSock.socket());
InetSocketAddress addr = (getAddress()!=null?new InetSocketAddress(getAddress(),getPort()):new InetSocketAddress(getPort()));
serverSock.socket().bind(addr,getAcceptCount());
} else {
// Retrieve the channel provided by the OS
Channel ic = System.inheritedChannel();
if (ic instanceof ServerSocketChannel) {
serverSock = (ServerSocketChannel) ic;
}
}
// 设置 阻塞模式
serverSock.configureBlocking(true); //mimic APR behavior
// 初始化 连接器、轮询器 默认线程数
if (acceptorThreadCount == 0) {
acceptorThreadCount = 1;
}
if (pollerThreadCount <= 0) {
pollerThreadCount = 1;
}
setStopLatch(new CountDownLatch(pollerThreadCount));
// 是否初始化 ssl
initialiseSsl();
selectorPool.open();
}

// 开启 NIO endpoint, 创建 acceptor, poller 线程.
@Override
public void startInternal() throws Exception {
// 设置 running 状态
if (!running) {
running = true;
paused = false;
// 默认 DEFAULT_SIZE:128 500
processorCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getProcessorCache());
eventCache = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getEventCache());
nioChannels = new SynchronizedStack<>(SynchronizedStack.DEFAULT_SIZE,
socketProperties.getBufferPool());
if ( getExecutor() == null ) {
createExecutor();
}
// 初始化 连接数控制器,默认最大连接数 10000
initializeConnectionLatch();
// 开启 poller 线程, 默认 2
// 检测到 事件后,交给 processor 处理
pollers = new Poller[getPollerThreadCount()];
for (int i=0; i<pollers.length; i++) {
pollers[i] = new Poller();
Thread pollerThread = new Thread(pollers[i],
getName() + "-ClientPoller-"+i);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
}
// 开启 Acceptor 线程
startAcceptorThreads();
}
}
// AbstractEndpoint
protected final void startAcceptorThreads() {
int count = getAcceptorThreadCount();
acceptors = new Acceptor[count];
// 开启 Acceptor 线程
for (int i = 0; i < count; i++) {
// NioEndpoint 中实现
acceptors[i] = createAcceptor();
String threadName = getName() + "-Acceptor-" + i;
acceptors[i].setThreadName(threadName);
Thread t = new Thread(acceptors[i], threadName);
t.setPriority(getAcceptorThreadPriority());
t.setDaemon(getDaemon());
t.start();
}
}

连接数控制器——-LimitLatch

处理流程图:

NIO模式下,Tomcat默认把阀门大小设置为 10000,可在 server.xml Connector节点下配置 maxConnections 属性修改。在连接数到达最大值后,仍可以接收客户端连接,直到操作系统接收队列被塞满。默认100,可在 Connector节点下 配置 acceptCount 属性修改。

SocketChannel接收器——–Acceptor

​ Acceptor主要监听是否有客户端发来的连接并接收该连接,accept操作是阻塞的。此时返回 SocketChannel对象。Acceptor接收 SocketChannel 对象后要把它设置成非阻塞(后面对客户端连接才去非阻塞模式处理),接着设置套接字属性,封装成非阻塞通道对象。(NioChannel–HTTP、SecureNioChannel–HTTPS),最后将非阻塞通道对象注册到通道队列由 Poller 负责检测事件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// NioEndpoint
protected class Acceptor extends AbstractEndpoint.Acceptor {
@Override
public void run() {
int errorDelay = 0;
// 死循环,知道收到 shutdown 命令
while (running) {
// Loop if endpoint is paused
while (paused && running) {
state = AcceptorState.PAUSED;
Thread.sleep(50);
}
if (!running) {
break;
}
state = AcceptorState.RUNNING;
try {
// 超过最大 连接,等待状态
countUpOrAwaitConnection();
// 接收从server来的下一个socket连接
SocketChannel socket = serverSock.accept();
// 正确接收 socket,重置 errorDelay
errorDelay = 0;
// Configure the socket
if (running && !paused) {
// 把 socket 交给合适的 处理器处理
if (!setSocketOptions(socket)) {
closeSocket(socket);
}
} else {
closeSocket(socket);
}
}
}
state = AcceptorState.ENDED;
}
}
protected boolean setSocketOptions(SocketChannel socket) {
// 处理 socket
try {
// 设置 非阻塞模式
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());
// 判断是否开启 SSL 类型,生成不同类型的 Channel
if (isSSLEnabled()) {
channel = new SecureNioChannel(socket, bufhandler, selectorPool, this);
} else {
channel = new NioChannel(socket, bufhandler);
}
} else {
channel.setIOChannel(socket);
channel.reset();
}
// 获取 Poller,注册 成 Event 事件。
getPoller0().register(channel);
} catch (Throwable t) {
// 出错了,就返回,进行 关闭 socket 处理
return false;
}
return true;
}

轮询器—-Poller

​ 需要同时对很多连接进行管理,通过不断遍历事件列表,对对应连接的相应事件作出处理。Poller内部依赖 JDK的Selector对象进行轮询,Selector会选择出待处理的事件,每轮询一次就选出若干需要处理的NioChannel,在NIO模式下,每次读取的数据时不确定的,每次读取的数据可能有请求头和请求行,每次只能尝试去解析报文,如果解析不成功则等待下次轮询读取更多数据后再次尝试,如果解析成功则做一些逻辑处理后对客户端响应,这些处理工作在任务定义器中定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// 在 NioEndpoint startInternal方法中
pollers = new Poller[getPollerThreadCount()];
for (int i=0; i<pollers.length; i++) {
pollers[i] = new Poller();
Thread pollerThread = new Thread(pollers[i], getName() + "-ClientPoller-"+i);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
}

// NioEndpoint 类中定义
public class Poller implements Runnable {
private final SynchronizedQueue<PollerEvent> events =
new SynchronizedQueue<>();
private volatile boolean close = false;
private Selector selector;
@Override
public void run() {
// 死循环,直到调用 destory 法
while (true) {
boolean hasEvents = false;
try {
if (!close) {
// 在 Acceptor 收到请求封装成 Socket 注册到 event 中
// 在轮询时从Event中取,进行处理
hasEvents = events();
if (wakeupCounter.getAndSet(-1) > 0) {
//if we are here, means we have other stuff to do
//do a non blocking select
keyCount = selector.selectNow();
} else {
keyCount = selector.select(selectorTimeout);
}
wakeupCounter.set(0);
}
if (close) {
events();
timeout(0, false);
try {
selector.close();
} catch (IOException ioe) {
log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe);
}
break;
}
} catch (Throwable x) {
continue;
}
//either we timed out or we woke up, process events first
if ( keyCount == 0 ) hasEvents = (hasEvents | events());

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();
// 另一个线程调用了 cancelledKey 方法,attachment 可能为null
// 移除次事件,否则进行处理事件
if (attachment == null) {
iterator.remove();
} else {
iterator.remove();
processKey(sk, attachment);
}
}
// 处理超时情况
timeout(keyCount,hasEvents);
}
getStopLatch().countDown();
}

protected void processKey(SelectionKey sk, NioSocketWrapper attachment) {
try {
if ( close ) {
cancelledKey(sk);
} else if ( sk.isValid() && attachment != null ) {
if (sk.isReadable() || sk.isWritable() ) {
if ( attachment.getSendfileData() != null ) {
processSendfile(sk,attachment, false);
} else {
unreg(sk, attachment, sk.readyOps());
boolean closeSocket = false;
// Read goes before write
if (sk.isReadable()) {
// 在父类中定义
if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) {
closeSocket = true;
}
}
if (!closeSocket && sk.isWritable()) {
if (!processSocket(attachment, SocketEvent.OPEN_WRITE, true)) {
closeSocket = true;
}
}
if (closeSocket) {
cancelledKey(sk);
}
}
}
} else {
//invalid key
cancelledKey(sk);
}
} catch ( CancelledKeyException ckx ) {
cancelledKey(sk);
}
}
}
// AbstractEndpoint
public boolean processSocket(SocketWrapperBase<S> socketWrapper,
SocketEvent event, boolean dispatch) {
try {
if (socketWrapper == null) {
return false;
}
// 从 栈中取一个
SocketProcessorBase<S> sc = processorCache.pop();
if (sc == null) {
// 没有就新建一个
sc = createSocketProcessor(socketWrapper, event);
} else {
sc.reset(socketWrapper, event);
}
// 判断是否有 Executor,最终都是调用 Processor 的 run方法。
Executor executor = getExecutor();
// 见SocketProcessor
if (dispatch && executor != null) {
executor.execute(sc);
} else {
sc.run();
}
} catch (RejectedExecutionException ree) {
return false;
}
return true;
}

任务定义器—SocketProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
// 在上面的操作中,执行 run 方法时,
// SocketProcessorBase
@Override
public final void run() {
synchronized (socketWrapper) {
if (socketWrapper.isClosed()) {
return;
}
doRun();
}
}
// 在 NioEndpoint 类中实现
@Override
protected void doRun() {
NioChannel socket = socketWrapper.getSocket();
SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
int handshake = -1;
if (handshake == 0) {
SocketState state = SocketState.OPEN;
// 处理请求
if (event == null) {
// 调用 Handler 转交给 Processor 去处理 process 方法,
state = getHandler().process(socketWrapper, SocketEvent.OPEN_READ);
} else {
state = getHandler().process(socketWrapper, event);
}
if (state == SocketState.CLOSED) {
close(socket, key);
}
}
socketWrapper = null;
event = null;
//return to cache
if (running && !paused) {
processorCache.push(this);
}
}

// AbstractProtocol
protected static class ConnectionHandler<S> implements AbstractEndpoint.Handler<S> {
@Override
public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) {
if (wrapper == null) {
return SocketState.CLOSED;
}
S socket = wrapper.getSocket();
// 根据Socket获取具体协议的处理器
Processor processor = connections.get(socket);
// 如果process==null,尝试其它协议、新建等
// SSL 支持
processor.setSslSupport(
wrapper.getSslSupport(getProtocol().getClientCertProvider()));
// process 和 connection 关联
connections.put(socket, processor);
SocketState state = SocketState.CLOSED;
do {
// 处理
state = processor.process(wrapper, status);
} while ( state == SocketState.UPGRADING);
// Make sure socket/processor is removed from the list of current
connections.remove(socket);
release(processor);
return SocketState.CLOSED;
}
}

// AbstractProcessorLight(公共父类)
@Override
public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status)
throws IOException {
SocketState state = SocketState.CLOSED;
Iterator<DispatchType> dispatches = null;
do {
// 根据 SocketEvent 所处的 状态执行不同操作。
if (dispatches != null) {
DispatchType nextDispatch = dispatches.next();
state = dispatch(nextDispatch.getSocketStatus());
} else if (status == SocketEvent.DISCONNECT) {
// Do nothing here, just wait for it to get recycled
} else if (isAsync() || isUpgrade() || state == SocketState.ASYNC_END) {
state = dispatch(status);
if (state == SocketState.OPEN) {
state = service(socketWrapper);
}
} else if (status == SocketEvent.OPEN_WRITE) {
state = SocketState.LONG;
} else if (status == SocketEvent.OPEN_READ){
state = service(socketWrapper);
} else {
state = SocketState.CLOSED;
}
if (state != SocketState.CLOSED && isAsync()) {
state = asyncPostProcess();
}
if (dispatches == null || !dispatches.hasNext()) {
dispatches = getIteratorAndClearDispatches();
}
} while (state == SocketState.ASYNC_END ||
dispatches != null && state != SocketState.CLOSED);
return state;
}

// 调用具体协议的service方法处理请求
@Override
public SocketState service(SocketWrapperBase<?> socketWrapper) {
// 判断状态
while (!getErrorState().isError() && keepAlive && !isAsync()
&& upgradeToken == null &&
sendfileState == SendfileState.DONE && !endpoint.isPaused()) {

// 解析request请求头
try {
if (!inputBuffer.parseRequestLine(keptAlive)) {
if (inputBuffer.getParsingRequestLinePhase() == -1) {
return SocketState.UPGRADING;
} else if (handleIncompleteRequestLineRead()) {
break;
}
}
if (endpoint.isPaused()) {
response.setStatus(503);
setErrorState(ErrorState.CLOSE_CLEAN, null);
} else {
keptAlive = true;
request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount());
if (!inputBuffer.parseHeaders()) {
openSocket = true;
readComplete = false;
break;
}
if (!disableUploadTimeout) {
socketWrapper.setReadTimeout(connectionUploadTimeout);
}
}
} catch (IOException e) {
setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e); break;
} catch (Throwable t) {
// 400 - Bad Request
response.setStatus(400);
setErrorState(ErrorState.CLOSE_CLEAN, t);
// 日志调用处
getAdapter().log(request, response, 0);
}
// Has an upgrade been requested?
Enumeration<String> connectionValues = request.getMimeHeaders().values("Connection");
boolean foundUpgrade = false;
while (connectionValues.hasMoreElements() && !foundUpgrade) {
foundUpgrade = connectionValues.nextElement().toLowerCase(
Locale.ENGLISH).contains("upgrade");
}
if (foundUpgrade) {
// Check the protocol
String requestedProtocol = request.getHeader("Upgrade");
UpgradeProtocol upgradeProtocol = httpUpgradeProtocols.get(requestedProtocol);
if (upgradeProtocol != null) {
if (upgradeProtocol.accept(request)) {
response.setStatus(HttpServletResponse.SC_SWITCHING_PROTOCOLS);
response.setHeader("Connection", "Upgrade");
response.setHeader("Upgrade", requestedProtocol);
action(ActionCode.CLOSE, null);
getAdapter().log(request, response, 0);

InternalHttpUpgradeHandler upgradeHandler =
upgradeProtocol.getInternalUpgradeHandler(
getAdapter(), cloneRequest(request));
UpgradeToken upgradeToken = new UpgradeToken(upgradeHandler, null, null);
action(ActionCode.UPGRADE, upgradeToken);
return SocketState.UPGRADING;
}
}
}

if (!getErrorState().isError()) {
rp.setStage(org.apache.coyote.Constants.STAGE_PREPARE);
try {
prepareRequest();
} catch (Throwable t) {
// 500 - Internal Server Error
response.setStatus(500);
setErrorState(ErrorState.CLOSE_CLEAN, t);
getAdapter().log(request, response, 0);
}
}

if (maxKeepAliveRequests == 1) {
keepAlive = false;
} else if (maxKeepAliveRequests > 0 &&
socketWrapper.decrementKeepAlive() <= 0) {
keepAlive = false;
}

// 通过 CoyotAdapte 处理 request
if (!getErrorState().isError()) {
try {
rp.setStage(org.apache.coyote.Constants.STAGE_SERVICE);
// 处理 request,见 CoyoteAdapter 解析
getAdapter().service(request, response);
if(keepAlive && !getErrorState().isError() && !isAsync() &&
statusDropsConnection(response.getStatus())) {
setErrorState(ErrorState.CLOSE_CLEAN, null);
}
} catch (InterruptedIOException e) {
setErrorState(ErrorState.CLOSE_CONNECTION_NOW, e);
} catch (HeadersTooLargeException e) {
if (response.isCommitted()) {
setErrorState(ErrorState.CLOSE_NOW, e);
} else {
response.reset();
response.setStatus(500);
setErrorState(ErrorState.CLOSE_CLEAN, e);
response.setHeader("Connection", "close");
}
} catch (Throwable t) {
// 500 - Internal Server Error
response.setStatus(500);
setErrorState(ErrorState.CLOSE_CLEAN, t);
getAdapter().log(request, response, 0);
}
}

// Finish the handling of the request
rp.setStage(org.apache.coyote.Constants.STAGE_ENDINPUT);
if (!isAsync()) {
endRequest();
}
rp.setStage(org.apache.coyote.Constants.STAGE_ENDOUTPUT);

// If there was an error, make sure the request is counted as
// and error, and update the statistics counter
if (getErrorState().isError()) {
response.setStatus(500);
}

if (!isAsync() || getErrorState().isError()) {
request.updateCounters();
if (getErrorState().isIoAllowed()) {
inputBuffer.nextRequest();
outputBuffer.nextRequest();
}
}
if (!disableUploadTimeout) {
int soTimeout = endpoint.getConnectionTimeout();
if(soTimeout > 0) {
socketWrapper.setReadTimeout(soTimeout);
} else {
socketWrapper.setReadTimeout(0);
}
}
rp.setStage(org.apache.coyote.Constants.STAGE_KEEPALIVE);
sendfileState = processSendfile(socketWrapper);
}
rp.setStage(org.apache.coyote.Constants.STAGE_ENDED);
}

CoyoteAdapter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@Override
public void service(org.apache.coyote.Request req, org.apache.coyote.Response res) {
Request request = (Request) req.getNote(ADAPTER_NOTES);
Response response = (Response) res.getNote(ADAPTER_NOTES);
// request == null,新建并关联
if (request == null) {
// Create objects
request = connector.createRequest();
request.setCoyoteRequest(req);
response = connector.createResponse();
response.setCoyoteResponse(res);
// Link objects
request.setResponse(response);
response.setRequest(request);
// Set as notes
req.setNote(ADAPTER_NOTES, request);
res.setNote(ADAPTER_NOTES, response);
// Set query string encoding
req.getParameters().setQueryStringCharset(connector.getURICharset());
}
// 设置请求头,告知网站是用何种语言或框架编写的
// 默认false,Servlet/4.0 JSP/2.3xxxxxxxxxxxxxx
if (connector.getXpoweredBy()) {
response.addHeader("X-Powered-By", POWERED_BY);
}
boolean async = false;
boolean postParseSuccess = false;
req.getRequestProcessor().setWorkerThreadName(THREAD_NAME.get());
try {
// 请求映射、解析参数等操作。
postParseSuccess = postParseRequest(req, request, res, response);
if (postParseSuccess) {
//check valves if we support async
request.setAsyncSupported(
connector.getService()
.getContainer()
.getPipeline()
.isAsyncSupported());
// 由 Pipeline 处理流程,见Pipeline篇
connector.getService()
.getContainer()
.getPipeline()
.getFirst()
.invoke(request, response);
}
// 异步处理
if (request.isAsync()) {
// 省略
} else {
request.finishRequest();
response.finishResponse();
}
} finally {
// 处理访问日志,见日志篇
if (!async && postParseSuccess) {
Context context = request.getContext();
if (context != null) {
context.logAccess(request, response,
System.currentTimeMillis() - req.getStartTime(), false);
}
}
req.getRequestProcessor().setWorkerThreadName(null);
// 回收 request and response
if (!async) {
request.recycle();
response.recycle();
}
}
}

评论