Deep understanding of one of the Tomcat series: System architecture

Source: Internet
Author: User

Objective

Tomcat is an open source project under the Apache Fund, and is a Web server in nature. This is a common scenario: a Web project in Eclipse Bedstead and deployed to Tomcat, launch Tomcat, enter a similar URL in the browser http://localhost:8080/webproject/anyname.jsp , and then you can see the contents of the JSP page we wrote. Everything is natural and logical, but it all comes from Tomcat, so how does this happen behind Tomcat? With the curiosity of the working principle of Tomcat, I decided to study the source of Tomcat, but the process of deploying the source environment let me be discouraged, in the spirit of I do not believe the enthusiasm, tossing a night + a morning, finally the source code environment to build up.

To make the article seem more organized, I'll explain the Tomcat workflow in the following ways:

    • Build Tomcat Source Environment guide
    • Tomcat's system architecture
    • Description of the core components in Tomcat
    • How Servlets work
    • An example
Tomcat's system architecture

First, let's look at the architecture of Tomcat from a macro perspective:

As you can see from this diagram, the core components of Tomcat are two connector and container (detailed later), a connector+ a container constitutes a service,service is a component that provides services externally, With service components Tomcat will be able to provide services, but the service is not available, but also have the environment to provide services to you, so the outermost server provides service for the survival of the soil. So what exactly are these components for? Connector is a connector that is primarily responsible for receiving requests and handing them over to Container,container is a container that is mainly loaded with the components that specifically handle the request. Service is primarily to correlate container with connector, a single container or a single connector cannot process a request completely, only two are combined to complete the processing of a request. Server This is responsible for managing the service collection, we see a tomcat can provide a variety of services, then these serice are managed by the server, the specific work includes: Provide an interface access service externally, internal maintenance service collection, Maintaining a service collection also includes managing the service lifecycle, looking for a requested service, ending a service, and so on. This is a brief description of the core components of Tomcat, so let's take a closer look at each component's execution process:

Server

It says that the server is the Management Service interface, the server is the top-level container of Tomcat, is an interface, the standard implementation class of the server interface is the Standardserver class, there are many methods in the server interface, We focus on two methods: AddService () and Findservice (String). Let's look at the full picture of the server interface first:

Then look at the implementation code for AddService () and Findservice (String):

Code Listing 1-1:

/** * Add a new Service to the set of defined Services. * * @param service The Service to be added */@Overridepublic void addService(Service service) {    service.setServer(this);    synchronized (services) {        Service results[] = new Service[services.length + 1];        System.arraycopy(services, 0, results, 0, services.length);        results[services.length] = service;        services = results;        if (getState().isAvailable()) {            try {                service.start();            } catch (LifecycleException e) {                // Ignore            }        }        // Report this property change to interested listeners        support.firePropertyChange("service", null, service);    }}

As you can see, the server uses an array to manage the service, copying the original service into a new array for each service addition, and putting the new service into the service array. So the server is associated with the service, so what's behind it getState().isAvailable() ? Determines whether the service method is executed by determining whether the state is invalid. When it comes to the state, we have to say that Tomcat manages the lifecycle interface for each component's lifecycle:

Lifecycle interface

The components in Tomcat are given to this interface management, but the lifecycle of the specific component is managed by the parent container of the containing component, the top-level container in Tomcat manages the service lifecycle, and the service container is the parent container of connector and container. So the life cycle of these two components is managed by service, container also has sub-containers, so the lifecycle of these sub-containers is managed. This allows the lifecycle of all containers to be controlled as long as all components implement the lifecycle interface, starting with the top-level container server. The lifecycle interface defines a number of States, in which the state transitions after invoking different methods are described in detail, and different methods are defined, and these methods are changed in the post-execution state, and the following methods are defined in the Lifecycle interface:

The Startinernal () method is implemented in Standserver, which is the process of looping through the service of Standserver management, and the service of Tomcat implements the lifecycle interface. So the managed service will be notified to execute the start () method, and the Startintenal () method is this:

Code Listing 1-2:

/** * Start nested components ({@link Service}s) and implement the requirements * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}. * * @exception LifecycleException if this component detects a fatal error *  that prevents this component from being used */@Overrideprotected void startInternal() throws LifecycleException {    fireLifecycleEvent(CONFIGURE_START_EVENT, null);    setState(LifecycleState.STARTING);    globalNamingResources.start();    // Start our defined Services    synchronized (services) {        for (int i = 0; i < services.length; i++) {            services[i].start();        }    }}

All the service is now notified and then the Start method is executed. If a service is not allowed to be used, a Lifecycleexception exception will be thrown.

Stopintenal () Notifies all service execution stop methods, which are similar to the Startintenal () method. The execution process involves a very important design pattern, the Observer pattern .

Now that we know that the container manages the container's life cycle through the lifecycle interface, how does the state change in the parent container be notified to the child container? Back in code listing 1-2, we noticed that there is a fireLifecycleEvent() way to execute the firelifecycleevent () as follows:

    1. Call Lifecyclebase's firelifecycleevent (Lifecyclelistener Listener) method, Lifecyclebase is an abstract class that implements the lifecycle interface
    2. Continue calling Lifecyclesupport (a firelifecycleevent (String type, Object data) method that assists in completing an event notification class that has registered listeners, cannot be inherited, uses final)
    3. Complete Event Notification

The Firelifecycleevent (String type, Object data) method is as follows:

Code Listing 1-3:

/** * Notify all lifecycle event listeners that a particular event has * occurred for this Container.  The default implementation performs * this notification synchronously using the calling thread. * * @param type Event type * @param data Event data */public void fireLifecycleEvent(String type, Object data) {    LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);    LifecycleListener interested[] = listeners;    for (int i = 0; i < interested.length; i++)        interested[i].lifecycleEvent(event);}

Therefore, the notification of the specific event is done by the Lifecycleevent method of the Lifecyclelistener interface, and each implementation class can implement different event monitoring logic according to different situations.

Service

Service is the interface that provides services specifically, one service wraps connector and one container, how does this work in Tomcat? The service is an interface whose standard implementation class is Standardservice, and below is an aerial view of these two classes:


Here, we only care about the most closely with connector and container method: Setcontainer () and AddConnector () method, first look at the source of the Setcontainer () method:

Code Listing 2-1:

/** * Set The <code>Container</code> that handles requests for all * <code>Connectors</code> Assoc Iated with the This Service. * * @param container The new container */@Overridepublic void Setcontainer (Container container) {container oldcontaine    R = This.container;    if (Oldcontainer! = null) && (Oldcontainer instanceof Engine)) ((engine) oldcontainer). Setservice (NULL);    This.container = container; if (This.container! = null) && (This.container instanceof Engine)) ((engine) this.container). Setservice (th    IS);        if (GetState (). IsAvailable () && (This.container! = null)) {try {this.container.start ()); } catch (Lifecycleexception e) {//Ignore}} if (GetState (). IsAvailable () && (Oldconta        Iner = null)) {try {oldcontainer.stop (); } catch (Lifecycleexception e) {//Ignore}}}//Report the property change to IntereSted Listeners Support.firepropertychange ("container", Oldcontainer, This.container);} 

As you can see from the code, the main task is to set up a container container to handle requests sent by one or more connector. First, determine if the current service is already associated with the container container, and if it is already associated, remove the association. If the original container container has been started, terminates its life cycle, ends the run, and sets a new association relationship, the new container container begins a new life cycle. Finally, this process is notified to the event listener of interest.

Here's a look at the AddConnector method:

Code Listing 2-2:

 /** * Add A new Connector to the set of defined connectors, and associate it * with this Service ' s Container. * * @param connector the connector to be added */@Overridepublic void AddConnector (Connector connector) {synchronized (        Connectors) {Connector.setservice (this);        Connector results[] = new Connector[connectors.length + 1];        System.arraycopy (connectors, 0, results, 0, connectors.length);        Results[connectors.length] = connector;        connectors = results;            if (GetState (). IsAvailable ()) {try {connector.start (); } catch (Lifecycleexception e) {log.error (sm.getstring ("Standardservice.connector.            Startfailed ", connector), e); }}//Interested listeners Support.firepropertychange ("Connector", Nu    ll, connector); }}

The execution process is also clear: Wrap the connectors array with a synchronous block of code, set the connector relationship with container and service first, then let connector start the new life cycle, and finally notify the event listener of interest. Note that the connector Management and server Management service use an array copy and assign the new array to the current array, thereby indirectly implementing the dynamic array. The use of arrays I think might be due to performance considerations.

Deep understanding of one of the Tomcat series: System architecture

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.