所有實務上所面臨的效能問題,約七成以上的主因都是導因自應用程式,而起因於服務平臺或作業系統的問題相對較少。雖然如此,針對服務平臺的效能調校議題還是不容忽視。而調校的參數會因不同伺服器平臺產品而有些許差異,但以下幾項需要被著重的項目,則會是一致概念。
執行緒(Thread)相關設定
若是想將現行的硬體設備的運算效能發揮到最大,增大執行環境中允許同時進行的執行緒數量是最直接的做法。執行緒的多寡直接反映在CPU用量的比重上,觀察目前的CPU使用狀況,再來調整可行的執行緒數量,以利取得較佳的系統經驗值。
以Tomcat、JBoss而言,你可以指定Connector中的maxThreads,來決定可同時運行的執行緒數量,這會反應在實際可供前方接入的TCP connection最大數。一般規模的網站,該值的設定範圍可從200到600不等,高流量網站甚至可設到1,000以上,視硬體規格搭配度及實際應用特性而定。
而connectionTimeout,則決定來自前端Connector連線之逾時長度,若網站訪客的行為屬於單一頁面停留時間短暫、瀏覽換頁快速,此數值就可以設定得短一些;反之,像是問卷系統,使用者需要在同一頁上有較長作答時間,則建議調高,以避免重複花費建立connection的時間。實務上設置的範圍約略在2,000至60,000之間(ms)。
而應用服務平臺一般亦提供Threads Pooling的機制,以利透過Pool直接取用,在回應效能上會有明顯改善。像是Tomcat或JBoss平臺中可透過設定Executor的方式來指定Threads Pool的機制,同時定義Pool內最大(maxSpareThreads)、最小(minSpareThreads)閒置執行緒的數量,以及執行緒的最大閒置時間(maxIdleTime),來有效管理執行緒生命周期。
另外,要將確定不被使用的預設Connector設定予以移除,免去多餘的資源浪費。常見的像是Tomcat若是透過前端Apache HTTP Server以mod_jk方式接入,就僅需保留AJP Connector,而將預設啟用的HTTP Connector設定內容移除。
記憶體相關設定
記憶體用量的管理,可配置的區域主要分為Heap及Non-Heap等兩部分。而就參數設置而言,則可以從JVM本身啟動腳本的參數值先行著手,可著重在記憶體空間的配置,以及垃圾回收(Garbage Collection,GC)機制等兩大方向來思考。
Heap記憶體空間的配置,可透過像是JVM啟動參數的xms、xmx來設定,決定記憶體初始及最高配置量,這空間主要提供給執行時期所需的物件實例(Instance)使用,若網站使用較多生命周期較長的變數,而且會依流量明顯成長的(像是session scope變數),或是在邏輯運算需要定義較多的暫存變數,則這部分需要給予較高的設定值。
而參數XX:PermSize、XX:MaxPermSize,則決定可配置永久保存區(Non-Heap Memory)的記憶體空間,此區則主要提供載入類別(Class)及Meta信息所使用,若程式在執行時期用了較多的外部API 套件,則此參數需要配置較大的空間。
垃圾回收(GC),則是清理Heap Memory空間中已不使用的記憶空間,可定義MinHeapFreeRatio、MaxHeapFreeRatio參數,來決定啟動GC作業執行的水位點。透過增添JVM啟動參數(-verbose:gc)或Profiling工具,來觀察GC作業歷程,進而定義Generation Size及Collector類型,以改善效能。
另外,就外部函式庫(External JAR)的載入問題,將全站各個webapp都會用到的函式庫部署至Server層級(像是Oracle / MySQL JDBC Driver),而個別webapp特定使用的函式庫才部署於自己網站程式中,避免類別被重複載入及版本衝突控管不易的問題;而檢視網站程式中不需要的外部函式庫(External JAR)予以簡化甚至移除,減少應用伺服器在啟動時不必要類別的載入,也是常見方法。
資料庫連線相關設定
對於應用伺服器而言,資料庫是相當重要的資料來源,Connection Pooling機制亦已廣泛使用,此機制提供從應用伺服器連至資料庫的連線管理方式。常見的解決方案像是Apache DBCP、Proxool等,明顯效益在於,有效節省取得資料庫連線的成本。
定義Pool初始最小連線數 (minimum-connection-count) 及最大連線數(maximum-connection-count) ,決定同時連線數的彈性,這與網站使用者流量的穩定度有高度相關。然而最大連線數的設置,也能保護資料庫系統,免於瞬間大量請求而灌爆。
一旦連線建立,資料庫系統則會產生執行緒來服務此連線需求,就會有運算效能耗用,所以定義最大連線數的參數值時,需一併考慮目前資料庫系統所可配置的系統資源及運算能力,若多臺應用伺服器的架構下,每臺定義的連線設定則需統整考量。
而針對平時及尖峰時段Pool中的active/idle connection數量做為調校參考。若Idle數量遠較Active數量為高,表示有許多資料庫連線被建立、但無任何資料存取,則可考慮將removeAbandonedTimeout時間調短,由管理機制及早釋放無用的連線資源。
記錄檔(Logging)機制
應用程式常利用記錄檔輔助測試及釐清問題,然而大量寫入記錄的行為亦常造成系統效能瓶頸,而一般服務平臺預設開啟記錄檔機制,像是主控臺的執行記錄顯示,使用大量的I/O動作而牽制執行效能。
在程式開發過程中,系統事件的記錄方式透過完整的記錄軟體框架(像是log4j)來達成,可適時開關記錄檔機制的啟動與否,以及決定記錄等級高低,亦是減少上線系統寫入記錄頻率的較佳方式。進階做法可再結合非同步機制(像是佇列或是訊息服務)來縮短回應時間,不讓記錄寫入成為主程式的效能負擔。
而記錄檔機制的預設值是不適合上線系統,記錄檔的大小也影響寫入效能,一般以日期設定檔案切割,除了避免單檔過大,也方便日常維運。
快取(Cache)管理機制
應用伺服器本身(像JBoss),或是常見知名的軟體框架(Spring Framework中的EHCache)中都包含物件快取機制。就快取內容而言,主要是針對類別及物件本身,或是被叫用的方法暫存於記憶體中以提升執行效率。針對網站大量的唯讀行為,像是部落格文章、新聞的瀏覽,內容異動頻率較低,快取機制效益則可以發揮到最大;若針對其他涉及資料寫入等行為,透過快取也許可獲得較佳的回應時間,然而資料同步策略則需要設定得當,否則容易造成快取內容與實體資料不一致的混亂現象。
就實務而言,Cache機制所指定的磁碟位置盡可能與系統磁碟機錯開,提升磁碟I/O效能;而要指定快取的物件,主要以stateless的商業邏輯元件(像是Service、Factory模式元件),以及異動頻率較低的Entity資料物件(像是全國縣市鄉鎮區域列表);而資料存取的prepared statement也是被快取的重要項目,當受到重複呼叫時,更能提升資料查詢效能。Hibernate本身的Query Cache功能,效果也是類似。
而快取效益一般是由命中率來衡量,再調整應設置的快取空間。因為當請求發生時無法在快取區中取得所需的資料,重新從資料儲存區建立載入 (Activate)快取物件,並同時遺棄(Passivate)不再使用的快取物件,過程相當費時。一般而言,快取命中率必須達八成以上,才算有效發揮。
專欄作者
熱門新聞
2026-01-12
2026-01-12
2026-01-12
2026-01-12
2026-01-12