[轉]10+倍性能提高全過程--優酷帳號綁定淘寶帳號的TPS從500到5400的優化歷程

摘要: # 10+倍性能提高全過程--優酷帳號綁定淘寶帳號的TPS從500到5400的優化歷程 ## 背景說明 > 2016年的雙11在淘寶上買買買的時候,天貓和優酷土豆一塊兒作了聯合促銷,在天貓雙11當天購物滿XXX元就贈送優酷會員,這個過程須要用戶在優酷側綁定淘寶帳號(登陸優酷、提供淘寶帳號,優酷調用淘寶API實現兩個帳號綁定)和贈送會員並讓會員權益生效(看收費影片、免廣告等等) >html

10+倍性能提高全過程--優酷帳號綁定淘寶帳號的TPS從500到5400的優化歷程

背景說明

2016年的雙11在淘寶上買買買的時候,天貓和優酷土豆一塊兒作了聯合促銷,在天貓雙11當天購物滿XXX元就贈送優酷會員,這個過程須要用戶在優酷側綁定淘寶帳號(登陸優酷、提供淘寶帳號,優酷調用淘寶API實現兩個帳號綁定)和贈送會員並讓會員權益生效(看收費影片、免廣告等等)java

這裏涉及到優酷的兩個部門:Passport(在上海,負責登陸、綁定帳號,下文中的優化過程主要是Passport部分);會員(在北京,負責贈送會員,保證權益生效)git

在雙11活動以前,Passport的綁定帳號功能一直在運行,只是沒有碰到過大促銷帶來的挑戰程序員


會員部分的架構改造

  • 接入中間件DRDS,讓優酷的數據庫支持拆分,分解MySQL壓力
  • 接入中間件vipserver來支持負載均衡
  • 接入集團DRC來保障數據的高可用
  • 對業務進行改造支持Amazon的全鏈路壓測

主要的壓測過程

screenshot.png

上圖是壓測過程當中主要的階段中問題和改進,主要的問題和優化過程以下:github

- docker bridge網絡性能問題和網絡中斷si不均衡 (優化後:500->1000TPS) - 短鏈接致使的local port不夠 (優化後:1000-3000TPS) - 生產環境snat單核致使的網絡延時增大 (優化後能達到測試環境的3000TPS) - Spring MVC Path帶來的太高的CPU消耗 (優化後:3000->4200TPS) - 其餘業務代碼的優化(好比異常、agent等) (優化後:4200->5400TPS) 

優化過程當中碰到的好比淘寶api調用次數限流等一些業務問題就不列出來了spring


Passport部分的壓力

因爲用戶進來後先要登陸而且綁定帳號,實際壓力先到Passport部分,在這個過程當中最開始單機TPS只能到500,通過N輪優化後基本能達到5400 TPS,下面主要是闡述這個優化過程docker

Passport 核心服務分兩個:

  • Login 主要處理登陸請求
  • userservice 處理登陸後的業務邏輯,好比將優酷帳號和淘寶帳號綁定

爲了更好地利用資源每臺物理加上部署三個docker 容器,跑在不一樣的端口上(808一、808二、8083),經過bridge網絡來互相通信數據庫

Passport機器大體結構

screenshot.png

說明:這裏的500 TPS到5400 TPS是指登陸和將優酷帳號和淘寶帳號綁定的TPS,也是促銷活動主要的瓶頸api

userservice服務網絡相關的各類問題


太多SocketConnect異常(如上圖)

在userservice機器上經過netstat也能看到大量的SYN_SENT狀態,以下圖:
tomcat

由於docker bridge經過nat來實現,嘗試去掉docker,讓tomcat直接跑在物理機上

這時SocketConnect異常再也不出現

重新梳理一下網絡流程

docker(bridge)----短鏈接--->訪問淘寶API(淘寶open api只能短鏈接訪問),性能差,cpu都花在si上;

若是 docker(bridge)----長鏈接到宿主機的某個代理上(好比haproxy)-----短鏈接--->訪問淘寶API, 性能就能好一點。問題多是短鏈接放大了Docker bridge網絡的性能損耗

當時看到的cpu si很是高,截圖以下:

去掉Docker後,性能有所提高,繼續經過perf top看到內核態尋找可用的Local Port消耗了比較多的CPU,gif動態截圖以下(能夠點擊看高清大圖):

注意圖中ipv6_rcv_saddr_equal和inet_csk_get_port 總共佔了30%的CPU

通常來講一臺機器可用Local Port 3萬多個,若是是短鏈接的話,一個鏈接釋放後默認須要60秒回收,30000/60 =500 這是大概的理論TPS值

同時觀察這個時候CPU的主要花在sy上,最理想確定是但願CPU主要用在us上,截圖以下:

sy佔用了30-50%的CPU,這太不科學了,同時經過 netstat 分析鏈接狀態,確實看到不少TIME_WAIT:

因而讓PE修改了tcp相關參數:下降 tcp_max_tw_buckets和開啓tcp_tw_reuse,這個時候TPS能從1000提高到3000

優化到3000 TPS後上線繼續壓測

竟然性能又回到了500,太沮喪了,其實最開始帳號綁定慢,Passport這邊就懷疑taobao api是否是在大壓力下不穩定,程序員通常都是認爲本身沒問題,有問題的必定是對方 :) ,taobao api那邊給出調用數據都是1ms之內就返回了(alimonitor監控圖表)。

因而懷疑從優酷的機器到淘寶的機器中間鏈路上有瓶頸,可是須要設計方案來證實這個問題在鏈路上,要不各個環節都會認爲本身沒有問題的,當時Passport的開發也只能拿到Login和Userservice這兩組機器的權限,中間的負載均衡、交換機都沒有權限接觸到。

在嘗試過tcpdump抓包、ping等各類手段分析後,設計了場景證實問題在中間鏈路上。

設計以下三個場景證實問題在中間鏈路上:

  1. 壓測的時候在userservice ping 淘寶的機器;
  2. 將一臺userservice機器從負載均衡上拿下來(沒有壓力),ping 淘寶的機器;
  3. 從公網上非優酷的機器 ping 淘寶的機器;

這個時候奇怪的事情發現了,壓力一上來**場景一、2**的兩臺機器ping淘寶的rt都從30ms上升到100-150ms,**場景1** 的rt上升能夠理解,可是**場景2**的rt上升不該該,同時**場景3**中ping淘寶在壓力測試的狀況下rt一直很穩定(說明壓力下淘寶的機器沒有問題),到此確認問題在優酷到淘寶機房的鏈路上有瓶頸,並且問題在優酷機房出口扛不住這麼大的壓力。因而從上海Passport的團隊找到北京Passport的PE團隊,確認在優酷調用taobao api的出口上使用了snat,PE到snat機器上看到snat只能使用單核,並且對應的核早就100%的CPU了,由於以前一直沒有這麼大的壓力因此這個問題一直存在只是沒有被發現。

因而PE去掉snat,再壓的話 TPS穩定在3000左右


到這裏結束了嗎? 從3000到5400TPS

優化到3000TPS的整個過程沒有修改業務代碼,只是經過修改系統配置、結構很是有效地把TPS提高了6倍,對於優化來講這個過程是最輕鬆,性價比也是很是高的。實際到這個時候也臨近雙11封網了,最終經過計算(機器數量*單機TPS)徹底能夠抗住雙11的壓力,因此最終雙11運行的版本就是這樣的。 可是有工匠精神的工程師是不會輕易放過這麼好的優化場景和環境的(基線、機器、代碼、工具都具有配套好了)

優化完環境問題後,3000TPS能把CPU US跑上去,因而再對業務代碼進行優化也是可行的了。

進一步挖掘代碼中的優化空間

雙11前的這段封網實際上是比較無聊的,因而和Passport的開發同窗們一塊兒挖掘代碼中的能夠優化的部分。這個過程當中使用到的主要工具是這三個:火焰圖、perf、perf-map-java。相關連接:http://www.brendangregg.com/perf.html ; https://github.com/jrudolph/perf-map-agent

經過Perf發現的一個SpringMVC 的性能問題

這個問題具體參考我以前發表的優化文章http://www.atatech.org/articles/65232 。 主要是經過火焰圖發現spring mapping path消耗了過多CPU的性能問題,CPU熱點都在methodMapping相關部分,因而修改代碼去掉spring中的methodMapping解析後性能提高了40%,TPS能從3000提高到4200.

著名的fillInStackTrace致使的性能問題

代碼中的第二個問題是咱們程序中不少異常(fillInStackTrace),實際業務上沒有這麼多錯誤,應該是一些不重要的異常,不會影響結果,可是異常頻率很高,對這種咱們能夠找到觸發的地方,catch住,而後不要拋出去(也就是別觸發fillInStackTrace),打印一行error日誌就行,這塊也能省出10%的CPU,對應到TPS也有幾百的提高。

screenshot.png

部分觸發fillInStackTrace的場景和具體代碼行(點擊看高清大圖):
screenshot.png

對應的火焰圖(點擊看高清大圖):
screenshot.png

screenshot.png

解析useragent 代碼部分的性能問題

整個useragent調用堆棧和cpu佔用狀況,作了個彙總(useragent不啓用TPS能從4700提高到5400)
screenshot.png

實際火焰圖中比較分散:
screenshot.png

最終經過對代碼的優化勉勉強強將TPS從3000提高到了5400(太不容易了,改代碼過程太辛苦,不如改配置來錢快)

優化代碼後壓測tps能夠跑到5400,截圖:

最後再次總結整個壓測過程的問題和優化歷程

- docker bridge網絡性能問題和網絡中斷si不均衡 (優化後:500->1000TPS) - 短鏈接致使的local port不夠 (優化後:1000-3000TPS) - 生產環境snat單核致使的網絡延時增大 (優化後能達到測試環境的3000TPS) - Spring MVC Path帶來的太高的CPU消耗 (優化後:3000->4200TPS) - 其餘業務代碼的優化(好比異常、agent等) (優化後:4200->5400TPS) 

整個過程獲得了淘寶API、優酷會員、優酷Passport、網絡、螞蟻等衆多同窗的幫助,原本是計劃去上海跟Passport的同窗一塊兒覆盤而後再寫這篇文章的,結果一直未能成行,請原諒我拖延到如今才把你們一塊兒辛苦工做的結果整理出來,可能過程當中的數據會有一些記憶上的小錯誤。
相關文章
相關標籤/搜索