1. 程式人生 > >tomcat執行載入機制,dns地址解析,tcp/ip三握四揮(全)

tomcat執行載入機制,dns地址解析,tcp/ip三握四揮(全)

一.瞭解從輸入url到顯示頁面過程中都發生了什麼:

   1.通過url並利用DNS解析出目的主機的ip地址;     2.找到目標主機,建立TCP/IP連線;    3.Tomcat監聽到請求,進行處理;    4.返回html檔案,進行頁面渲染;    5.斷開TCP/IP連線(如過有需要的話)     

二.在大致瞭解了上述過程後下面我將進行詳細的講解:

 在講解之前,我們要回憶回憶關於網路的一點小知識:

 TCP/IP四層模型,如下圖所示:


(一)通過url並利用DNS解析出目的主機的ip地址;

    在位址列輸入url,url中的主機名一般是域名,但是我們要將它解析成IP地址,這就用到DNS地址解析

        大致過程就是:客戶端提出域名解析請求,首先檢查本地的DNS快取檔案和hosts檔案,如果沒有就發給本地的域名伺服器,如果有對應項就直接返回,如果沒有對應項,如下圖所示:(我們用www.baidu.com舉例)

        ①就將請求直接就發給全球只有13臺的根域名伺服器,該伺服器返回字尾為 .com. (注意每個根域名後面都有一個.)的頂級域名伺服器的ip地址

        ②本地伺服器去訪問頂級域名伺服器,該伺服器返回類似 baidu.com 的二級域名伺服器的ip地址

        ③本地伺服器去訪問剛返回來的二級域名伺服器,該伺服器返回你要找的www.baidu.com 的ip地址

(二)找到目標主機,建立TCP/IP連線;(三握手)

    根據上一步我們已經獲取到目標主機的ip地址,現在要開始建立TCP/IP連線,TCP/IP三次握手大致過程如下:


①.第一次連線請求SYN_SENT  向伺服器傳送一個攜帶SYN(SYN位置為1)同步資訊,SEQ序號由客戶端隨機生成表明下次接受到的ACK的值要是SEQ+1SEQ每次隨機產生))資訊的報文  只有SYN表示第一次握手

②.第二次連線請求服務端傳送確認資訊是一個攜帶 SYN+ACK(SYNACK都置為1), SEQ由服務端隨機生成序號 = y , ACK確認資訊,它要求下一次客戶端傳送回來的SEQ要為 x+1 就是它自身的值 = x+1rwnd(視窗大小)=5000

③.第三次連線請求 ESTIBLISHD 客戶端向伺服器傳送一個包含ACK , SEQ=x+1被上一次連線限制),ACK=y+1確認資訊,它要求下一次服務端傳送回來的SEQ要為 x+1 就是它自身的值 rwnd=10000視窗大小)的報文資訊


(三)Tomcat監聽到請求,進行處理;

在瞭解這個之前,我們首先看一小段server.xml原始碼:

<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
  <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- 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>
  <!-- A "Service" is a collection of one or more "Connectors" that share
       a single "Container" Note:  A "Service" is not itself a "Container",
       so you may not define subcomponents such as "Valves" at this level.
       Documentation at /docs/config/service.html
   -->
  <Service name="Catalina">
    <!--The connectors can use a shared executor, you can define one or more named thread pools-->
    <!--
    <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
        maxThreads="150" minSpareThreads="4"/>
    -->
    <!-- A "Connector" represents an endpoint by which requests are received
         and responses are returned. Documentation at :
         Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
         Java AJP  Connector: /docs/config/ajp.html
         APR (HTTP/AJP) Connector: /docs/apr.html
         Define a non-SSL HTTP/1.1 Connector on port 8080
    -->
    <Connector port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    <!-- A "Connector" using the shared thread pool-->
    <!--
    <Connector executor="tomcatThreadPool"
               port="8080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    -->
    <!-- Define a SSL HTTP/1.1 Connector on port 8443
         This connector uses the BIO implementation that requires the JSSE
         style configuration. When using the APR/native implementation, the
         OpenSSL style configuration is required as described in the APR/native
         documentation -->
    <!--
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" />
    -->
    <!-- Define an AJP 1.3 Connector on port 8009 -->
    <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
    <!-- An Engine represents the entry point (within Catalina) that processes
         every request.  The Engine implementation for Tomcat stand alone
         analyzes the HTTP headers included with the request, and passes them
         on to the appropriate Host (virtual host).
         Documentation at /docs/config/engine.html -->
    <!-- You should set jvmRoute to support load-balancing via AJP ie :
    <Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
    -->
    <Engine name="Catalina" defaultHost="localhost">
      <!--For clustering, please take a look at documentation at:
          /docs/cluster-howto.html  (simple how to)
          /docs/config/cluster.html (reference documentation) -->
      <!--
      <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
      -->
      <!-- 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>
      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <!-- SingleSignOn valve, share authentication between web applications
             Documentation at: /docs/config/valve.html -->
        <!--
        <Valve className="org.apache.catalina.authenticator.SingleSignOn" />
        -->
        <!-- 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 "%r" %s %b" />
      </Host>
    </Engine>
  </Service>
</Server>

由上述原始碼大致可以總結出tomcat其實分為兩個重要的組成部分:ConnectionContainer 

下面我給出tomcat大致組成圖:


上面的框圖中,我們可以知道,tomcat有兩個核心的元件ConnectionContainer,Tomcat會開啟兩個埠進行服務監聽,8009 8080 8080埠監聽的是BrowserHTTP請求)

Tomcat具體處理請求過程如下:

在輸入http://localhost:8080/TTMS/index.jsp的時候;

① 請求被埠為8080的connector監聽到,在server.xml裡:

② connector將請求交給他所在的service裡對應的engine,來處理;engine獲得請求後,將匹配他所有的host主機,如果匹配不到則交給預設的defaultHost,也就是localhost;此時,從請求localhost/TTMS/index.jsp中解析到,對應的host主機名為“localhost”;

③ host接收到請求後,匹配他下面的context,也就是你部署的專案,這裡從請求路徑“/TTMS/index.jsp”中,解析到對應的context為“TTMS”,故交給name=”TTMS”的context(也就是專案名稱)處理;

④ context隨後在自己的mappingtable(可以在web.xml中進行配置)裡尋找servlet-mapping攔截路徑為*.jsp的servlet,這裡找到得是JSPServlet處理;

⑤ 找到JSPServlet後,開始進行Servlet的處理工作,具體如下:

    Ⅰ. 載入:Servlet類被載入到Java虛擬機器中,並且例項化。在這個過程中,web容器(例如tomcat)會呼叫Servlet類的公開無參建構函式,產生一個Servlet類的例項物件。預設情況下Servlet是在第一次請求的時候載入,但是可以通過<load-on-startup>標籤設定Servlet在Web容器啟動的時候載入。

    Ⅱ. 初始化:Web容器初始化Servlet的時候會呼叫init()方法,所以初始化程式碼應該放在init()方法中,如開啟資料來源等。

    Ⅲ. 提供服務: 當有HTTP請求指向Servlet的時候,呼叫service()方法。如果是繼承自HttpServlet的話,根據不同的請求型別業務邏輯程式碼會包含在doGet()或doPost()方法中。

    Ⅳ. 銷燬:當重新部署Web應用或者關閉Web容器等的時候將呼叫Servlet的destroy()方法。

⑥ context執行完畢後,將HttpServletResponse 返回給Host;

⑦ host將HttpServletResponse 返回給engine;

⑧ engine 將HttpServletResponse 返回給 connector;

⑨ connector 將 HttpServletResponse 返回給使用者的browser;


(四)返回html檔案,進行頁面渲染;

       現在大多數網頁一般都是採用DOM樹的方式進行頁面渲染,因為我的方向主要是後臺,所以就不詳細說明了。。。

(五)斷開TCP/IP連線;(四揮手)

    (一般不會伺服器響應一次就關閉連線,現在的網頁一般建立的都是長連線Keep-alive,因為建立和釋放連線都會消耗大量資源,降低系統工作的效率和速度)

    具體的斷開TCP/IP連線的過程如下:


         ①. 第一步主機A傳送釋放連線請求並將TCP報文的FIN位置為1 隨機生成一個SEQ

         ②. 主機B 主機A傳送確認報文 ACK置為1 隨機生成一個SEQ值,ACK的值位上一步 SEQ 的值加一  第二步主要傳送還沒有傳送完的資料報文資訊

經過這兩步 AB 的連線就釋放掉了(此時整個連線處於半關閉狀態)        A只接收B的迴應     不再向B傳送請求

         ③. 第三步  主機B向主機A傳送 FIN=1 的報文繼續攜帶ACK應用程序釋放連線 B不在傳送報文

         ④. 主機A 主機B傳送確認資訊確認連線關閉

至此,整個連線已經釋放完畢


上述就是我今天要分享的內容,都是本人自己的理解和整理,如有不對請指出。。謝謝