接口监控_java应用监控之利用cat接口性能优化,每一次都是血的教训
之前幾篇文章對cat進行了簡介、安裝部署、代碼埋點,今天分享一下如何利用cat幫助我們做接口優化。
為什么要接口性能優化?
1.用戶體驗差:接口訪問速度慢、如果一個頁面打開需要好幾秒,用戶可能在頁面沒有完全打開時,就關掉頁面離開了,造成用戶流失,通過性能優化,減少服務器響應時長,可提高用戶體驗,較少用戶的流失。
2.雪崩效應:接口訪問速度慢,會帶來雪崩效應,在微服務時代,一個功能頁面可能需要調用多個服務接口,如果某一個接口響應速度慢,會導致調用這個接口的服務也變得很慢,最后會導致所有的服務整體變慢。
什么樣的接口值得優化?
1.調用頻繁且調用時間長的接口,值得優化。接口a被調用10000次,平均調用時長500ms,接口b被調用10次,平均調用時長3秒。優化接口a,假設從500ms優化到300ms,每一次節省200ms,總體優化時長是200萬毫秒。優化接口b,即使從3秒優化到100ms,總體優化時長也只有29000毫秒。碰到這種情況建議優化接口a,性價比更高,更值得優化。
2.調用次數少,但每次調用都異常(如超時無返回),這樣的接口也必須優化。
如何使用cat定位需要優化的接口?
1.挑選性價比高的接口(Transaction)
如上圖選擇的是cache-service應用,CacheService.mutliExecute調用最頻繁,調用72萬次,調用時長也比較多,可以作為被優化的接口。
2.通過條件篩選,提供Long-url、Long sql、Long sevice、Long call篩選條件,可以自行組合,調整時間長度。(Promblem)
3.調用出錯,必須要修改處理(promblem)
接口如何優化?
1.查看調用鏈,定位哪個方法調用時間長
通過上圖,發現接口存在循環調用,優化方案:調用批量操作接口,減少接口調用次數。
2.慢sql優化方法
第一步:explain查看sql執行計劃,確認sql是否走索引。
第二步:確認數據庫表是否建立索引,如果沒有索引,創建合適的索引,保持最左原則。
第三步:如果存在索引,沒有索引,分析其中原因
第四步:如果sql走了索引,依然很慢,緩存中間結果(異構一張中間表或者將結果緩存到redis中)
具體優化例子:
1.查詢庫存接口,數據庫表存在索引,而沒有使用到索引,是因為數據庫表屬性類型是varchar,sql中使用了in,然而傳參的時候使用的是數值類型,導致發生了數據類型轉換,導致沒有走索引。優化方案,修改傳參類型,使用字符串進行傳參,優化之后從300ms降低到60ms。(如果數據庫中是數值類型,參數使用字符串類型,即便發生了類型轉換,依然可以走索引,很奇怪)。sql中使用in,作為多條件查詢,有時候能走索引,有時候不能走索引,當in中只有1個值的時候,一定會走索引,當in中查詢的結果,達到所有記錄的一定比例的時候,不會走索引。
2.大表分頁優化,定時任務,需要對大表分頁查詢,可以使用子查詢的方式進行優化。舉例:商品表100萬條記錄,需要每天定時更新商品的銷量。一般做法使用多線程,每個線程處理200條數據
select * from item limit 900000,200越往后執行,時間會越長,因為mysql需要定位前90萬條記錄,之后再取出后面的200條數據,因為沒有走索引,所以會比較慢。
優化方案一:利用子查詢
select * from item i,(select id from item limit 900000,200) as g where g.id = i.id因為可以走索引,而且子查詢使用到了覆蓋索引,不需要進行第二次查詢,可以提高查詢速度。
優化方案二:主鍵Id區間法
前提條件表結構中存在自增長主鍵。取出表的最小值和最大值,將這兩個值進行分段,每個線程處理一個區間。這樣查詢可以利用主鍵索引。
select * from item where id in (1,2,3,4,5,..200)3.Jvm優化
查詢庫存優化之后,走了索引之后,的確快了很多,通過cat發現,庫存服務有兩個應用實例,有一個實例接口非常快,一個很慢,通過cat的Heartbeat發現慢的那臺機器存在full gc,每隔一段時間就發生一次fullgc。
查看jvm的Gc命令
jstat -gcutil pid 2000如果存在大量的YGC可以通過jmap命令定位哪些對象創建的多,然后進行代碼優化,盡量減少對象的創建。或者調整jvm參數,增加Eden區的大小。如果存在大量的fullGC這種情況要引起注意,因為一次fullGC會消耗時間比較長,嚴重影響性能,需要調整jvm參數。
jmap -histo pid | grep com.galaxy(包路徑)top命令查看cpu,內存等使用情況
topcpu使用過高優化方案
首先顯示線程列表:
ps -mp pid -o THREAD,tid,time找到了耗時最高的線程28802,占用CPU時間快兩個小時了!
其次將需要的線程ID轉換為16進制格式:
printf "%x" tid最后打印線程的堆棧信息:
jstack pid |grep tid -A 30無法獲取數據庫連接
可能是因為數據庫在執行修改表結構造成了鎖表
select * from information_schema.processlist where db = 'item' and state like '%lock%'需要對查出來的進程進行kill掉。可以通過命令
kill 進程Id
獲取redis連接失敗,可能存在某些地方沒有釋放連接,可通過jstack命令進行定位
jstack –l pid > jstack.txt下載jstack.txt進行分析,搜索Lock關鍵詞,可以方便定位問題。最好的方法,對連接的操作,進行統一的封裝,不留給開發人員犯錯的機會。
遇到問題不可怕,可怕的是同樣的問題重復犯。將開發過程中遇到的問題,記錄下來,總結定期復盤,可避免重犯同樣的錯誤。吃一塹,長一智,特此記錄下來和大家分享,希望對你有所幫助。
總結
以上是生活随笔為你收集整理的接口监控_java应用监控之利用cat接口性能优化,每一次都是血的教训的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: windows配置Python多版本共存
- 下一篇: win7 其他用户当前已登录到此计算机,