几个重要的角色:
Acceptor、Poller
Http11Processor、CoyoteAdapter
class org.apache.catalina.connector.Connector{
protected void startInternal() throws LifecycleException {
// org.apache.coyote.http11.Http11NioProtocol
protocolHandler.start(); //!!!
}
}
class org.apache.coyote.http11.Http11NioProtocol{
public void start() throws Exception {
// org.apache.tomcat.util.net.NioEndpoint
endpoint.start();
}
}
class org.apache.tomcat.util.net.NioEndpoint{
public void startInternal() throws Exception {
pollers = new Poller[getPollerThreadCount()]; // 启动pollers线程
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();
}
startAcceptorThreads(); // 启动接受线程
}
protected final void startAcceptorThreads() {
int count = getAcceptorThreadCount(); // 接受网络请求的线程数量
acceptors = new Acceptor[count];
for (int i = 0; i < count; i++) {
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();
}
}
protected AbstractEndpoint.Acceptor createAcceptor() {
return new Acceptor();
}
}
class org.apache.tomcat.util.net.NioEndpoint.Acceptor {
public void run() {
// Loop until we receive a shutdown command
while (running) {
try {
socket = serverSock.accept(); // 接受socket
if (running && !paused) {
if (!setSocketOptions(socket)) {//!!! 委托给 org.apache.tomcat.util.net.NioEndpoint.Poller 进行工作
countDownConnection();
closeSocket(socket);
}
} else {
countDownConnection();
closeSocket(socket);
}
}
}
protected boolean org.apache.tomcat.util.net.NioEndpoint.setSocketOptions(SocketChannel socket){
//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); // org.apache.tomcat.util.net.NioEndpoint.Poller.register(channel); 添加事件
}
public Poller org.apache.tomcat.util.net.NioEndpoint.getPoller0() {
int idx = Math.abs(pollerRotater.incrementAndGet()) % pollers.length;
return pollers[idx];
}
}
class org.apache.tomcat.util.net.NioEndpoint.Poller {
// 注册任务
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(getSoTimeout());
ka.setWriteTimeout(getSoTimeout());
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); // 添加事件!!!! events.offer(r);
}
// 执行任务
public void run() {
while (true) {
keyCount = selector.selectNow();
// 迭代Select键列表
Iterator<SelectionKey> iterator =
keyCount > 0 ? selector.selectedKeys().iterator() : null;
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
NioSocketWrapper attachment = (NioSocketWrapper)sk.attachment();
processKey(sk, attachment); // !!!!处理用户的socket请求
}
}
}
protected void processKey(SelectionKey sk, NioSocketWrapper attachment) {
// Read goes before write
if (sk.isReadable()) {
if (!processSocket(attachment, SocketEvent.OPEN_READ, true)) { // !!!处理用户的socket请求
closeSocket = true;
}
}
if (!closeSocket && sk.isWritable()) {
if (!processSocket(attachment, SocketEvent.OPEN_WRITE, true)) {
closeSocket = true;
}
}
}
// 处理任务
public boolean processSocket(SocketWrapperBase<S> socketWrapper,
SocketEvent event, boolean dispatch) {
sc = createSocketProcessor(socketWrapper, event); // 创建Socket处理器
sc.run();//!!!
}
// 创建任务处理器
protected SocketProcessorBase<NioChannel> org.apache.tomcat.util.net.NioEndpoint.createSocketProcessor(
SocketWrapperBase<NioChannel> socketWrapper, SocketEvent event) {
return new SocketProcessor(socketWrapper, event);
}
}
// 创建任务处理器
class org.apache.tomcat.util.net.NioEndpoint.SocketProcessor{
public final void run() {
doRun();//!!!!
}
protected void doRun() { // 任务处理器
NioChannel socket = socketWrapper.getSocket();
SelectionKey key = socket.getIOChannel().keyFor(socket.getPoller().getSelector());
// getHandler() === org.apache.coyote.AbstractProtocol.ConnectionHandler
state = getHandler().process(socketWrapper, event);//!!!!-----------------
}
}
// 连接处理器
class org.apache.coyote.AbstractProtocol.ConnectionHandler{
public SocketState process(SocketWrapperBase<S> wrapper, SocketEvent status) {
// org.apache.coyote.http11.Http11NioProtocol.createProcessor();
// processor = org.apache.coyote.http11.Http11Processor
processor = getProtocol().createProcessor();//------------------------------------------
register(processor); // 把processor注册到MServer服务器
do {
//---------------------------!!!!!!!!!!!!!!!-------------------
// !!! org.apache.coyote.http11.Http11Processor.process(wrapper, status)
state = processor.process(wrapper, status);
} while ( state == SocketState.UPGRADING);
}
}
class org.apache.coyote.http11.Http11Processor{
// 父类构造函数
private AbstractProcessor(AbstractEndpoint<?> endpoint, Request coyoteRequest,
Response coyoteResponse) {
this.endpoint = endpoint;
asyncStateMachine = new AsyncStateMachine(this);
request = coyoteRequest;
response = coyoteResponse;
response.setHook(this);
request.setResponse(response);
request.setHook(this);
}
// 父类构造函数
public super(AbstractEndpoint<?> endpoint) {
// AbstractProcessor(endpoint, new Request(), new Response());
AbstractProcessor(endpoint, new org.apache.coyote.Request(), new org.apache.coyote.Response());
}
// 构造函数
public Http11Processor(int maxHttpHeaderSize, AbstractEndpoint<?> endpoint,int maxTrailerSize,
Set<String> allowedTrailerHeaders, int maxExtensionSize, int maxSwallowSize,
Map<String,UpgradeProtocol> httpUpgradeProtocols) {
super(endpoint);//!!!创建 request 和 response
userDataHelper = new UserDataHelper(log);
inputBuffer = new Http11InputBuffer(request, maxHttpHeaderSize);
request.setInputBuffer(inputBuffer);
outputBuffer = new Http11OutputBuffer(response, maxHttpHeaderSize);
response.setOutputBuffer(outputBuffer);
}
// 处理
public SocketState process(SocketWrapperBase<?> socketWrapper, SocketEvent status)
throws IOException {
state = service(socketWrapper); //!!!!处理服务------------------------
}
public SocketState service(SocketWrapperBase<?> socketWrapper)
throws IOException {
// 解析请求行,解析出协议类型 protocol/queryString/requestURI/method,如protocol是HTTP/2.0 --------------------------
if (!inputBuffer.parseRequestLine(keptAlive)) {
}
request.getMimeHeaders().setLimit(endpoint.getMaxHeaderCount()); // 最多的mime头数量 ----
Enumeration<String> connectionValues = request.getMimeHeaders().values("Connection"); // 取得Connection的值 -----
prepareRequest(); // !!!预处理请求头,解析出主机和端口等 --------------------------
// !!! org.apache.catalina.connector.CoyoteAdapter
getAdapter().service(request, response);//!!!!!!!!!!! ----------------------
}
private void prepareRequest() {
long contentLength = request.getContentLengthLong(); // 内容长度
MessageBytes valueMB = headers.getValue("host"); // 主机名称
parseHost(valueMB); // 解析主机名和端口
}
}
class org.apache.catalina.connector.CoyoteAdapter{
// 服务方法
public void service(org.apache.coyote.Request req,
org.apache.coyote.Response res)
throws Exception {
// org.apache.catalina.connector.Request
Request request = (Request) req.getNote(ADAPTER_NOTES);
Response response = (Response) res.getNote(ADAPTER_NOTES);
if (request == null) {
// org.apache.catalina.connector.Connector.createRequest();
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().setQueryStringEncoding
(connector.getURIEncoding()); // 设置查询字符串的编码
}
if (connector.getXpoweredBy()) {
response.addHeader("X-Powered-By", POWERED_BY);
}
postParseSuccess = postParseRequest(req, request, res, response);//!!!! 解析scheme、查找路由、sessionID
// request.getMappingData() 内部存储路由映射对象和Servlet对象
if (postParseSuccess) {
// Calling the container
// org.apache.catalina.core.StandardService --- getService()
// org.apache.catalina.core.StandardEngine --- getContainer()
// org.apache.catalina.core.StandardPipeline --- getPipeline()
// org.apache.catalina.core.StandardEngineValve --- getFirst()
connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);//!!!!!! 管道机制
}
}
// 解析请求
protected boolean postParseRequest(org.apache.coyote.Request req, Request request,
org.apache.coyote.Response res, Response response) throws IOException, ServletException {
boolean mapRequired = true;
while (mapRequired) { // 映射路由
// This will map the the latest version by default
// org.apache.catalina.mapper.Mapper
connector.getService().getMapper().map(serverName, decodedURI,
version, request.getMappingData()); // 映射出路由 -------------------并创建出相应对象!!!!
parseSessionCookiesId(request); // 解析出sessionID
parseSessionSslId(request);// 解析出sessionID
sessionID = request.getRequestedSessionId(); // 取得sessionID
break;
}
return true;
}
}