一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - Java教程 - JAVA下單接口優化實戰TPS性能提高10倍

JAVA下單接口優化實戰TPS性能提高10倍

2021-06-19 10:48Sam哥哥 Java教程

今天小編就為大家分享一篇關于JAVA下單接口優化實戰TPS性能提高10倍,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧

概述

最近公司的下單接口有些慢,老板擔心無法支撐雙11,想讓我優化一把,但是前提是不允許大改,因為下單接口太復雜了,如果改動太大,怕有風險。另外開發成本和測試成本也非常大。對于這種有挑戰性的任務,我向來是非常喜歡的,因為在解決問題的過程中,可以學習到很多東西。

當時我只是知道下單接口慢,但是沒人告訴我慢在哪里,也即是說,哪些瓶頸導致下單接口慢了。其實沒人知道也沒關系的,因為我們可以通過壓測來找到具體的瓶頸。

下面會詳細介紹一下,在本次壓測中遇到的問題以及如何解決,期間用了什么工具。

用到的工具和環境

工具

  • jmeter
  • java自帶的jvisualvm
  • jmx
  • nmon

環境

  • 騰訊云mysql
  • 騰訊云2核4g的服務器1臺

找瓶頸

下單屬于寫接口,大部分情況下,瓶頸都出在db里,程序可能都在等待db鎖的釋放。為了驗證這個想法,我們可以使用jmeterjvisualvm來驗證一下。

為了監控服務器和服務器中java進程,我們需要開啟jmx,可以在java進程啟動的時候,添加如下幾個參數:

?
1
2
jmx_opts="-dcom.sun.management.jmxremote.port=7969 -dcom.sun.management.jmxremote -dcom.sun.management.jmxremote.authenticate=false -dcom.sun.management.jmxremote.ssl=false -djava.rmi.server.hostname=xx.xx.xx.xx"
nohup java ${jmx_opts} -jar xxxxx.jar

djava.rmi.server.hostname填寫java進程所在服務器的ip地址,-dcom.sun.management.jmxremote.port=7969是指定jmx監控端口的,這里是7969。

重新啟動進程后,打開本地的(我用的是window10)jvisualvm,添加jmx配置。配置成功后,可以點擊線程那個tab,因為我們要做線程dump,觀察線程的執行情況。

JAVA下單接口優化實戰TPS性能提高10倍

JAVA下單接口優化實戰TPS性能提高10倍

好了,現在我們可以使用jmeter來對下單接口進行壓測了??梢韵扔?0線程并發壓,執行時間是1分鐘。

JAVA下單接口優化實戰TPS性能提高10倍

在壓測的過程中,做一下線程dump,同時利用nmon觀察應用服務器cpu的負載情況。

JAVA下單接口優化實戰TPS性能提高10倍

負載很低,將線程并發調整到100后,cpu還是上不去,這樣的話,初步可以判斷,代碼里有鎖。
通過觀察dump文件,發現如下信息:

- locked <22f6e7f3> (a com.mysql.cj.core.io.readaheadinputstream)
- at com.sun.proxy.$proxy231.reduceskustock(unknown source)

觸發這個lock的業務代碼是reduceskustock方法。通過閱讀代碼,發現reduceskustock被包在一個大事務里面。

?
1
2
3
4
5
6
7
8
9
@transactional(rollbackfor = {exception.class})
 createorder() {
 //1、扣減庫存
 reduceskustock();
 //2、創建訂單
 insertorder();
 //3、其他寫操作
 。。。。
}

庫存記錄通常存在一張獨立的庫存表,由于創建訂單的方法,是一個大事務,這樣就會導致某條庫存記錄只有當整個createorder()方法執行完后,數據庫行鎖才會被釋放,在這個期間,其他線程是無法對這條庫存記錄進行寫操作的。因此我們可以在reduceskustock()中,再開一個事務,操作完這條庫存記錄后,趕緊釋放鎖,這樣應該可以提高一些性能。為了驗證是否是因為事務的原因導致下單接口慢,我們可以直接將createorder()方法的事務去掉,再壓測一下。

壓測結果發現,下單接口的tps提高了一倍,cpu也上去了不少,但是仍然不夠理想,代碼里,應該還有其他的鎖。再次做線程dump,又發現了一個鎖。

- locked <438be230> (a org.apache.http.pool.abstractconnpool$2)
- at org.apache.http.impl.client.closeablehttpclient.execute(closeablehttpclient.java:108)

導致鎖的代碼是httpclientexecute方法,該方法在執行的時候,一直在等待獲取http連接,通過查看源代碼,發現居然沒有使用連接池,醉了。趕緊加上如下代碼:

?
1
2
3
poolinghttpclientconnectionmanager pool = new poolinghttpclientconnectionmanager();
pool.setdefaultmaxperroute(400);
httpclient = httpclients.custom().setconnectionmanager(pool).build();

再次壓測后,發現代碼里已經沒有鎖了。tps提升了5倍。但是接下來還得做幾件事情:

1、打印下單接口的所有sql,然后逐一進行explain操作,看看有沒有全表掃描的語句或者沒用到索引的sql語句;
2、觀察下單接口執行的過程中,full gc發生的次數;
3、增加應用的mysql連接數;

好了,到了這地方,我們可以回到前面,來解決庫存問題了。由于老板說,不能大改,因此我就在reduceskustock方法上,再開一個事務。

?
1
2
@transactional(propagation = propagation.requires_new)
reduceskustock(){}

讓執行庫存操作的線程執行完后,趕緊釋放行鎖。這樣做也有個風險,就是庫存扣減成功后,下單失敗了。不過這種情況比較少,因為當時的下單接口中,大部分業務邏輯都在前面做好判斷了,到達插入訂單的代碼時,就只是單獨的insert了,除非數據庫掛了,不然不會出現下單失敗的情況。

在開發環境下,經過調優后,下單接口的tps提升了3倍左右,當然由于開發環境的數據庫和應用服務器都比較差,也會對tps有影響的。當時優化完后,在生產上進行了壓測,發現tps提升了10倍。

這個是下單接口的邏輯不能大改的情況下的優化方案,一般來說,庫存操作應該是單獨的服務,可以單獨優化的。而單純的下單邏輯也是可以優化的。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。如果你想了解更多相關內容請查看下面相關鏈接

原文鏈接:https://blog.csdn.net/linsongbin1/article/details/82656887

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲国产综合久久久无码色伦 | 五月最新女厕所高跟嘘嘘 | 久久久久久免费高清电影 | 99在线免费播放 | 国产精品www夜色影视 | 日本一卡二卡3卡四卡网站精品 | 2021年国内自拍 | 成人先锋| 福利视频导航大全 | 国产亚洲视频网站 | 99久久精品免费看国产一区二区 | 女色在线观看免费视频 | 久久国产精品人妻中文 | 国产欧美视频高清va在线观看 | 日韩精品欧美 | 8x在线永久成人影院 | 国产a片毛片 | 国产精品免费久久久久影院 | 国产探花视频在线观看 | 成人在线日韩 | x8x8国产在线观看2021 | 九九成人免费视频 | 国产成人理在线观看视频 | 天天干女人 | china中国xxxxfree| 高肉h护士办公室play | 青草悠悠视频在线观看 | 日本高清色视影www日本 | 亚洲视频在线免费看 | 国产在线视频资源 | 国产亚洲精品aaa大片 | 欧美成人在线影院 | 国产一区二区三区高清视频 | 亚洲国产福利精品一区二区 | 逼123| 国内精品91久久久久 | 99免费看| 91四虎国自产在线播放线 | tk白嫩玉足脚心vk | 日韩精品中文字幕久久 | 亚洲国产区中文在线观看 |