摘要:指標虛擬內存已使用的大小,如果大于,表示你的機器物理內存不足了每秒從磁盤讀入虛擬內存的大小,如果這個值大于,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。每秒虛擬內存寫入磁盤的大小,如果這個值大于,同上,單位為。
原理剖析(第 013 篇)應用系統性能調優
-
一、大致介紹1. 本人接手的一個打車系統,因為出現了一次響應十分緩慢的情況,因此才有了應用調優的篇章; 2、由于過程中可能沒有闡述的太清楚,如想詳細了解可以留言之類的,希望其中的點點滴滴對大家有所幫助;二、調優背景
在某一個月黑風高的夜晚,21點多以后,許許多多的小伙伴都相繼下班了,然后大家開始習慣性的掏出自己心愛的手機, 點擊了公司的打車應用App,大概在 21:00 ~ 21:30 期間還風平浪靜的,但是就在 21:30 ~ 21:40 的樣子,突然打車應用App 響應非常緩慢,App頁面上的菊花一直轉個不停,直到App請求超時菊花才消失, 然后用戶還是不停的點擊App,因為這個時候 小伙伴們都急著回家,都相繼不停的請求下單,獲取詳情等頁面操作,體驗非常不友好; 因為出現了這么一次情況,雖然沒有給用戶沒有給公司帶來什么損失,但是該現象從側面已經反應出了系統某些方面的 問題,或許系統參數需要優化一番,或許系統設計交互需要優化一番,或許等等等的可能,才有了后續系統調優的歷程。三、計劃分析
1、流程相關分析優化:看看哪些流程可以同步轉異步處理,App哪些請求可以合并起來,Server哪些業務場景需要補償機制等。 2、數據庫相關分析優化:哪些Sql耗時較長,哪些方法可以去除事務且去除事務后的帶來的問題場景分析,數據庫連接池參數 是否合理,數據庫本身相關參數的閾值情況的一些綜合考慮; 3、內存使用情況分析優化:新老年代內存使用率及回收情況,CPU使用率,磁盤使用率,swap區使用情況, 線程dump,堆dump。 4、JVM參數分析調優:YGC的平均耗時,YGC的平均間隔,FGC的平均耗時,FGC的平均間隔等等,根據具體情況反映具體問題; 5、TCP/Tomcat參數分析調優:這個得根據實際壓測情況來相應評估是否需要調整;四、Linux命令相關查看指標 4.1 CPU 指標
1、 vmstat n m 每n秒采集一次,一共采集m次,r:表示運行隊列,r值一般負載超過了3就比較高,超過了5就高,超過了10就不正常了; bi和bo一般都要接近0,不然就是IO過于頻繁 ) [root@svr01]$ vmstat 1 3 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 206944 633564 29876 1252176 0 0 10 27 0 0 1 1 98 0 0 0 0 206944 634232 29876 1252192 0 0 0 0 811 1504 1 1 98 0 0 0 0 206944 634480 29876 1252264 0 0 0 0 951 1458 6 1 93 0 0 2、 uptime 最近1分鐘,5分鐘,15分鐘的系統平均負載, <=3 則系統性能較好。 <=4 則系統性能可以,可以接收。 >5 則系統性能負載過重,可能會發生嚴重的問題,那么就需要擴容了,要么增加核 [root@svr01]$ uptime 21:27:44 up 207 days, 11:15, 1 user, load average: 26.45, 16.76, 7.50 3、 top 主要看us和sy,其中us<=70,sy<=35,us+sy<=70說明狀態良好, 同時可以結合idle值來看,如果id<=70 則表示IO的壓力較大。4.2 Memory 指標
1、 vmstat swpd:虛擬內存已使用的大小,如果大于0,表示你的機器物理內存不足了 每秒從磁盤讀入虛擬內存的大小,如果這個值大于0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。 so:每秒虛擬內存寫入磁盤的大小,如果這個值大于0,同上,單位為KB。 [root@svr01]$ vmstat 1 3 procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 206944 633564 29876 1252176 0 0 10 27 0 0 1 1 98 0 0 0 0 206944 634232 29876 1252192 0 0 0 0 811 1504 1 1 98 0 0 0 0 206944 634480 29876 1252264 0 0 0 0 951 1458 6 1 93 0 04.3 Disk 指標
1、 df Use%:已使用占比,Use% <= 90% 表示還勉強接受正常 [root@svr01]$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/mapper/VolGroup00-LVroot 17737040 4286920 12542448 26% / tmpfs 1893300 0 1893300 0% /dev/shm /dev/sda1 194241 127341 56660 70% /boot /dev/mapper/VolGroup00-LVhome 487652 2348 459704 1% /home /dev/mapper/VolGroup00-LVcloud 3030800 260440 2613076 10% /opt/cloud /dev/mapper/VolGroup00-LVtmp 8125880 18724 7687728 1% /tmp /dev/mapper/VolGroup00-LVvar 25671996 848996 23512280 4% /var /dev/mapper/VolGroup1-LVdata1 41149760 33707952 5344864 87% /wls/applogs4.4 Disk IO 指標
1、 sar -d 1 1 查看磁盤報告 1 1 表示間隔1s,運行1次 如果svctm的值與await很接近,表示幾乎沒有I/O等待,磁盤性能很好,如果await的值遠高于svctm的值, 則表示I/O隊列等待太長,系統上運行的應用程序將變慢。 如果%util接近100%,表示磁盤產生的I/O請求太多,I/O系統已經滿負荷的在工作,該磁盤請求飽和,可能存在瓶頸。 idle小于70% I/O壓力就較大了,也就是有較多的I/O。 [root@svr01]$ sar -d 1 1 Linux 2.6.32-642.6.2.el6.x86_64 (SHB-L0044551) 07/20/2018 _x86_64_ (1 CPU) 03:00:23 PM DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util 03:00:24 PM dev252-0 23.00 808.00 80.00 38.61 9.88 375.35 43.48 100.00 03:00:24 PM dev252-16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 03:00:24 PM dev253-0 4.00 448.00 0.00 112.00 1.11 222.00 249.50 99.80 03:00:24 PM dev253-1 50.00 400.00 0.00 8.00 24.40 523.20 20.00 100.00 03:00:24 PM dev253-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 03:00:24 PM dev253-3 3.00 32.00 0.00 10.67 0.99 242.33 331.67 99.50 03:00:24 PM dev253-4 0.00 0.00 0.00 0.00 1.61 0.00 0.00 100.00 03:00:24 PM dev253-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 03:00:24 PM dev253-6 3.00 0.00 24.00 8.00 1.30 393.67 261.33 78.40 Average: DEV tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util Average: dev252-0 23.00 808.00 80.00 38.61 9.88 375.35 43.48 100.00 Average: dev252-16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: dev253-0 4.00 448.00 0.00 112.00 1.11 222.00 249.50 99.80 Average: dev253-1 50.00 400.00 0.00 8.00 24.40 523.20 20.00 100.00 Average: dev253-2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: dev253-3 3.00 32.00 0.00 10.67 0.99 242.33 331.67 99.50 Average: dev253-4 0.00 0.00 0.00 0.00 1.61 0.00 0.00 100.00 Average: dev253-5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: dev253-6 3.00 0.00 24.00 8.00 1.30 393.67 261.33 78.404.5 Network IO 指標
1、 netstat -nat |awk "{print $6}"|sort|uniq -c|sort -rn 在不考慮系統負載、CPU、內存等情況下,netstat監控大量ESTABLISHED連接與Time_Wait連接 [root@svr01]$ netstat -nat |awk "{print $6}"|sort|uniq -c|sort -rn 265 TIME_WAIT 45 ESTABLISHED 38 CLOSE_WAIT 18 LISTEN 8 FIN_WAIT2 2 SYN_SENT 1 Foreign 1 established)五、一些關于統計的量化指標
注意:有些命令通用,有些是我根據系統的日志文件格式利用awk/sed兩個命令結合寫出來的。 1、netstat -nat |awk "{print $6}"|sort|uniq -c|sort -rn ( 查看TCP連接狀態 ) 2、netstat -n|grep TIME_WAIT|awk "{print $5}"|sort|uniq -c|sort -rn|head -n20( 查找較多time_wait連接 ) 3、netstat -anlp|grep tcp |awk "{print $5}" |awk -F":" "{print $1}" |uniq -c |sort -nr | head -n3( 查出訪問靠前的IP地址 ) 4、cat hmilyylimh_sql.log | awk "{print $6}" | awk -F"ms" "{print $1}" | awk -F"=" "{print $2 | "sort -r -n" }" | head -n5( 查詢sql文件中耗時最高的前5個耗時數據值 ) 5、cat hmilyylimh_supp.log | awk "{print $10}" | awk -F"timeConsuming=" "{print $2 }" | awk -F"ms" "{print $1 | "sort -r -n" }" | head -n5( 查看supp文件中耗時最高的前5個耗時數據值 ) 6、cat hmilyylimh_sql.log | grep "sql:=" | awk "{print $5}" | uniq -c | sort -rn | head -n2( 查詢sql文件總共打印了多少條SQL日志 ) 7、cat hmilyylimh_sql.log | grep "NormalTimeConsuming" | awk "{print $5}" | uniq -c | sort -rn | head -n2( 查看sql文件成功執行了多少條SQL日志 ) 8、cat hmilyylimh_sql.log | grep "BadTimeConsuming" | awk "{print $5}" | uniq -c | sort -rn | head -n2( 查看sql文件失敗或者異常執行了多少條SQL日志 ) 9、cat hmilyylimh_supp.log | grep "sendReqSupp start"| awk "{print $6$7$8}" | uniq -c | sort -nr | head -n2( 查詢supp文件sendReqSupp start字符串出現的次數 ) 10、lsof -n | awk "{print $1,$2}" | sort | uniq -c | sort -nr | head -n10( 統計持有各個進程持有句柄數最高的10個 ) 11、lsof -n | awk "{print $1,$2}" | sort | uniq -c | sort -nr | awk "{ sum+=$1 };END { print sum } "( 計算所有進程持有句柄數的總和,ulimit -n命令查看最大句柄數 ) 12、lsof | awk "NF == 9 { print $0}" | sort +6 -7nr | head -n10( 查看系統打開的大文件列表 ) 13、top -b -n 1 | grep -E "Cpu(s)|Mem|Swap"( 一次性查出系統當前的CPU、內存、交換區的情況 ) 14、iostat -p sda | awk -F"Device" "{ print $1 }"( 查看cpu的統計信息(平均值) ) 15、cat access_log.`date +%Y%m%d`.txt | awk "{print $6}" | uniq -c | sort -k2 -r | head -n10( 統計每秒請求并發,按照時間降序排列 ) 16、cat access_log.`date +%Y%m%d`.txt | awk "{print $6}" | uniq -c | sort -rn | head -n10( 統計每秒并發,按照并發量降序排列 ) 17、cat access_log.`date +%Y%m%d`.txt | awk "{ sum+=$NF }; END { print sum*2/8/1024/1024, "M" }"( 查看訪問hmilyylimh服務器每天的總流量 ) 18、cat gc.log | tail -n20|awk "{print $4}"| awk -F"->" "{print $1, $2, $3 }"| awk -F"(" "{print $1, $2, $3}" | awk -F")" "{print $1}" | awk -F"K" "{print $1/$3*100, "% used -> " ,$2/$3*100, "% used " , 100-$2/$3*100, "% free ", $3/1024, "M total --- 新生代" }"( 查看gc指標,新生代最后n條記錄的新生代內存變化率 ) 19、cat gc.log | tail -n20 | awk "{print $7}" | awk -F"->" "{print $1, $2, $3 }" | awk -F"(" "{print $1, $2, $3}" | awk -F")" "{print $1}" | awk -F"K" "{print $1/$3*100, "% used -> " ,$2/$3*100, "% used " , 100-$2/$3*100, "% free ", $3/1024, "M total --- 堆內存" }"( 查看最后10條GC日志的堆內存已使用轉化率 ) 20、cat /etc/sysctl.conf | grep "tcp_"( 查看TCP參數設置信息 ) 21、cat hmilyylimh.log | awk "{if($2>"15:17:00.236") print $0}" | grep "max_user_connections" | wc -l( 查看具體時間點后某個字符串出現的次數 )六、系統常用計數器命令
1、echo "<<<<<<<<<<<<<< 線程阻塞等待計數: "`less hmilyylimh_error.log | grep "with callerRunsPolicy" | wc -l`", ""db事務嵌套鎖AcquireLock計數: "`less hmilyylimh_error.log | grep "CannotAcquireLockException" | wc -l`", ""創建事務異常計數: "`less hmilyylimh_error.log | grep "CannotCreateTransactionException" | wc -l`", ""db連接池溢出計數: "`less hmilyylimh_error.log | grep "more than "max_user_connections"" | wc -l`", ""Pool Empty計數: "`less hmilyylimh_error.log | grep "Unable to fetch a connection" | wc -l`" >>>>>>>>>>>>>>" 2、echo "<<<<<<<<<<<<<< UnknownHostException計數: "`less hmilyylimh_error.log | grep "UnknownHostException" | wc -l`", ""ConnectionPoolTimeout計數: "`less hmilyylimh_error.log | grep "ConnectionPoolTimeout" | wc -l`", ""ConnectException計數: "`less hmilyylimh_error.log | grep "ConnectException" | wc -l`", ""ConnectTimeoutException計數: "`less hmilyylimh_error.log | grep "ConnectTimeoutException" | wc -l`", ""SocketTimeoutException計數: "`less hmilyylimh_error.log | grep "SocketTimeoutException" | wc -l`", ""OtherException計數: "`less hmilyylimh_error.log | grep "OtherException" | wc -l`" >>>>>>>>>>>>>>" 3、echo "<<<<<<<<<<<<<< Sql耗時最高的前5個數值: "`cat hmilyylimh_sql.log | awk "{print $6}" | awk -F"ms" "{print $1}" | awk -F"=" "{print $2 | "sort -r -n" }" | head -n5`", ""Supp耗時最高等待前5個數值: "`cat hmilyylimh_supp.log | awk "{print $10}" | awk -F"timeConsuming=" "{print $2 }" | awk -F"ms" "{print $1 | "sort -r -n" }" | head -n5`" >>>>>>>>>>>>>>" 4、echo "<<<<<<<<<<<<<< Http請求耗時最高前10個數值: "`less hmilyylimh.log | grep "timeConsuming=" | awk "{print $9}" | awk -F"=" "{print $2}" | awk -F"ms" "{print $1 | "sort -r -n" }" | head -n10`" >>>>>>>>>>>>>>"七、流程相關分析優化
1. 通過 access_log.txt 日志分析,在特定時間段內,將請求至系統的 url 分組計數,最后會出一個根據url調用次數的排序; 2、針對請求次數數一數二的url接口,在分析完業務場景后,決定將高頻率的接口優化成同步轉異步; 3、然而想查看Server端每個Http請求的耗時時間,卻發現沒有相關功能點統計,于是乎又新增切面Aspect來統計Client請求至 Server的耗時統計日志,然后通過 less,grep,awk 命令來分析耗時最高的url請求,后續可做成監控及時發現長耗時請求; 4、同樣發現請求下游系統也沒有相關耗時統計,因此依葫蘆畫瓢再次新增請求下游系統切面來統計耗時情況; 5、在后續的壓測過程中,效果顯著,單臺服務器的TPS提升了3倍,而且在壓測過程不斷打出線程dump, 堆dump日志,然后 重點將 hmilyylimh_20180716-143726.threads 放到網頁中分析,結果發現一個比較嚴重的問題,Log4J 1.x blocked 問題,總計大概有90多個線程在等待同一把鎖。于是乎將應用的 log4j 1.x 版本升級至 log4j 2.x 版本。但是呢,官方 明確說明:Log4j 2.4 and greater requires Java 7, versions 2.0-alpha1 to 2.3 required Java 6。因此我們就只好 采用了2.3版本。 6、后面還考慮了將請求下游系統的日志做成了異步打印,效果更佳; 7、通過和前端溝通,將一些請求進行了進行了聚合處理返回給前端,在某種程度上友好的提升了交互體驗; 8、針對支付場景的支付狀態同步新增了補償機制,后臺主動查詢下游系統訂單的支付狀態,最大力度的保證用戶看到的支付 狀態是準實時的; 9、針對Http的工具類,根據業務的實際情況定制一套超時參數,盡量減少Http連接長時間被Hold住不釋放,必要時Http請求 工具類做相應的嘗試次數控制; 10、最后的壓測也比較簡單,通過寫程序操控狀態扭轉,將整個打車流程走完,程序只需要傳入人數來壓測系統最高負荷; 經過后續壓測顯示,日志鎖顯然不存在了,最后一次統計的數據得知TPS相比最初提升了至少5倍以上,由此可見流程的優化 和日志的優化對于系統的性能提升有很大的幫助;八、數據庫相關分析優化
1、通過收集產線出問題時刻的數據庫指標( max_used_connections/max_user_connections/max_connections ),除了這三個 參數意外,還收集了數據庫連接超時時間,出問題時刻數據庫實例前后幾個小時的時序分析圖; 2、在測試環境壓測情況下,而后臺應用的連接池的參數配置為: 嘗試步驟一: (max_connections=160, max_user_connections=80, 兩臺1核2G的服務器) tomcat.initialSize=25 tomcat.validationInterval=25000 tomcat.maxActive=85 tomcat.minIdle=25 tomcat.maxIdle=25 結論:系統部署重啟后直接啟動不起來,報的什么錯已經忘記了,然后繼續調整連接池參數; 嘗試步驟二: (max_connections=160, max_user_connections=80, 兩臺1核2G的服務器) tomcat.initialSize=12 tomcat.validationInterval=25000 tomcat.maxActive=85 tomcat.minIdle=12 tomcat.maxIdle=12 結論:系統能正常啟動,相對于步驟一來說,連接池的合理配置非常重要,但是在壓測情況下發生了一些異常; --- Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: User hmily already has more than "max_user_connections" active connections,于是乎繼續后續步驟; 嘗試步驟三: (max_connections=160, max_user_connections=80, 兩臺1核2G的服務器) tomcat.initialSize=12 tomcat.validationInterval=25000 tomcat.maxActive=80 tomcat.minIdle=12 tomcat.maxIdle=12 結論:相對于步驟二來說,異常還是有一些,數據庫的 160 剛剛等于 tomcat.maxActive * 2 = 160, 但是又引發了另外一個異常: Cause: org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-nio-0.0.0.0-40009-exec-91] Timeout: Pool empty. Unable to fetch a connection in 5 seconds, none available[size:40; busy:3; idle:37; lastwait:5000]; 于是乎繼續后續步驟; 嘗試步驟四: (max_connections=160, max_user_connections=80, 兩臺1核2G的服務器) tomcat.initialSize=12 tomcat.validationInterval=25000 tomcat.maxActive=80 tomcat.minIdle=12 tomcat.maxIdle=12 結論:相對于步驟二來說,異常還是有一些,數據庫的 160 剛剛等于 tomcat.maxActive * 2 = 160, 但是還是會引發了另外一個異常: Cause: org.apache.tomcat.jdbc.pool.PoolExhaustedException: [http-nio-0.0.0.0-40009-exec-91] Timeout: Pool empty. Unable to fetch a connection in 5 seconds, none available[size:40; busy:3; idle:37; lastwait:5000]; 于是乎繼續后續步驟; 在這一步,我們無法計算每個SQL的耗時情況,于是集成了SqlMapClientTemplate類,在SqlMapClientTemplate的擴展類 中針對queryForObject、queryForList、update、delete主流的方法進行了before/after/finally增強處理打印SQL耗時; 嘗試步驟五: (max_connections=160, max_user_connections=80, 兩臺1核2G的服務器) tomcat.initialSize=12 tomcat.validationInterval=25000 tomcat.maxActive=40 tomcat.minIdle=12 tomcat.maxIdle=12 結論:在步驟四中,通過將maxActive改回40, 且對耗時的SQL進行優化處理,同時對一些不常變化的SQL配置進行了緩存 處理,這樣一來在壓測高并發的情況下,所有情況全部有所好轉,一切正常自如; 但是我遠不滿足于此,然后我又開始調整連接池參數配置; 嘗試步驟六: (max_connections=320, max_user_connections=160, 兩臺1核2G的服務器) tomcat.initialSize=12 tomcat.validationInterval=25000 tomcat.maxActive=80 tomcat.minIdle=12 tomcat.maxIdle=12 結論:之前出現的異常也沒有了,于是我綜合以上我的各種嘗試,實際測試總結了一些關于個人理解的參數配置; 3、小結: 對于連接池這塊,想必大家也同樣都是從網上摘抄下來的配置,雖然調整后的配置不一定是最佳的,但是對整個應用沒有 起到副作用的話,那就是對應用最適合的配置。而且大家在配置的時候,還得綜合考慮服務器水平擴展后對數據庫的一個壓力 情況,調整的時候一定要參照數據庫實例的參數配置來綜合考慮衡量應用的參數配置。 #初始化連接: 連接池啟動時創建的初始化連接數量 tomcat.initialSize=12 -- 原因:線程快照圖最小連接數為22,目前由于業務量大,僅僅只是2臺服務器,考慮到后續的業務還會繼續擴大, 因為該參數不適宜調整的太高,根據實際情況最后調整為12。 #避免過度驗證,保證驗證不超過這個頻率——以毫秒為單位 tomcat.validationInterval=25000 -- 原因:數據庫的連接超時時間是29秒,我們盡可能小于數據庫的連接超時時間 #最大活動連接: 連接池在同一時間能夠分配的最大活動連接的數量,如果設置為非正數則表示不限制 tomcat.maxActive=50 -- 原因:線程快照圖的最大連接數為82,目前產線只有2臺服務器,最大也就是 50 * 2 = 100,還遠遠小于 max_user_connections數值,最初是滴測試情況調整的為40,而產線的服務器性能絕對比測試環境好,綜合評估定位50。 #最小空閑連接: 連接池中容許保持空閑狀態的最小連接數量, 低于這個數量將創建新的連接, 如果設置為0則不創建.默認與initialSize相同 tomcat.minIdle=12 -- 原因:考慮和initialSize調整為一樣的 #最大空閑連接: 連接池中容許保持空閑狀態的最大連接數量, 超過的空閑連接將被釋放, 如果設置為負數表示不限制 tomcat.maxIdle=12 -- 原因:考慮和minIdle一樣九、內存使用情況分析優化
1、通過 awk 命令分析gc日志文件,發現老年代還有較多的空間可以利用,于是就是看看哪些是可以不經常變化的配置,盡量 減少數據庫IO的操作,最大程度先去讀取緩存,緩存沒有再去從數據庫中加載數據。 2、在壓測的過程中,盡量多一些headDump文件,然后通過 eclipse 工具來分析看看都有哪些大對象,也沒有發現任何有疑點 的地方,于是反查代碼,在一些定時任務需要加載大量數據的地方,當加載出來的數據用完之后直接手動釋放,盡快讓垃圾 回收期回收內存。 3、還有一點就是,在一些后臺定時輪詢的任務中,有些任務需要通過for循環來處理一些任務,這個時候我們可以每循環一次 或者循環數次之后通過調用Thead.sleep(xxx)休眠一下,一是可以緩沖一下IO高密度的操作,還有就是讓出CPU時間片, 讓有些緊急的任務可以優先獲取CPU執行權。 4、做完這些后,壓測后通過GC日志分析,老年代內存相比未優化前多了一些,但是性能吞吐率卻大大的得到了提高,磁盤IO 的TPS也在一定程度上降低了。十、JVM參數分析調優
1、為了應對將來的高業務量,目前需要擴容服務器,將2臺服務器擴容至4臺服務器,然后將服務器由2核4G升級成為4核8G。 因此在升級過程中對于參數的調整也存在了一定的迷惑期。 2、JVM參數的調整測試過程一兩句話也說不清,這里我就講解一下大致的思路: ? YGC的平均耗時,YGC的平均間隔,可以通過GC日志完整分析出來,根據實際情況是否需要調整堆大小,年輕代占比,存活區占比; ? FGC的平均耗時,FGC的平均間隔,同樣可以通過GC日志完整分析出來,重點關注FGC耗時,想辦法調整堆大小,年輕代占比,存活區占比,垃圾回收器方式; ? S2區的使用占比,如果S2占比為0,且YGC平均耗時也在40ms以內的話,也沒有FGC,這也算是相對比較理想的情況; ? S2區滿的話,FGC頻繁或者GC效果很差時建議調整堆大小,還得不到改善就要開發分析實際Heap消耗的對象占比了; 3、最后附上我的4核8G的JVM參數情況如下: -Xms2048M -Xmx2048M -Xss256k -XX:NewSize=512m -XX:MaxNewSize=512m -XX:SurvivorRatio=22 -XX:PermSize=256m -XX:MaxPermSize=512m -XX:+UseParNewGC -XX:ParallelGCThreads=4 -XX:+ScavengeBeforeFullGC -XX:+CMSScavengeBeforeRemark -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=60 -XX:CMSInitiatingPermOccupancyFraction=70 -XX:+PrintGCApplicationConcurrentTime -XX:+PrintHeapAtGC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=logs/oom.log -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -verbose:gc -Xloggc:logs/gc.log -Djava.net.preferIPv4Stack=true 4、GC優化的一點建議: ? Minor GC 執行非常迅速 ( 建議 50ms 以內 ) ? Minor GC 沒有頻繁執行 ( 建議大約 10s 執行一次 ) ? Full GC 執行非常迅速 ( 建議 1000ms 以內 ) ? Full GC 沒有頻繁執行 ( 建議大約 10min 執行一次 )十一、TCP/Tomcat參數分析調優
1、在測試壓測過程中,由于很大提升系統應用的請求并發,因此需要調整Tomcat中相關的參數,maxThreads、acceptCount (最大線程數、最大排隊數),也就是說需要查看 tomcat的Connector、Executor 所有屬性值,但產線本人并未做相應調整; 2、在壓測過程中,發現大量的TIME-WAIT的情況,于是根據實際調整系統的TCP參數,在高并發的場景中,TIME-WAIT雖然會峰 值爬的很高,但是降下來的時間也是非常快的,主要是需要快速回收或者重用TCP連接。 3、最后附上我的4核8G的TCP參數情況如下: vim /etc/sysctl.conf #編輯文件,加入以下內容: net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.tcp_fin_timeout = 30 #然后執行 /sbin/sysctl -p 讓參數生效。十二、小結
總而言之,經過這一系列的分析調優下來,對于系統來說,應用的系統性能提升相當可觀,同時也在優化的過程中建立起了 一套自己獨有的思考方式,雖說目前優化下來的這套配置并不是最完美的,但是它確實最適合系統的。 以上這些數據值僅供參考,如果大家有更好的方式或者更優雅的調優方式,也歡迎大家一起來多多討論。十三、下載地址
https://gitee.com/ylimhhmily/SpringCloudTutorial.git
SpringCloudTutorial交流QQ群: 235322432
SpringCloudTutorial交流微信群: 微信溝通群二維碼圖片鏈接
歡迎關注,您的肯定是對我最大的支持!!!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/77121.html
摘要:本文會以引出問題為主,后面有時間的話,筆者陸續會抽些重要的知識點進行詳細的剖析與解答。敬請關注服務端思維微信公眾號,獲取最新文章。 原文地址:梁桂釗的博客博客地址:http://blog.720ui.com 這里,筆者結合自己過往的面試經驗,整理了一些核心的知識清單,幫助讀者更好地回顧與復習 Java 服務端核心技術。本文會以引出問題為主,后面有時間的話,筆者陸續會抽些重要的知識點進...
摘要:理解內存模型對多線程編程無疑是有好處的。干貨高級動畫高級動畫進階,矢量動畫。 這是最好的Android相關原創知識體系(100+篇) 知識體系從2016年開始構建,所有的文章都是圍繞著這個知識體系來寫,目前共收入了100多篇原創文章,其中有一部分未收入的文章在我的新書《Android進階之光》中。最重要的是,這個知識體系仍舊在成長中。 Android 下拉刷新庫,這一個就夠了! 新鮮出...
閱讀 2762·2021-11-16 11:45
閱讀 1671·2021-09-26 10:19
閱讀 2063·2021-09-13 10:28
閱讀 2823·2021-09-08 10:46
閱讀 1550·2021-09-07 10:13
閱讀 1547·2019-08-30 13:50
閱讀 1386·2019-08-30 11:17
閱讀 1465·2019-08-29 13:18