WebSphere Application Server 中 Web 服務器插件工作原理及故障診斷

引言

Web 服務器與 WebSphere Application Server ( 簡稱爲 WAS) 配合進行請求分發是一種很常見的拓撲結構。而 IBM WebSphere Application Server 的 Web 服務器插件實際上就是 Web 服務器和 WAS 之間的連接器。它主要的職責就是將從 Web 服務器接收的請求轉送給 WAS。瞭解 Web 服務器插件的工作原理不但可以幫助我們更快地檢測跟插件相關的問題,還能幫助我們構建更加完善的應用架構。

Web 服務器插件的工作原理

跟 WAS 不同,Web 服務器插件是使用 C 語言開發的,所以它會稍微依賴於插件所在的操作系統及使用的 Web 服務器。但這個依賴關係非常小,因爲 Web 服務器插件在不同操作系統和 Web 服務器上的操作都差不多。下面我們就一步步介紹 Web 服務器插件的工作原理。

Web 服務器插件基礎

WAS 前端支持很多不同廠商的 Web 服務器,常見的 Web 服務器包括 IBM HTTP Server、Apache HTTP Server 和微軟的 IIS 等。我們這裏主要以 IBM HTTP Server ( 簡稱 IHS) 爲例。如下圖所示,一個從瀏覽器發送的 HTTP 請求經過 Web 服務器之後會被重新定向給應用服務器 ( 這裏指的應用服務器都是 WAS)。這個重定向的操作就是由 Web 服務器插件來完成的,我們可以把它想成是一個 Web 服務器和應用服務器之間的“代理”。

圖 1. Web 服務器插件

圖 1. Web 服務器插件

這 個重定向是基於一系列插件配置的規則,Web 服務器會優先讓插件去處理每一個請求,只有當插件沒有配置相關的 URL 纔會讓 Web 服務器去處理。我們可以這樣去理解,如果 Web 服務器插件把 HTTP 請求發送給 WAS,那麼插件就可以看成是一個 HTTP 客戶端,WAS 接收這些請求,那 WAS 就可以看成是一個 HTTP 服務器。HttpTransport 組件就是在 WAS 內部充當 HTTP 服務器來接收 HTTP 請求的,我們可以設置多個 HttpTransport 組件配合多個端口使用。

那麼肯定有人要問爲什麼要使用 Web 服務器插件而不直接將 HTTP 請求從 Web 服務器轉給 HttpTransport 組件呢?使用插件來完成這個工作有很多優點:

  • 插件可以提供負載管理和故障轉移的能力幫助我們將請求分發給多個 WAS 或者將請求轉發給合適的 WAS。

  • 靜態頁面由 Web 服務器處理就夠了,不需要轉給 WAS 從而提高處理性能。

  • 插件相當於在客戶端和 WAS 之間多加了一層結構,從而也提高了 WAS 的安全性。

Web 服務器插件架構

接下來就讓我們看看插件工作的細節,幫助我們更好地理解插件的原理:

圖 2. Web 服務器插件請求轉發流程

圖 2. Web 服務器插件請求轉發流程

  1. Web Server Process – native code:從瀏覽器過來的請求第一步會經過默認的 80 端口進入 Web 服務器。

  2. httpd.conf:之後 IHS 會通過默認的 httpd.conf 找到插件的配置文件 plugin-cfg.xml 從而將 HTTP 請求轉給插件。

  3. 插件會在 Web 服務器啓動時加載 plugin-cfg.xml 配置文件。我們需要把插件同 IHS 安裝在同一臺機器上。

  4. plugin-cfg.xml:這是插件的核心配置文件。它包含了哪些 URL 將轉發給 WAS。我們可以通過 WAS 的管理控制檯修改和生成這個配置文件。但修改和生成配置文件後我們還需要同 Web 服務器同步配置信息。

  5. HttpTransport:這個組件實際上可以理解爲一個 WAS 內部的基於 Java 的 HTTP 服務器。它主要的職責就是接收從插件轉過來的請求並將請求再轉給 WAS 的 Web 容器處理。

  6. Web Container:Web 容器最後就是利用 Java EE 的 servlet 規範解析並處理請求,再將處理的結果返回給 Web 服務器插件。

Web 服務器插件工作流程

下面我們將詳細向大家介紹 Web 服務器插件的工作流程,流程主要包括四個步驟:

  • 初始化

  • URL 匹配和 WAS 服務器選擇

  • 將請求發送給指定 WAS

  • 接收從 WAS 返回的結果

  1. 初始化

    當 IHS 啓動後,IHS 會先讀取 <HIS_HOME>\conf\httpd.conf 文件進行初始化。Web 服務器啓動成功後會繼續讀取插件的配置文件 plugin-cfg.xml,並將配置文件中的配置解析出來。一旦 Web 服務器啓動、讀取並加載配置成功之後,插件就可以準備接收 HTTP 請求了。

    如果在 WAS 控制檯中配置了 Web 服務器,當有新的應用安裝到 WAS 上時,我們需要更新插件的 plugin-cfg.xml 配置文件。更新方法有兩種:

    圖 3. WAS 控制檯 Web 服務器管理界面

    圖 3. WAS 控制檯 Web 服務器管理界面

    更新 plugin-cfg.xml 配置文件後,Web 服務器是不需要重啓的。默認情況下,插件會每隔 60 秒自動重新加載配置文件。如果您想更改這個數值,可以修改 plugin-cfg.xml 的配置文件。下面我們把重新加載的時間間隔改爲 5 分鐘 (300 秒 ):

    清單 1. 代碼最大長度示例
     <Config RefreshInterval=”300”> 
     <Log LogLevel="Warn" Name= 
    "D:\WebSphere\AppServer/logs/http_plugin.log"/> 
     <Property Name="ESIEnable" Value="false"/> 
     <Property Name="ESIMaxCacheSize" Value="1024"/>

    在測試或開發環境中可以使用較短的 RefreshInterval 時間,因爲應用或環境需要經常修改。對於比較穩定的生產環境,我們建議 RefreshInterval 值可以設置的稍微長一些,這樣可以提高整個系統的性能。

  • 手工拷貝到插件的配置目錄中或者直接修改配置文件

  • 利用 WAS 管理控制檯生成並傳播新的配置文件

URL 匹配和 WAS 服務器選擇Web 服務器接受到新的 HTTP 請求會首先將這個請求傳給插件。如果插件配置了相應的 URI,插件會匹配 URI 將請求傳給 WAS 處理,如果沒有配置相應的 URI,那隻能由 Web 服務器來處理了。首先我們先介紹一下插件配置中的相關屬性:清單 2. 插件配置的相關屬性 <Config>   <Log LogLevel="Error" Name="<WAS_HOME>\logs\http_plugin.log"/>   <VirtualHostGroup Name="default_host">   <VirtualHost Name="*:80"/>   </VirtualHostGroup>   <ServerCluster Name="MyCluster">   <Server Name="CL1">   <Transport Hostname="SHARAD" Port="9080" Protocol="http"/>   </Server>   </ServerCluster>   <UriGroup Name="MyURIs">   <Uri Name="/MyPath/*"/>   </UriGroup>   <Route ServerCluster="MyCluster"  UriGroup="MyURIs" VirtualHostGroup="default_host"/>   </Config>這些配置的主要作用是就是將一個請求與 ServerCluster 中的一臺服務器關聯起來:接下來,我們就看看整個插件 URL 匹配和選擇服務器的過程:圖 4. 插件 URL 匹配和選擇服務器的過程
  • Step 1:當 Web 服務器接收到一個請求後,它會立即將這個請求轉給插件。

  • Step 2:插件接收到這個請求後會把它分成兩個部分:主機名和 URI 地址。

  • Steps 3, 4, 5, 6:插件會自底至上查找配置文件中定義的 Route,匹配 Route 中的 VirtualHostGroup。如果有多個 Route 都匹配,那麼會選擇最底下匹配的 Route,如果沒有匹配的 Route,那麼插件會把請求返回給 Web 服務器。

  • Steps 7, 8a, 9:接下來插件會依次匹配 UriGroup 中的 URI 地址。當主機名和 URI 地址都匹配了,插件就可以將這個請求轉給合適的 WAS 了。

  • Steps 10a, 10b:如果 VirtualHostGroup 和 URI 匹配失敗,插件會把請求發回給 Web 服務器,如果匹配成功,將從 ServerCluster 選擇合適的服務器接收請求。

  • Steps 11, 12, 13:之後插件會檢查請求的 Cookie 或 URL 中的 jsessionid 參數。從 jsessionid 中找到相應的 CloneID,如果此 CloneID 與某一臺 WAS 的 CloneID 匹配,那麼插件就會將請求轉給這臺 WAS,如果沒有 jsessionid 或者沒有 CloneID 匹配,那麼繼續執行 Step 14。

  • Step 14:如果沒有 jsessionid,插件會根據 ServerCluster 中每臺 WAS 的 LoadBalanceWeight 權重、ClusterAddress 地址和 Random/RoundRobin 隨機 / 輪詢 ( 依次分發 ) 規則尋找合適的 WAS,用戶都可以自行修改這些配置。

  • Step 15:HTTP 請求會被送給目標 WAS,如果 WAS 沒響應或者當機了,那麼插件會通過選擇策略重新選擇合適的 WAS 發送。

  • 插件首先先將請求同每一個 Route 對比一下。一個 Route 包括 ServerCluster、UriGroup 和 VirtualHostGroup 的信息。

  • 根據 HTTP 請求的信息,如果 Route 中有匹配的 UriGroup 和 VirtualHostGroup,那麼插件就會將此請求發給相對應的 ServerCluster。

  • 如果 ServerCluster 中有多個服務器,那麼插件會根據一定的策略或 Session 等信息將請求發送給合適的服務器。

將請求發送給指定 WAS相對於 WAS 來說,插件就是一個 HTTP 客戶端。所以插件的發送過程就是通過 TCP/IP 協議將瀏覽器請求轉發給 WAS。如 果請求成功地轉發給了 WAS,插件會從 WAS 端收到一個成功的 TCP/IP ACK 回覆。如果在超時之前仍沒有收到回覆,插件會返回給 Web 服務器一個 500 錯誤。我們可以通過操作系統層面設置 TCP/IP 的超時時間,也可以在插件的 plugin-cfg.xml 配置文件中設置。接收從 WAS 返回的結果將請求發送給 WAS 後插件會進入等待狀態。當 WAS 返回給插件對應的結果後,插件結束其等待狀態。但當請求處理失敗後,插件會把 WAS 標爲不可用的狀態,如果此 WAS 長期處於不可用狀態,插件會將請求轉給 ServerCluster 中的另一臺 WAS。如果所有的 WAS 都不可用或網絡超時,插件會返回給 Web 服務器一個 500 的錯誤。

對於 WAS 端的 HttpTransport 模塊來說可以理解成一個基於 Java 內嵌的 HTTP 服務器或者內部的 IHS。它會同 WAS 中的 Web Container 通信發送請求並接收處理後的結果。

Web 服務器插件的問題診斷

有時候檢測一個 WAS 組件的問題很困難,而且檢查到最後可能是和 Web 服務器插件相關的問題。接下來我們就會介紹一些工具和技術來幫助大家追蹤和檢測問題。

Web 服務器端的日誌和 Trace

  1. 插件的日誌文件:http_plugin.log

    當出現插件初始化失敗了、HTTP 報 500 或 404 等錯誤、WAS 訪問不了了或者網絡錯誤等問題時可以檢查這個日誌文件。它位於插件目錄的 logs/<web server>/ 裏。

    插件的日誌級別可以設爲三種級別:Error、Warn 或 Trace。Error 級別是默認級別,只打印少量的信息,其次是 Warn 級別,Trace 級別會給出最詳盡的信息。我們可以在 plugin-cfg.xml 配置中修改日誌的級別:

    清單 3. 插件日誌的級別
     <?xml version="1.0" encoding="ISO-8859-1"?> 
     <Config> 
     <Log LogLevel=”Error" Name="E:\Temp\HTTPServer\Plugins\logs\webserver1 
     http_plugin.log"/>

    具體的日誌格式如下:

    [ddd mm dd hh:mm:ss yyyy] PID TID - MsgType: Component: Task: Message

    PID 代表了 Web 服務器的進程 ID,TID 是 PID 中目標請求的線程 ID,這兩個 ID 都是以十六進制格式顯示的。而 MsgType 主要顯示的是三種日誌級別。

    下面的列表顯示的是插件接收到 HttpTransport 的信息 (Trace 級別 ):

    清單 4. Trace 級別的日誌信息
     ============================================================================ 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: ws_common: 
     websphereExecute: Wrote the request; reading the response 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: lib_htresponse: 
     htresponseRead: Reading the response: 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: HTTP/1.1 200 OK 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Server: WebSphere 
     Application Server/5.0 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Set-Cookie: 
     JSESSIONID=0000NIK0UC2LBSJ00VVNHITUAEQ:uji3uq4g;Path=/ 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Cache-Control: no- 
     cache="set-cookie,set-cookie2"
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Expires: Thu, 01 Dec 1994 
     16:00:00 GMT 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Content-Type: text/html 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Content-Language: en-US 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: Transfer-Encoding: 
     chunked 
     [Thu May 01 12:39:05 2003] 000006d0 00000750 - TRACE: ws_common: 
     websphereExecute: Read the response; breaking out of loop 
     ============================================================================
  2. Web 服務器日誌:access.log 和 error.log

    當遇到 HTTP 500 或 404 等錯誤、Web 服務器初始化錯誤或或網絡等問題時可以檢查這兩個日誌文件。

  • access.log:這個文件主要記錄返回給 Web 服務器的每一個迴應,如果 Web 服務器發送一個請求但沒有從 WAS 收到任何迴應的話,我們將無法在這個日誌文件中找到相應的迴應。所以我們可以通過這個日誌文件檢查請求是否得到了正確的響應。他的格式如下:  

    127.0.0.1 - - [01/May/2003:15:48:00 -0500] "GET /AnyPath/MyServlet HTTP/1.0" 200 9736

  • Error.log:這個文件主要記錄 IHS 做遇到的任何錯誤。我們也可以通過 Web 服務器的配置文件 httpd.conf 修改日誌的級別。

WAS 的日誌和 Trace

  1. HttpTransport 的 Trace

    如果我們不能從 Web 服務器和插件的日誌文件中找到有用的信息,那我們就可以在 WAS 中打開 HttpTransport 模塊的 Trace 信息查找相關的信息。如圖:

    圖 5. 開啓 Trace

    圖 5. 開啓 Trace

    HtppTransport 的 Trace 信息如下:

    com.ibm.ws.http.*

    com.ibm.ws.webcontainer.*

  2. WAS 的 SystemOut.log 和 SystemErr.log

    當然,我們也可以通過 WAS 的兩個日誌文件,查看是否有和插件相關的 WAS 問題或 HTTP 錯誤等。

檢測工具

我 們還可以通過操作系統和 WAS 提供的工具幫助我們檢測插件的問題。比如我們可以通過操作系統的 netstat 和 telnet 命令檢測服務器是否可用、網絡是否有問題。也可以通過 WAS 自帶的 TPV (Tivoli Performance Viewer) 或者 ITCAM (IBM Tivoli Composite Application Manager) 輔助我們監測和檢查問題。

結束語

通過了解 Web 服務器插件的工作原理及工作流程,我們可以更好地分析問題和完善應用架構。再加上多種日誌信息和其他工具的輔助,我們可以很方便地定位和解決 Web 服務器插件相關的問題。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章