摘要:運行模式分種模式一般使用模式效率低對系統配置有一些比較高的要求確認的運行模式配置文件關鍵配置最大線程數默認是最小活躍線程數默認是最大的等待隊列個數,超過則請求拒絕默認值是,一般不改變。
前言
Tomcat作為Web應用的服務器,目前絕大多數公司都是用其作為應用服務器的,應用服務器的執行效率會影響系統執行,這里會講Tomcat怎樣進行配置能提高處理性能。另外必須提到對應的JVM參數的優化的一些經驗。
Tomcat運行模式分3種模式: bio,nio,apr 一般使用nio模式
bio效率低,apr對系統配置有一些比較高的要求
配置文件 server.xml
關鍵配置
maxThreads
最大線程數, 默認是200
minSpareThread
最小活躍線程數, 默認是25
maxQueueSize
最大的等待隊列個數,超過則請求拒絕默認值是Integer.MAX_VALUE ,一般不改變。在某些緊急狀態修復問題需要調整
連接器(Connector)
Connector是連接器,負責接收客戶的請求,以及向客戶端回送響應的消息。所以Connector的優化是重要部分。默認情況下 Tomcat只支持200線程訪問,超過這個數量的連接將被等待甚至超時放棄,所以我們需要提高這方面的處理能力。nio配置- server.xml
影響性能配置 protocol
org.apache.coyote.http11.Http11Protocol - 阻塞式的Java連接器enableLookups
org.apache.coyote.http11.Http11NioProtocol - 不阻塞Java連接器
org.apache.coyote.http11.Http11AprProtocol - APR / native 連接器
選擇不阻塞Java連接器
若是你想request.getRemoteHost()的調用履行,以便返回的長途客戶端的實際主機名的DNS查詢,則設置為true。設置為false時跳過DNS查找,并返回字符串的IP地址(從而提高性能)。默認場景下,禁用DNS查找
compression設置成on,開啟壓縮
禁用AJP鏈接器使用Nginx+tomcat的架構,用不著AJP協議,所以把AJP連接器禁用
server.xml注釋掉以下配置
優化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
jvm的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 的。
解決方法: 代碼中遞歸也不要遞歸的層次過多
思考題線上應用系統出現問題,怎么快速定位系統哪塊資源問題?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/76651.html
摘要:幾個死鎖場景兩個線程相互調用導致互相等待同步結束。線程為了檢測死鎖,它需要遞進地檢測所有被請求的鎖。思考題線程有哪些狀態這些線程大多處于什么樣的狀態分布我們可以稱系統運行是健康的。 前言 在上一期Tomcat優化中,針對JVM相關主要參數做過一定說明,這一期主要介紹進行一些概念及經驗。后面分章節去講述相關工具的基本使用。 優化優先級 整體來講,系統優化應先優化架構及代碼,來解決具體功能...
閱讀 2078·2023-04-25 17:57
閱讀 1284·2021-11-24 09:39
閱讀 2482·2019-08-29 16:39
閱讀 3312·2019-08-29 13:44
閱讀 3117·2019-08-29 13:14
閱讀 2313·2019-08-26 11:36
閱讀 3810·2019-08-26 11:00
閱讀 948·2019-08-26 10:14