How the Tomcat Web container works

Source: Internet
Author: User
Tags connection pooling set socket

Tomcat's modular structure is well designed, and its web container has a very good performance. JBoss uses Tomcat's web container directly, and earlier versions of WebLogic were also using Tomcat's code.
The working process of the Web container in the following document in the second reference document has been quite clear, and I will not repeat it. If you do not know the calling procedure, you need to look at this document first. Here to analyze the process of connector.
1. A simple Web server example
This example is also found on the Internet, do not know the original author, it is not referenced in the reference.
This is the main program that initiates the service.
public class Httpserver {
public static void Main (String args[]) {
int port;
ServerSocket Server_socket; Read Server port number
try {
Port = Integer.parseint (Args[0]);
} catch (Exception e) {
Port = 8080;
}
try {
Listening for server ports, waiting for connection requests
Server_socket = new ServerSocket (port);
System.out.println ("Httpserver running on port"
+ Server_socket.getlocalport ());
Show startup information
while (true) {
Socket socket = server_socket.accept ();
SYSTEM.OUT.PRINTLN ("New Connection accepted"
+ socket.getinetaddress () + ":" + socket.getport ());
Creating a split Thread
try {
Httprequesthandler request = new Httprequesthandler (socket);
Thread thread = new thread (request);
Start thread
Thread.Start ();
} catch (Exception e) {
System.out.println (e);
}
}
} catch (IOException e) {
System.out.println (e);
}
}
}

Here is the thread that created the output
public class Httprequesthandler implements Runnable {
Final static String CRLF = "\ r \ n";
Socket socket;
InputStream input;
OutputStream output;
BufferedReader BR;
Construction method
Public Httprequesthandler (socket socket) throws Exception {
This.socket = socket;
This.input = Socket.getinputstream ();
This.output = Socket.getoutputstream ();
this.br = new BufferedReader (New InputStreamReader (socket
. getInputStream ()));
}

Implement the Run () method of the Runnable interface
public void Run () {
try {
ProcessRequest ();
} catch (Exception e) {
System.out.println (e);
}
}

private void ProcessRequest () throws Exception {
while (true) {
Read and display request information submitted by Web browser
String headerline = Br.readline ();
SYSTEM.OUT.PRINTLN ("The client request is" + headerline);
if (headerline.equals (CRLF) | | headerline.equals (""))
Break
StringTokenizer s = new StringTokenizer (headerline);
String temp = S.nexttoken ();
if (Temp.equals ("GET")) {
String fileName = S.nexttoken ();
filename = "." + filename;
Open the requested file
FileInputStream FIS = null;
Boolean fileexists = true;
try {
FIS = new FileInputStream ("d:/workspace/tomcat/bin/" +filename);
} catch (FileNotFoundException e) {
FileExists = false;
}
Complete Response message
String serverline = "Server:a simple java Httpserver";
String statusline = null;
String contenttypeline = null;
String entitybody = null;
String contentlengthline = "error";
if (fileexists) {
Statusline = "http/1.0 OK" + CRLF;
Contenttypeline = "Content-type:" + contentType (fileName) + CRLF;
Contentlengthline = "Content-length:"
+ (New Integer (Fis.available ())). ToString () + CRLF;
} else {
Statusline = "http/1.0 404 Not Found" + CRLF;
Contenttypeline = "text/html";
Entitybody = "< Html> "
+ "< head>< title>404 not found</title></head> "+" < body>404 not Found "+" <br>usage:http://yourhostname:port/"+" filename.html</body& Gt;</html> ";
}
Send to server information
Output.write (Statusline.getbytes ());
Output.write (Serverline.getbytes ());
Output.write (Contenttypeline.getbytes ());
Output.write (Contentlengthline.getbytes ());
Output.write (Crlf.getbytes ());
Send Message Content
if (fileexists) {
Sendbytes (FIS, Output);
Fis.close ();
} else {
Output.write (Entitybody.getbytes ());
}
}
}
Closing sockets and Streams
try {
Output.close ();
Br.close ();
Socket.close ();
} catch (Exception e) {
}
}

private static void Sendbytes (FileInputStream fis, outputstream os)
    throws Exception {
  //Create a 1K buffer
   byte[] buffer = new byte[1024];
   int bytes = 0;
  //Output the file to the socket output stream
   while ((bytes = fis.read (buffer))! =-1) {
    Os.write (buffer, 0, bytes);
  }
}

private static string ContentType (String fileName) {
if (Filename.endswith (". htm") | | filename.endswith (". html")) {
return "text/html";
}
return "FileName";
}
}
This simple example illustrates the basic implementation of Web services. Tomcat is on top of this modular thread pool, network connection and WEBHTTP protocol 3 packages. The thread pool can be used independently, the network connection is pooled, and the webhttp is obtained directly from the network connection pool.
2. Implementation of thread pool
The implementation of this feature is in package Org.apache.tomcat.util.thread.
ThreadPool is the thread pool that is the core of this feature implementation. It uses all the other classes to do the work. In a class diagram, all other classes are used by such a relationship.
Let's see how this class works.
How to start the connection pool:
Public synchronized void Start () {
Stopthepool = false;
Currentthreadcount = 0;
currentthreadsbusy = 0;

Adjustlimits ();
Pool = new Controlrunnable[maxthreads];
Openthreads (minsparethreads);
if (Maxsparethreads < MaxThreads) {
Monitor = new Monitorrunnable (this);
}
}
method, initializes all threads into the standby state, depending on the configuration.
An array of maxthreads numbers is defined first, but only minsparethreads are initialized. Monitorrunnable is used to check if there are more than maxsparethreads of idle numbers.
Currentthreadcount is the number of threads that the current initialization can use, and currentthreadsbusy is the number of threads currently in use.
Ways to use connection pooling:
public void Runit (Threadpoolrunnable r) {
if (null = = r) {
throw new NullPointerException ();
}
Controlrunnable C = findcontrolrunnable ();
C.runit (R);
}
In this method, we first look for the available threads and find them and run them.
The method of finding an available thread is also simple, which is to take the currentthreadcount-currentthreadsbusy-1 element of the thread array back and set the element to null.
After the thread has finished running, set currentthreadsbusy--, and then put the currentthreadcount-currentthreadsbusy-1 thread back on it.
Wait until the thread is insufficient, and wait for the failure to throw an exception.
Describe the features of classes not mentioned above:
Threadpoolrunnable This is an interface that specifies some of the actions that a thread needs to run when it runs. There is a need to write some code for business logic.
Threadwithattributes This class is not seen from the above code, which identifies some of the characteristics of the currently running thread, such as recording some state of the currently running thread.
Threadpoollistener is used to monitor new threads in ThreadPool.
Controlrunnable This class is the inner class of ThreadPool, which is used to run threadpoolrunnable. Notifies ThreadPool to recycle threads when Threadpoolrunnable is finished running. It is always in a standby state. Once this object is instantiated, it has been in a dead loop to check if there is something that it needs to run.
3. Realization of network connection function
The implementation of this feature is in package org.apache.tomcat.util.net.
The network connection function is built on the thread pool, and a connection service model is implemented. The server opens the port, pooling enters the connection and creates a worker thread for the incoming connection.
The two main applications of Tomcat's network connection are 1. Web apps that you provide yourself. 2. Web apps for Apache. The parsing process for both processes is the same. It's just that the network connection protocol is different. Two apps are implemented with the functionality of this package.

Pooltcpendpoint is the core, it uses the ThreadPool. Tcpworkerthread the work required to complete a connection by invoking the interface Tcpconnectionhandler. The tcpconnection identifies a connection object.
The initialization method code for Pooltcpendpoint is simple, creating or referencing ThreadPool in the builder, creating serversocket at initialization to listen for client connections.
Here is the initialization method
public void Initendpoint () throws IOException, Instantiationexception {
try {
if (factory = = null)
Factory = Serversocketfactory.getdefault ();
if (ServerSocket = = null) {
try {
if (inet = = null) {
ServerSocket = Factory.createsocket (port, backlog);
} else {
ServerSocket = Factory
. Createsocket (port, backlog, inet);
}
} catch (Bindexception be) {
throw new Bindexception (Be.getmessage () + ":" + port);
}
}
if (servertimeout >= 0)
Serversocket.setsotimeout (serverTimeOut);
} catch (IOException ex) {
Log ("couldn ' t start endpoint", ex, Logger.debug);
Throw ex;
} catch (Instantiationexception Ex1) {
Log ("couldn ' t start endpoint", Ex1, Logger.debug);
Throw Ex1;
}
initialized = true;
}

The startup method is also simple, just use Tcpworkerthread as the thread pool's worker thread, start the connection pool, and you're done.
public void Startendpoint () throws IOException, Instantiationexception {
if (!initialized) {
Initendpoint ();
}
if (Ispool) {
Tp.start ();
}
running = true;
paused = false;
if (Ispool) {
Listener = new Tcpworkerthread (this);
Tp.runit (listener);
} else {
Log.error ("XXX error-need pool!");
}
}

The listening details are wrapped in the Tcpworkerthread class. At run time, it listens on the ServerSocket port. When a connection is found, a new thread is opened immediately to continue listening, and the thread begins processing the connection. Here's the code:
public void Runit (Object perthrdata[]) {
Create Per-thread Cache
if (endpoint.isrunning ()) {
Loop If endpoint is paused
while (endpoint.ispaused ()) {
try {
Thread.Sleep (1000);
} catch (Interruptedexception e) {
Ignore
}
}
Accept a new connection
Socket s = null;
try {
s = Endpoint.acceptsocket ();
} finally {
Continue accepting on another thread ...
if (endpoint.isrunning ()) {
Endpoint.tp.runIt (this);
}
}
Process the connection
if (null! = s) {
Tcpconnection con = null;
int step = 1;
try {
1:set socket options:timeout, linger, etc
Endpoint.setsocketoptions (s);
2:ssl handshake
Step = 2;
if (endpoint.getserversocketfactory () = null) {
Endpoint.getserversocketfactory (). handshake (s);
}
3:process the connection
Step = 3;
Con = (tcpconnection) perthrdata[0];
Con.setendpoint (endpoint);
Con.setsocket (s);
Endpoint.getconnectionhandler (). Processconnection (Con,
(object[]) perthrdata[1]);
} catch (SocketException se) {
......
4. Implementation of the Protocol Web HTTP
The implementation of this feature is in package org.apache.coyote.http11.
The core class for implementing the HTTP protocol is http11protocol. The implementation of the specific function class has mxpoollistener (Implementation threadpoollistener), Http11connectionhander (Implementation Tcpconnectionhandler).
Http11protocol's initialization method is simple, is to set up a network connection to start running.
Http11connectionhander initializes the class Http11processor, which parses the requested string and gives it the container of the connector that generated the connection, which is the engine completion. The engine uses recursion to parse the data that should be returned to the user. This process is described in the reference documentation.

How the Tomcat Web container works

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.