Tomcat --執行流程

#1.Tomcat組成
tomcat的server.xml配置html

<?xml version='1.0' encoding='utf-8'?>

 <!-- tomcat(啓動後)監聽端口8005,若是收到SHUTDOWN命令,則關閉服務器-->
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />

  <!-- Global JNDI resources
       Documentation at /docs/jndi-resources-howto.html
  -->
  <GlobalNamingResources>
    <!-- Editable user database that can also be used by
         UserDatabaseRealm to authenticate users
    -->
    <Resource name="UserDatabase" auth="Container"
              type="org.apache.catalina.UserDatabase"
              description="User database that can be updated and saved"
              factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
              pathname="conf/tomcat-users.xml" />
  </GlobalNamingResources>

  <!-- 給Service命名,service是一組Connector,它們共用一個Engine來處理全部的controller請求 -->
  <Service name="Catalina">

    <!--端口號8080用於監聽來自客戶端的http請求
    minProcessors:該Connector先建立minProcessors個線程等待客戶請求,每一個請求由一條線程負責。
    maxProcessors:設置server處理的最大線程數,當現有的線程數(maxProcessors) 小於 客戶端的請求時,則自動建立新的線程來處理,可是最多隻能爲maxProcessors。
    acceptCount:設置客戶請求排隊數,當現有的線程數已經達到maxProcessors時,爲客戶請求排隊,當排隊數超過acceptCount時,再後來的請求返回Connection refused錯誤。
    redirectport:將請求轉到8443端口去處理
    connectionTimeout:設置鏈接超時時間
     -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />

    <!-- Engine用來處理接收到的請求,將請求轉發給對應的host來處理,
    默認的虛擬主機是localhost
    -->
    <Engine name="Catalina" defaultHost="localhost">

      <!-- Use the LockOutRealm to prevent attempts to guess user passwords
           via a brute-force attack -->
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <!-- This Realm uses the UserDatabase configured in the global JNDI
             resources under the key "UserDatabase".  Any edits
             that are performed against this UserDatabase are immediately
             available for use by the Realm.  -->
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <!-- 設置虛擬主機相關屬性,主機名localhost
        appBase:虛擬主機的根目錄,這裏設爲webapps/,它匹配請求與Context,
        將請求轉發給對應的Context處理。因此,須要將app.war包放在tomcat的webapps
        目錄下。
       -->
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

        <!-- Context是一個上下文容器,處理Host轉過來的請求。即掃描webApp的web.xml文件。
        docBase:web應用文件的物理路徑,即絕對路徑
        path:虛擬目錄,指請求訪問該web應用的url入口
        reloadable:true表示tomcat服務器在運行狀態下會監視WEB-INF/classes和
        WEB-INF/lib目錄下class文件的改動,若是檢測到有class文件被更新,則web服務器會自動從新加載web應用。
        -->
        <!--
        <Context docBase="D:/resource/testSQL" path="/testSQL" reloadable="true" source="org.eclipse.jst.j2ee.server:testSQL"/>
        -->
      </Host>
    </Engine>
  </Service>
</Server>

由server.xml文件可知,tomcat的組成包括
1.server:它表示真個servlet容器
2.service:它由Connector(一個或多個)、Engine(負責處理全部Connector得到的請求)組成。
3.Connector:它監聽客戶端請求,將請求交給Engine處理;從Engine獲取處理值再返回給客戶。Tomcat一般有兩個Connector,端口爲8080(默認,能夠修改)的一直監聽來自http的請求;另外一個端口(8009)監聽AJP(協議)請求。
4.Engine:Engine下能夠配置多個虛擬主機,當獲取一個請求時,它將該請求分配到某個Host上,而後將該請求交給Host處理。
5.Host:表示一個虛擬主機,每一個虛擬主機下能夠部署一個或多個webApp,每一個webApp對應一個Context,每一個Context都有一個Context Path。當Host得到一個請求時,將該請求匹配到某個Context上,而後將該請求交給Context來處理。
6.Context:一個Context對應一個webApp,一個webApp由一個或多個Servlet組成,Context在建立的時候根據配置文件$<CATALINA_HOME>/conf/web.xml()與/webapps/WEB-INF/web.xml(app應用下面的web.xml)。這樣就將tomcat與app關聯起來了。
#2.web.xml簡介
一個Context對應一個webApp,每一個webApp由一個或多個Servlet組成,當一個webApp被初始化的時候,它用本身的ClassLoader對象載入"部署文件目錄下的web.xml"中定義的每一個Servlet類,它先載入tomcat的/conf/web.xml中部署的servlet,而後載入webApp根目錄下WEB-INF/web.xml中部署的類。
web.xml文件有兩個部分:Servlet類定義和Servlet映射定義,每一個被載入的Servlet類都有一個名字,而且都會被填入該Context的映射表中,與url-pattern值對應,當Context得到請求的時候,將查詢mapping list,找到被請求的servlet,並執行請求。
web.xml以下java

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- 引言:該文件是全部的webApp通用的配置文件,每當一個webApp被加載時,該文件首先被加載,其次再加載webApp的/WEB-INF/web.xml。
 -->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">

    <!--
      default的servlet
      當用戶的請求沒法匹配任何一個servlet的時候,該servlet被執行
     -->
    <servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 當請求的是一個jsp頁面的時候,該servlet被調用
      它是一個jsp編譯器,將請求的jsp頁面編譯成servlet再執行
     -->
    <servlet>
        <servlet-name>jsp</servlet-name>
        <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
        <init-param>
            <param-name>fork</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>xpoweredBy</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- The mappings for the JSP servlet -->
    <servlet-mapping>
        <servlet-name>jsp</servlet-name>
        <url-pattern>*.jsp</url-pattern>
        <url-pattern>*.jspx</url-pattern>
    </servlet-mapping>

<!-- 其它的省略 -->

</web-app>

#3.tomcat server處理一個http請求流程
假設客戶端的請求爲:http://localhost:8080/testSQL/index.jsp
1.請求被髮到localhost的8080端口,被tomcat監聽器獲取web

<Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />

2.Connector得到請求http://localhost:8080/testSQL/index.jsp,將請求轉給它所在的service的Engine處理spring

<Engine name="Catalina" defaultHost="localhost">

3.Engine得到請求localhost/testSQL/index.jsp,將請求轉給它匹配的Host處理apache

<Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">

很明顯,能夠匹配到主機名爲localhost的主機.(注意:localhost是Engine的默認主機,若是Connector沒有匹配到主機,因爲設置了defaultHost="localhost",也會轉給localhost處理)。
4.Host得到請求/testSQL/index.jsp,匹配它所擁有的全部的Context,匹配路徑是/testSQL的Context,若是沒有匹配到就返回錯誤信息(路徑找不到,這裏能夠配置一個默認的路徑,用於處理找不到路徑時返回404.jsp)。tomcat

<Context docBase="D:/resource/testSQL" path="/testSQL" reloadable="true" />

5.path="/testSQL"的Context得到了/testSQL/index.jsp請求,Context是一個上下文,它加載tomcat的web.xml和app的web.xml,去app的web.xml中匹配servlet-name=testSQL的servlet,而後匹配該servlet-mapping對應的url-pattern值(通常會在這裏作一些限制)服務器

<!-- 工程映射 -->
	<servlet>
		<servlet-name>testSQL</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:spring-config.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>testSQL</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

如上,我這裏配置成/*,即沒有作任何攔截操做,全部的請求都可以經過。
6.匹配servlet成功,調用servlet的doGet或doPost方法
匹配成功,即構造HttpServletRequest對象和HttpServletResponse對象 做爲參數 調用servlet的doGet或doPost方法。
6-1 轉折
由如上的配置信息可知,加載servlet-name=testSQL的時候,會調用DispatcherServlet這個類,而且初始化 spring-config.xml配置文件,DispatcherServlet這個類會分發路徑到每一個contrller,匹配到這個路徑的controller執行處理。app

@RestController
public class UserController {
	
	@Autowired
	private UserService userService;
	
	/**
	 * 獲取用戶列表
	 */
	@RequestMapping(value="/index.jsp",method= RequestMethod.GET)
	public void getUserList() {
		
		userService.getUserList();
		
		}
}

7.處理返回結果
如上處理是在tomcat的Context中,controller執行完後,將結果由HttpServletResponse對象返回給host;host將HttpServletResponse對象返回給Engine;Engine再返回給Connector,Connector在將HttpServletResponse對象返回給客戶端browser。eclipse

相關文章
相關標籤/搜索