編者按: 筆者遇到某單位Web 網(wǎng)站運行遲緩問題,初步排查是由于某些默認配置較低所致,之后筆者從架構(gòu)上對其進行了調(diào)整,徹底解決了該問題。
某單位的Web 網(wǎng)站最近訪問量比較大,造成網(wǎng)頁打開遲緩或者無法打開的問題。該網(wǎng)站基于J2EE 架構(gòu),在Web服務器上運行的是TomCat服務,數(shù)據(jù)庫服務器上安裝的是MySQL。
在出現(xiàn)故障后,單位對Tomcat 進行了重啟,這時網(wǎng)站雖然可以正常方式,但是很快就出現(xiàn)了無法訪問的故障。筆者通過執(zhí)行“top”“vmstat”等命令,發(fā)現(xiàn)CPU處于高負載狀態(tài),僅僅Java進程就占用了大量的CPU 資源,但是內(nèi)存的消耗并不大。
進入TomCat 安裝路徑下的“conf”目錄,打開其中的“server.xml”文件,發(fā)現(xiàn)其中的所有配置都采用了模式設置,而且其JVM 配置也采用的默認配置,并沒有采取具體的優(yōu)化措施。在Tomcat默認配置中很多參數(shù)都設置的很低,對于內(nèi)存和線程的配置來說尤甚。這些默認配置在低Web 業(yè)務量不會出現(xiàn)問題,一旦Web 業(yè)務量大量增長,很容易成為性能瓶頸。
例如,在“server.xml”中適當增大maxThreads(客戶請求最大線程數(shù))、minSpare Threads(Tomcat初始化 時創(chuàng)建的socket 線程數(shù))、max SpareThreads(Tomcat 連接器的最大空閑socket 線程數(shù))、acceptAccount(監(jiān)聽端口隊列最大數(shù))、minProce ssors(服務器創(chuàng)建時的最小處理線程數(shù))以及maxProce ssors(服務器同時最大處理線程數(shù))等參數(shù)的值,對其配置進行優(yōu)化處理。
進入“bin”目錄并打開“catalina.sh”文件,在其中添 加“-server–Xms8192m–Xmx8192m-Xmn1g-XX:PermSize=256M-XX:Max PermSize=512m”行,針對JVM 內(nèi)存配置進行優(yōu)化,這里是基于32 GB 內(nèi)存進行調(diào)整的。當重啟TomCat后,執(zhí)行“top”命令,會發(fā)現(xiàn)其占用的CPU 資源會逐漸降低。并且服務器的訪問效能提高了很多,但是Java 進程占用CPU的資源依然很高。
執(zhí) 行“l(fā)sof” “netstat”等命令,發(fā)現(xiàn)存在大量的Java 請求等待信 息。對TomCat日志進行分析后,發(fā)現(xiàn)存在很多報錯信息,提示數(shù)據(jù)庫連接超時,無法連接到數(shù)據(jù)庫等情況。
Tomcat 本身僅僅是一個Java 容器,使用連接/線程模型處理業(yè)務請求,主要用于處理JSP、Servlet 等動態(tài)應用。如果將其作為HTTP服務器使用,是無法高效率的處理靜態(tài)資源的。根據(jù)觀察到的情況分析,原因很可能是Tomcat 無法及時響應客戶端的請求,導致請求隊列越來越多,直到Tomcat 徹底無法工作。
對于正常的訪問請求來說,服務器會將其轉(zhuǎn)交給Tomcat 進行處理,Tomcat接著執(zhí)行編譯和訪問數(shù)據(jù)庫等操作,之后將信息返回給客戶端,客戶端接收到信息后,Tomcat 就關閉這個請求鏈接。在大訪問量的高并發(fā)訪問環(huán)境中,很多的請求在短時間內(nèi)都提交給Tomcat 處理,這樣Tomcat 應接不暇最終失去響應,造成Java 進程處于僵化狀態(tài)無法釋放其占用的CPU 資源。
要想解決以上問題,只有從架構(gòu)上對TomCat 進行調(diào)整。Tomcat 擅長處理JSP動態(tài)頁面,但是對于靜態(tài)頁面的處理不如Apache,這時可將Apache 和Tomcat 安裝在一臺服務器上,如果條件許可的話,最好將Apache 和TomCat 部署到兩臺服務器上。Apache和Tomcat的整合,可以通過jk 模塊結(jié)合AJP協(xié)議來實現(xiàn)。
然后執(zhí)行以下命令來編譯JK:
將得到的“mod_jk.so”文件復制到“/usr/local/apache2/modules”目錄中,設置所需的JK 連接器。
執(zhí)行“vim httpd.conf”命令,在Apache 配置文件中添加以下行,對JK 連接器屬性進行配置:
進入Apache的“conf”目錄,執(zhí)行“vim workers.properties”命令,輸入以下命令:
保存該文件,其作用是定義名為“tomcat1”的Tomcat Workers。
之后執(zhí)行“/usr/local/apache2/conf/uriworker map.properties”命令,創(chuàng)建URL 過濾規(guī)則文件,指定何種URL 由Tomcat 處理。
例如,輸入以下行:
指定所有請求都交給上述“tomcat1”處理。但是以下類型的文件Tomcat 不會處理,會先被JK 解析,之后交由Apache 處理,可以根據(jù)需要設置所需的文件類型。
進入Tomcat的“conf”目錄,執(zhí)行“vim server.xml”命令,并在其核心配置文件中的默認“”后面追加“Host name="x.x.x.x" debug="0"appBase="/web/site" un packWARs="true" ”行,其中的“x.x.x.x”為本機的IP。當然,Tomcat 虛擬主機要和Apache 配置的虛擬主機指向相同的網(wǎng)站路徑。打開“catalina.sh”文件,在開頭處添加“JAVA_HOME=/usr/local/jdk1.8.0_162”“export JAVA_HOME”行,設置所需的環(huán)境變量。
執(zhí)行以下等命令,來啟動Toamcat 和Apache:
通過查看“/usr/local/tomcat8.x/logs/catalina.out”文件,可以了解TomCat啟動日志信息。經(jīng)過以上架構(gòu)上的調(diào)整優(yōu)化,可以觀察到Java的資源占用率在逐步降低。但在高并發(fā)訪問情況下,Java 進程有時還存在占用較高CPU 資源的問題。
筆者對Tomcat日志進行分析后,發(fā)現(xiàn)僅僅使用一臺Tomcat 應用服務器是不夠的。于是筆者在前端服務器上運行Apache 和Mod_JK 模塊,負責調(diào)度和處理用戶的請求,在后端配置多臺TomCat 服務器負責動態(tài)應用的解析操作,并通過將負載均衡機制,將這些請求分配給多個Tomcat 服務器。即配置多臺Tomcat 服務器組成集群,利用JK 模塊構(gòu)建Tomcat 負載均衡系統(tǒng),將Apache 服務器傳送過來的請求,調(diào)度到不同的Tomcat 服務器上,讓其執(zhí)行動態(tài)解析操作。
對于集群模式來說,可以配置NFS 共享目錄,讓Apache 和多臺TomCat 之 間共享數(shù)據(jù)。這樣才徹底解決了上述故障,讓該網(wǎng)站高效運行起來。