記一次後端效能測試與除錯

2022-06-29 23:27:11 字數 3443 閱讀 3952

先說結論:專案遇到的主要瓶頸在cpu和uwsgi的listen引數。下面以時間順序記錄排查過程。

應用伺服器中uwsgi部分配置如下:

[uwsgi]

strict = true

single-interpreter = true

die-on-term = true

socket=0.0.0.0:5001

pidfile=/tmp/uwsgi-exp-flask.pid

vacuum=true

# python 虛擬環境目錄:

home=/root/.local/share/virtualenvs/expression-flask-p9tmtecw

pythonpath=/var/www/expression-flask

# web 應用python主程式:

uid=root

gid=root

chdir=/var/www/expression-flask

max-fd=65535

# socket監聽佇列大小,預設100

listen=100

# 2程序,每個程序1執行緒

processes=2

# threads=1

# apscheduler requires enable-threads, if no worker threads are used

enable-threads=true

master=true

# 無master時自動結束worker

no-orphans=true

# 設定master程序名稱

procname-master=uwsgi master (%p)

# 平滑重啟最長等待時間(秒)

reload-mercy=6

此外/etc/sysctl.conf部分配置如下:

net.ipv4.tcp_keepalive_time=1800

net.ipv4.tcp_keepalive_probes=3

net.ipv4.tcp_keepalive_intvl=15

net.ipv4.tcp_max_tw_buckets=25000

net.ipv4.tcp_tw_reuse=1

net.ipv4.tcp_fin_timeout=10

net.ipv4.tcp_syncookies=0

net.core.somaxconn=65535

發現效能問題後,首先需要定位慢在什麼地方。

# nginx配置(部分)

這樣可以看到如下這種時間記錄:

conn(upstream_connect_time)是nginx連線uwsgi花費的時間。這個圖是後來擷取的,最初req超5秒,conn超2秒。conn過大是uwsgi的listen引數過小造成的。listen佇列大小預設是100,滿了之後就會拒絕請求,這時候任務會被堆積在nginx端,記錄的conn就比較大。

通過把listen引數大小改成65535(不可超過net.core.somaxconn,否則uwsgi拒絕啟動),可以讓uwsgi接受更多請求放入backlog,所以降低了upstream_connect_time:

上面通過調整listen讓uwsgi一股腦地接受所有請求,並不能讓整體速度提高(請求失敗的都是499錯誤):

所以,還需要確認一下uwsgi和flask**到底是誰慢。

檢視uwsgi的日誌可看出耗時最長的請求執行了不到1秒:

所以**執行速度還可以,鍋是uwsgi的。

uwsgi處理很慢,是不是worker數量太少?所以嘗試把2程序增大到4/8/16/64程序,但是效能並沒有變好,4程序的時候似乎快了一點,8程序似乎又慢了一點,16/64程序反而導致效能再次下降。猜測是cpu效能不夠。prometheus和vps自帶監控精度都太低,不能看到瞬發的cpu佔用率,於是開htop肉眼觀察,發現請求到達時cpu占用可以到達88%上下,是挺高的。

(可能有人問為什麼要500併發瞬發而不連續壓測,因為連續壓測測試的是吞吐量而不是響應時間)

於是臨時搭個4核4g的伺服器部署nginx、uwsgi、flask**,redis和mongodb仍在原來的2核8g伺服器上,配置hosts通過內網訪問。

這下提公升很明顯:

只有第2、3個介面的最大響應時間超過3秒:

此時cpu峰值占用情況(上面是4核4g的應用伺服器,下面是2核8g的資料伺服器):

如何解決:

按預設的兩台4核4g應用伺服器,第2個介面ok。第三個介面時間過長是因為邏輯過於複雜,獲取題目之前先進行了試卷初始化工作。把這個介面拆分為兩個介面,ok。

單台4核4g應用伺服器+單台2核8g資料伺服器的情況下,把listen改回100看看對結果有多大影響:

此外uwsgi日誌中可查詢到佇列滿的告警資訊。

根據結果看listen的影響還是比較明顯的,數值過小和nginx的bargain太多而且不能充分調動每個worker的積極性。

記一次除錯

這是我最近幾個月來遇到的最棘手的乙個問題 昨天花了4個小時找出第一層次的原因 這個糾結啊,本來和老婆說好準時下班回家吃飯的,結果被這個問題拖了老久。這是乙個gradle的plugin,用來resolve公司內部的dependency的,弄完了跑測試專案的,拋乙個npe,而且npe還不在自己的 裡面。...

記一次除錯

這是我最近幾個月來遇到的最棘手的乙個問題 昨天花了4個小時找出第一層次的原因 這個糾結啊,本來和老婆說好準時下班回家吃飯的,結果被這個問題拖了老久。這是乙個gradle的plugin,用來resolve公司內部的dependency的,弄完了跑測試專案的,拋乙個npe,而且npe還不在自己的 裡面。...

記一次nginx module 除錯

參考了 先進入nginx工作目錄 usr local nginx sbin 使用gdb q tui q選項是以安靜模式啟動,不顯示gdb版本等資訊。tui選項可以顯示 介面 然後在gdb中啟動nginx shell nginx 啟動之後,可以檢視當前nginx中的程序號 shell pidof ng...