tomcat NIOEndpoint realization of Acceptor

EndPoint components belong connector Connector inside. It is a communication endpoint, is responsible for external implement TCP / IP protocol. EndPoint is the interface, its implementation class is AbstractEndpoint, and AbstractEndpoint specific category there AprEndpoint, Nio2Endpoint, NioEndpoint.

AprEndpoint: corresponds to the APR mode, simple understanding is to solve the problem of asynchronous IO from the operating system level, and greatly improve the processing performance of the server response. However, to enable this mode you need to install some other dependencies.
Nio2Endpoint: use code to implement asynchronous IO
NioEndpoint: use the NIO JAVA to achieve a non-blocking IO, Tomcat is the default startup to start, and this is the focus of our talk.

These five components defined in the code of NioEndpoint.class. The five specific components are doing it?

LimitLatch: connection controller, responsible for controlling the maximum number of connections
Acceptor: responsible for receiving a new connection, and then returns to a Channel object Poller
Poller: it can be regarded as in NIO Selector, responsible for monitoring the status of Channel
SocketProcessor: it can be seen as a task encapsulated class
Executor: Tomcat own extended thread pool, to perform tasks like

Relationships between components:

 

-----------------------------------------------------------

Acceptor start NioEndpoint of multithreading, a default initialization Acceptor:

package org.apache.tomcat.util.net;
public abstract class AbstractEndpoint<S>
/ ** 
* Acceptor is connected to receive, we can see Acceptor implement the Runnable interface,
* which will then open a new thread to execute the run method Acceptor it?
* In startAcceptorThreads method AbstractEndpoint in.
* /
Protected Final void startAcceptorThreads () {
int COUNT = getAcceptorThreadCount ();
acceptors element = new new Acceptor [COUNT];

for (int I = 0; I <COUNT; I ++) {
acceptors element [I] = createAcceptor ();
String threadName = getName () + "-Acceptor-" + I;
acceptors element [I] .setThreadName (threadName);
the Thread new new T = the Thread (acceptors element [I], threadName);
t.setPriority (getAcceptorThreadPriority ());
t.setDaemon (getDaemon ());
t.start ();
}
}

 

@Override 
protected AbstractEndpoint.Acceptor createAcceptor () {
return new new Acceptor ();
}

implement the specific content class:
1, run method, starting socket services;
2, close the socket service.
/**
* The background thread that listens for incoming TCP/IP connections and
* hands them off to an appropriate processor.
* 重要方法
*/
protected class Acceptor extends AbstractEndpoint.Acceptor {

@Override
public void run() {

int errorDelay = 0;

// Loop until we receive a shutdown command
while (running) {

// Loop if endpoint is paused
while (paused && running) {
state = AcceptorState.PAUSED;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// Ignore
}
}

if (!running) {
break;
}
state = AcceptorState.RUNNING;

try {
//if we have reached max connections, wait
countUpOrAwaitConnection();

SocketChannel socket = null;
try {
// Accept the next incoming connection from the server
// socket
socket = serverSock.accept();
} catch (IOException ioe) {
// We didn't get a socket
countDownConnection();
if (running) {
// Introduce delay if necessary
errorDelay = handleExceptionWithDelay(errorDelay);
// re-throw
throw ioe;
} else {
break;
}
}
// Successful accept, reset the error delay
errorDelay = 0;

// Configure the socket
if (running && !paused) {
// setSocketOptions() will hand the socket off to
// an appropriate processor if successful
if (!setSocketOptions(socket)) {
closeSocket(socket);
}
} else {
closeSocket(socket);
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString("endpoint.accept.fail"), t);
}
}
state = AcceptorState.ENDED;
}


private void closeSocket(SocketChannel socket) {
countDownConnection();
try {
socket.socket().close();
} catch (IOException ioe) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("endpoint.err.close"), ioe);
}
}
try {
socket.close();
} catch (IOException ioe) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("endpoint.err.close"), ioe);
}
}
}
}

Guess you like

Origin www.cnblogs.com/guanghuiqq/p/11209373.html