系統優化怎麼做-Tomcat優化

昌鬆發表於2018-08-04

大家好,這裡是「聊聊系統優化 」,並在下列地址同步更新

在這裡我會從基於J2EE系統及網際網路架構方面,來談談系統優化的各個方面,乾貨滿滿,歡迎訂閱及關注!

 

前言

Tomcat作為Web應用的伺服器,目前絕大多數公司都是用其作為應用伺服器的,應用伺服器的執行效率會影響系統執行,這裡會講Tomcat怎樣進行配置能提高處理效能。另外必須提到對應的JVM引數的優化的一些經驗。

Tomcat執行模式

分3種模式: bio,nio,apr 一般使用nio模式
bio效率低,apr對系統配置有一些比較高的要求

確認Tomcat的執行模式

配置檔案 server.xml

<Executor name="tomcatThreadPool" 
namePrefix="catalina-exec-" 
maxThreads="1024" 
minSpareThreads="512" 
prestartminSpareThreads="true" />

 

關鍵配置

maxThreads

最大執行緒數, 預設是200

minSpareThread

最小活躍執行緒數, 預設是25

maxQueueSize

最大的等待佇列個數,超過則請求拒絕預設值是Integer.MAX_VALUE ,一般不改變。在某些緊急狀態修復問題需要調整

聯結器(Connector)優化

Connector是聯結器,負責接收客戶的請求,以及向客戶端回送響應的訊息。所以Connector的優化是重要部分。預設情況下 Tomcat只支援200執行緒訪問,超過這個數量的連線將被等待甚至超時放棄,所以我們需要提高這方面的處理能力。

nio配置- server.xml

<Connector port="14081" protocol="org.apache.coyote.http11.Http11NioProtocol"
connectionTimeout="20000"
executor="tomcatThreadPool" 
URIEncoding="UTF-8" 
compression="on"   
useBodyEncodingForURI="true" 
enableLookups="false" 
redirectPort="14443" />

影響效能配置

  • protocol

org.apache.coyote.http11.Http11Protocol – 阻塞式的Java聯結器
org.apache.coyote.http11.Http11NioProtocol – 不阻塞Java聯結器
org.apache.coyote.http11.Http11AprProtocol – APR / native 聯結器
選擇不阻塞ava聯結器

  • enableLookups

若是你想request.getRemoteHost()的呼叫履行,以便返回的長途客戶端的實際主機名的DNS查詢,則設定為true。設定為false時跳過DNS查詢,並返回字串的IP地址(從而提高效能)。預設場景下,禁用DNS查詢

  • compression

設定成on,開啟壓縮

禁用AJP連結器

使用Nginx+tomcat的架構,用不著AJP協議,所以把AJP聯結器禁用
server.xml註釋掉一下配置

  <Connector port="8019" protocol="AJP/1.3" redirectPort="8443" />

優化JVM

/bin/catalina.sh

修改JAVA_OPTS引數
這裡需要參照機器配置,對JVM進行引數優化

JDK1.7

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=1024M -XX:PermSize=1024m -XX:MaxPermSize=1024m -XX:+DisableExplicitGC"

JDK1.8

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms1024m -Xmx1024m -XX:NewSize=512m -XX:MaxNewSize=1024M -XX:+DisableExplicitGC"

 

1.8 版本中已經沒有PermSize、MaxPermSize

JAVA8裡對metaspace可以在小範圍自動擴充套件永生代避免溢位。

引數說明

  • -Djava.awt.headless

沒有裝置、鍵盤或滑鼠的模式。

  • -Dfile.encoding

設定字符集

  • -server

vm的server工作模式,對應的有client工作模式。使用“java -version”可以檢視當前工作模式

  • -Xms1024m

初始Heap大小,使用的最小記憶體

  • -Xmx1024m

Java heap最大值,使用的最大記憶體
經驗: 設定Xms大小等於Xmx大小

  • -XX:NewSize=512m

表示新生代初始記憶體的大小,應該小於 -Xms的值

  • -XX:MaxNewSize=1024M

表示新生代可被分配的記憶體的最大上限,應該小於 -Xmx的值

  • -XX:PermSize=1024m

設定記憶體的永久儲存區域,記憶體的永久儲存區域,VM 存放Class 和 Meta 資訊,JVM在執行期間不會清除該區域

程式載入很多class情況下,超出PermSize情況下

JDK1.7會丟擲java.lang.OutOfMemoryError: PermGen space異常

JDK1.8下會丟擲 ERROR: java.lang.OutOfMemoryError: Metadata space 異常

  • -XX:MaxPermSize=1024m

設定最大記憶體的永久儲存區域
經驗: 設定PermSize大小等於MaxPermSize大小

  • -XX:+DisableExplicitGC

自動將System.gc()呼叫轉換成一個空操作,即應用中呼叫System.gc()會變成一個空操作,避免程式設計師在程式碼裡進行System.gc()這種危險操作。System.gc() 除非是到了萬不得也的情況下不使用,都交給JVM吧

其他優化引數

  • -XX:SurvivorRatio=2

年輕代中Eden區與Survivor區的大小比值

  • -XX:ReservedCodeCacheSize=256m

保留程式碼佔用的記憶體容量,無大的影響

  • -Xss1024k

單個執行緒堆疊大小值,減少這個值可以生成更多執行緒,作業系統對於一個程式內的執行緒數是有限制的,經驗值在3000-5000左右

  • -XX:+CMSParallelRemarkEnabled

CMS 垃圾回收演算法,對響應時間的重要性需求 大於 對吞吐量的要求,能夠承受垃圾回收執行緒和應用執行緒共享處理器資源,並且應用中存在比較多的長生命週期的物件的應用

  • -XX:+UseCMSCompactAtFullCollection

在使用concurrent gc 的情況下, 防止 memoryfragmention, 對live object 進行整理, 使 memory 碎片減少。

  • -XX:+UseCMSInitiatingOccupancyOnly

在FULL GC的時候, 對年老代的壓縮。CMS是不會移動記憶體的, 因此這個非常容易產生碎片, 導致記憶體不夠用, 因此, 記憶體的壓縮這個時候就會被啟用。 增加這個引數是個好習慣。可能會影響效能,但是可以消除碎片。

  • -XX:CMSInitiatingOccupancyFraction=60

使用cms作為垃圾回收, 使用60%後開始CMS收集

  • -XX:+UseGCOverheadLimit

用來限制使用記憶體,如果不做控制,可能會報出
java.lang.OutOfMemoryError: GC overhead limit exceeded

  • -XX:+UseConcMarkSweepGC

使用CMS記憶體收集

  • -XX:+UseParNewGC

設定年輕代為並行收集

  • -XX:+HeapDumpOnOutOfMemoryError
  • -XX:HeapDumpPath=/x/dump_tomcat.hprof

JVM會在遇到OutOfMemoryError時拍攝一個“堆轉儲快照”,並將其儲存在一個檔案中。

  • -Xloggc:/xx/gc_tomcat.log

gc的日誌,如果該日誌中出現頻繁的Full GC就是有相關的系統問題,如果很少,說明暫時還算正常

  • -XX:+PrintGCDateStamps

輸出GC的時間戳(以基準時間的形式)

  • -XX:+PrintGCDetails

輸出GC的日誌格式

  • -Dnetworkaddress.cache.ttl=60
  • -Dsun.net.inetaddr.ttl=60

設定DNS快取時間

  • -DautoStartup=false
  • -Dsun.net.client.defaultConnectTimeout=60000

連線建立超時時間

  • -Dsun.net.client.defaultReadTimeout=60000

內容獲取超時設定

  • -Djmagick.systemclassloader=no

是否生成縮圖的一個框架的配置

  • -Djava.security.egd=file:/dev/./urandom

最佳實踐

export JAVA_OPTS="-server -showversion -Xms2000m -Xmx2000m -Xmn500m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:SurvivorRatio=2 -XX:ReservedCodeCacheSize=256m -Xss1024k -Djava.awt.headless=true -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=60 -XX:+UseGCOverheadLimit -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tomcat_path/logs/dump_tomcat.hprof -Xloggc:/tomcat_path/logs/gc_tomcat.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCDetails -Dnetworkaddress.cache.ttl=60 -Dsun.net.inetaddr.ttl=60 -DautoStartup=false -Dsun.net.client.defaultConnectTimeout=60000 -Dsun.net.client.defaultReadTimeout=60000 -Djmagick.systemclassloader=no -Djava.security.egd=file:/dev/./urandom -Dfile.encoding=UTF-8"

常見JVM異常

  • java.lang.OutOfMemoryError: Java heap space —-JVM Heap(堆)溢位

JVM 在啟動的時候會自動設定 JVM Heap 的值,其初始空間(即-Xms)是實體記憶體的1/64,最大空間(-Xmx)不可超過實體記憶體。可以利用 JVM提供的 -Xmn -Xms -Xmx 等選項可進行設定。Heap 的大小是 Young Generation 和 Tenured Generaion 之和。在 JVM 中如果 98% 的時間是用於 GC,且可用的 Heap size 不足 2% 的時候將丟擲此異常資訊。

解決方法:手動設定 JVM Heap(堆)的大小。

  • java.lang.OutOfMemoryError: PermGen space —- PermGen space溢位。

jdk1.8 丟擲 ERROR: java.lang.OutOfMemoryError: Metadata space 異常

PermGen space 的全稱是 Permanent Generation space,是指記憶體的永久儲存區域。為什麼會記憶體溢位,這是由於這塊記憶體主要是被 JVM 存放Class 和 Meta 資訊的,Class 在被 Load 的時候被放入 PermGen space 區域,它和存放 Instance 的 Heap 區域不同,sun 的 GC 不會在主程式執行期對 PermGen space 進行清理,所以如果你的 APP 會載入很多 CLASS 的話,就很可能出現 PermGen space 溢位。

解決方法: 手動設定 MaxPermSize 大小

  • java.lang.StackOverflowError —- 棧溢位

棧溢位了,JVM 依然是採用棧式的虛擬機器。函式的呼叫過程都體現在堆疊和退棧上了。呼叫建構函式的 “層”太多了,以致於把棧區溢位了。通常來講,一般棧區遠遠小於堆區的,因為函式呼叫過程往往不會多於上千層,而即便每個函式呼叫需要 1K 的空間(這個大約相當於在一個 C 函式內宣告瞭 256 個 int 型別的變數),那麼棧區也不過是需要 1MB 的空間。通常棧的大小是 1-2MB 的。
通常遞迴也不要遞迴的層次過多,很容易溢位。

思考題

1. 線上應用系統出現問題,怎麼快速定位系統哪塊資源問題

相關文章