<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # Web 服務器如何工作? > 原文: [https://howtodoinjava.com/tomcat/a-birds-eye-view-on-how-web-servers-work/](https://howtodoinjava.com/tomcat/a-birds-eye-view-on-how-web-servers-work/) 許多時候,我們想知道 **Web 容器 / Web 服務器(例如 tomcat 或 jboss)如何工作?** 他們如何處理來自世界各地的傳入 HTTP 請求? 幕后發生的原因是什么? Java Servlet API(例如`ServletContext`,`ServletRequest`,`ServletResponse`和`Session`之類的類)如何適應圖片? 這些是非常重要的問題/概念,如果您是 Web 應用開發人員或渴望成為,則必須知道。 在這篇文章中,我將嘗試找出上述問題的答案,即使不是全部。 從這里保持集中。 ```java Table of Contents: What are web server, application server and web container? What are Servlets? How they help? What is ServletContext? Who creates it? Where ServletRequest and ServletResponse fits into life cycle? How Session is managed? Know the cookie? How thread safety should be ensured? ``` ## 什么是 Web 服務器,應用服務器和 Web 容器? 我將首先討論 **Web 服務器**和應用服務器。 我說一句 “從歷史上看,它們是不同的,但是這兩個以前截然不同的類別逐漸合并,現在在大多數情況和用途中應被視為一個實體。” 在 [**Mosaic**](https://en.wikipedia.org/wiki/Mosaic_%28web_browser%29 "Mosaic") 瀏覽器(通常被稱為第一個圖形化 Web 瀏覽器)和超鏈接內容的早期,出現了一種新概念“Web 服務器”,用于服務靜態網頁內容和 [**HTTP**](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol "http") 協議上的圖像。 很簡單。 如今,大多數內容都是靜態的,HTTP 1.0 協議只是一種隨身攜帶文件的方式。 但是很快,Web 服務器就發展為具有 [**CGI**](http://www.invir.com/int-prog-cgi.html "cgi") 功能。 這意味著在每個 Web 請求上有效啟動一個流程以生成動態內容。 到那時,HTTP 協議也已經成熟,Web 服務器變得更加復雜,并具有諸如緩存,安全性和會話管理之類的附加功能。 隨著技術的進一步成熟,我們從 Kiva 和 [**NetDynamics**](https://en.wikipedia.org/wiki/NetDynamics_Application_Server) 中獲得了基于公司的基于 Java 的服務器端技術,最終它們全部合并為 JSP(java 服務器頁面), 在當今大多數應用開發中使用。 ![web server application server](https://img.kancloud.cn/d6/5b/d65be8b4899f6c2041f6156e4ca6c884_600x418.png) 這是關于網絡服務器的。 現在,我們來討論**應用服務器**。 在并行類別中,應用服務器已經發展并存在了很長時間。 一些公司為 Unix 提供了諸如 [**Tuxedo**](https://en.wikipedia.org/wiki/Tuxedo_%28software%29 "Tuxedo")(面向事務的中間件),**TopEnd**,**Encina** 等產品,這些產品從大型機應用管理中衍生而來 和監視環境,例如 IMS 和 CICS。 這些產品大多數都指定了“封閉式”產品特定的通信協議,以將“胖”客戶端互連到服務器。 在 90 年代,這些傳統的應用服務器產品首先通過網關開始嵌入基本的 HTTP 通信功能。 很快,這兩類之間的界限開始模糊。 到那時,Web 服務器在處理更高的負載,更多的并發和更好的功能方面變得越來越成熟。 應用服務器開始提供越來越多的基于 HTTP 的通信功能。 所有這些都導致 Web 服務器和應用服務器之間的界限很窄。 在這一點上,“應用服務器”和“網絡服務器”之間的界線是模糊的。 但是,作為重點,人們繼續使用不同的術語。 當有人說“Web 服務器”時,您通常會想到以 HTTP 為中心,面向 Web UI 的應用。 當有人說“應用服務器”時,您可能會認為“負載較重,企業功能,事務和排隊,多通道通信(HTTP 及其他)”。 但是大多數情況下,這是同一款產品,如今可以同時滿足這兩種要求。 這就是有關 Web 服務器和應用服務器的一切。 現在進入第三個術語,即網絡容器。 ![web server servlet container](https://img.kancloud.cn/63/2e/632e9c40ae7c8eff077ccf82f1c7b483_535x211.png) [**Web 容器**](https://en.wikipedia.org/wiki/Web_container),尤其是 java 中的,應引用 servlet 容器。 Servlet 容器是與 Java Servlet 交互的 Web 服務器的組件。 Web 容器負責管理 Servlet 的生命周期,將 URL 映射到特定的 Servlet,并確保 URL 請求者具有正確的訪問權限以及更多此類服務。 基本上,綜合以上所有事實, **Servlet 容器是 Servlet 運行**并維持其生命周期的運行時環境。 ## 什么是 Servlet? 他們如何提供幫助? 在 Java 中,**servlet 使您可以編寫服務器端組件,以根據請求幫助生成動態內容**。 實際上,Servlet 是在`javax.servlet`包中定義的接口。 它聲明了 Servlet 生命周期的三種基本方法 - `init()`,`service()`和`destroy()`。 它們由每個 servlet(在 SDK 中定義或由用戶定義)實現,并在服務器的生命周期中由服務器在特定時間調用。 Servlet 類由其類加載器通過**延遲加載或急切加載**動態地加載到容器中。 **每個請求都在其自己的線程**中,并且 servlet 對象可以同時服務多個線程。 當不再使用它時,它將被 JVM 垃圾回收。 **延遲加載 servlet** ![Lazy Loaded Servlet1](https://img.kancloud.cn/2a/53/2a5328dbf4c24f570b05c1a799976efd_302x306.png) ![Lazy Loaded Servlet](https://img.kancloud.cn/e7/b0/e7b0632f83e46fb51105c9a0b71d265b_301x305.png) **立即加載 Servlet** ![Eagerly Loaded Servlet1](https://img.kancloud.cn/02/87/02870de29c3b6672748324f4364f1ee9_303x306.png) ![Eagerly Loaded Servlet](https://img.kancloud.cn/25/d5/25d557540217844c53dac4425e293dcd_302x305.png) ## 什么是`ServletContext`? 誰創造的? 當 Servlet 容器啟動時,它將部署并加載所有 Web 應用。 加載 Web 應用后,Servlet 容器將為每個應用創建一次` ServletContext`,并將其保留在服務器的內存中。 該 Web 應用的`web.xml`將被解析,并且在`web.xml`中找到的每個 Servlet,過濾器和監聽器都將被創建一次并保存在服務器的內存中。 當 Servlet 容器關閉時,它將卸載所有 Web 應用,并且`ServletContext`以及所有 Servlet,過濾器和監聽器實例都將被丟棄。 根據 Java 文檔, `ServletContext`定義了 Servlet 用于與其 Servlet 容器通信的一組方法,例如,獲取文件的 MIME 類型,調度請求或寫入日志文件。 對于 Web 應用**在其部署描述符**中標記為“已分發”的情況,每個虛擬機都有一個上下文實例。 在這種情況下,上下文**不能用作共享全局信息**的位置(因為該信息不是真正的全局信息)。 請改用外部資源,例如數據庫。 ## `ServletRequest`和`ServletResponse`適合生命周期的地方? Servlet 容器連接到 Web 服務器,該服務器在特定端口號(通常為 80)上監聽 HTTP 請求。當客戶端(具有 Web 瀏覽器的用戶)發送 HTTP 請求時, Servlet 容器將創建新的`HttpServletRequest`和`HttpServletResponse`對象將其傳遞給 URL 樣式與請求 URL 匹配的已創建過濾器和 Servlet 實例的方法,所有這些都在同一線程中。 請求對象提供對 HTTP 請求的所有信息的訪問,例如請求標頭和請求正文。 響應對象提供了以所需方式控制和發送 HTTP 響應的功能,例如設置標頭和正文(通常帶有 JSP 文件中的 HTML 內容)。 提交并完成 HTTP 響應后,請求和響應對象都將被丟棄。 ## 如何管理會話? 知道 cookie 嗎? 當客戶端首次訪問 Web 應用和/或要通過`request.getSession()`首次獲取`HttpSession`時,則 Servlet 容器將創建它,并生成一個長而唯一的 ID(您可以通過`session.getId()`獲取并存儲在服務器的內存中。 servlet 容器還將在 HTTP 響應中設置 Cookie,其中`JSESSIONID`為 cookie 名稱,唯一會話 ID 為 cookie 值。 根據 [**HTTP cookie 規范**](http://www.faqs.org/rfcs/rfc2965.html "http cookie")(體面的 Web 瀏覽器和 Web 服務器必須遵守的約定),要求客戶端(Web 瀏覽器)在后續請求中將該 Cookie 發送回 只要 Cookie 有效即可。 Servlet 容器將確定每個傳入的 HTTP 請求標頭中是否存在名為`JSESSIONID`的 cookie,并使用其值從服務器的內存中獲取關聯的`HttpSession`。 `HttpSession`會一直存在,直到沒有被使用為止,您可以在`web.xml`中指定該設置,該設置**默認為 30 分鐘**。 因此,如果客戶端超過 30 分鐘不再訪問該 Web 應用,則 Servlet 容器將破壞該會話。 即使指定了 cookie,每個后續請求都將無法再訪問同一會話。 servlet 容器將創建一個新的。 **現有會話** ![Existing session](https://img.kancloud.cn/0f/39/0f39fadd16c06b5de2128f585ac30919_302x307.png) **新會話** ![New session](https://img.kancloud.cn/4a/17/4a17ad917f8f98cb64b90ac0bbdb5d4a_606x308.png) 另一方面,客戶端上的會話 cookie **具有默認生存期,該生存期只要瀏覽器實例正在運行**即可。 因此,當客戶端關閉瀏覽器實例(所有選項卡/窗口)時,會話將在客戶端被丟棄。 在新的瀏覽器實例中,與該會話關聯的 cookie 將不再發送。 一個新的`request.getSession()`將返回一個全新的`HttpSession`并設置一個具有全新會話 ID 的 cookie。 ## 應如何確保線程安全? 您現在應該已經了解到,Servlet 和過濾器在所有請求之間共享。 這是 Java 的優點,因為它是[**多線程**](//howtodoinjava.com/category/java/multi-threading/ "multi-threading"),并且不同的線程(即 HTTP 請求)可以使用同一實例。 否則,在每個請求上重新創建它會太昂貴。 ![thread-safety](https://img.kancloud.cn/87/93/8793d71ed5e12a9a8cbd03d70c20bab0_303x305.png) 但是,您還應該意識到,永遠不要將任何請求或會話范圍的數據分配為 Servlet 或過濾器的實例變量。 它將在其他會話中的所有其他請求之間共享。 那是線程不安全的! 下面的示例說明: ```java public class MyServlet extends HttpServlet { private Object thisIsNOTThreadSafe; //Don't to this protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Object thisIsThreadSafe; thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests! thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe. } } ``` 不要這樣做。 這將導致軟件錯誤。 以上就是這個主題。 請繼續關注更多此類帖子。 最好訂閱電子郵件新聞信,以在收件箱中獲得通知。 **祝您學習愉快!** **推薦鏈接**: [http://www.invir.com/int-prog-cgi.html](http://www.invir.com/int-prog-cgi.html)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看