Nginx 中 map 模組的使用及效能測試

NO IMAGE

背景

最近我操刀了leetcode論壇遷移,整個過程持續了幾周的時間,總算暫時告了一個段落。常使用leetcode論壇的使用者應該已經發現論壇已經大變樣了吧~

期間遇到了不少坑坑窪窪,將來也還會有好多問題等待去一一解決。關於這個遷移過程中的收貨,這篇文章中就不細說了,有時間再另開一篇博文。這篇文章主要關注在url-mapping以及它的效能問題。

:url-mapping的問題從何而來呢?

舊的論壇和新的論壇是兩個不同的discuss框架。前者是phpbb,現在是nodebb。兩者的 url routing 完全不一樣,比如說同一個topic,在原來的url是 http://hostname/discuss/<topic_id>/<topic_name>

其中的slug

server {
...
if ($new) {
rewrite ^ https://discuss.leetcode.com$new redirect;
}
location / {
...
}
...
}

在server規則匹配中,$new值不為空,說明當前要訪問的url已經在http模組的mapping檔案中匹配到了,這個時候就不走各種location

url-mapping

生成urlmapping寫了一個python指令碼:

import hashlib
m2 = hashlib.md5()
current = "hello world"
f = open('./url.map', 'w')
for i in range(100):
m2.update(current)
current = m2.hexdigest()
f.write('~^/hello/world/'   current   '\\b(\?[^/]*)*/?$\t/;\n')
f.close()

nginx配置:

server {
listen 80;
server_name 120.26.138.197;
location ^~ /{
if ($new) {
proxy_pass http://120.26.138.197:1337$new;
break;
}
return 404;
}
}

abtest

rps測試(request per second):併發壓測使用100000次請求,併發100個使用者的方式。

# 不走nginx
ab -n100000 -c100 120.26.138.197:1337/
# 走nginx
ab -n100000 -c100 120.26.138.197/hello/world/5eb63bbbe01eeed093cb22bb8f5acdc3/

mapping條目直接訪問(rps)map第一條url(rps)map最後一條url(rps)不存在的url(rps)
1002829.441819.631765.259740.53
10001816.001509.524094.68
100001813.22514.24658.32
1000001836.0262.4065.80

跟預想的一樣,mapping的條目確實會對請求效率產生影響。而且幾萬條的對映在較高併發的情況下已經到了勉強能用的臨界了。還好以後mapping的條目不會再增加了,並且論壇的併發很難到100的量級。

tpr測試(time per request):因為考慮到伺服器比較穩定,減少壓測總數。同時把併發使用者減為1個。

# 不走nginx
ab -n1000 -c1 120.26.138.197:1337/
# 走nginx
ab -n1000 -c1 120.26.138.197/hello/world/5eb63bbbe01eeed093cb22bb8f5acdc3/

mapping條目直接訪問(ms)map第一條url(ms)map最後一條url(ms)不存在的url(ms)
1000.6900.9220.9330.507
10000.9251.0430.648
100000.9212.3401.915
1000000.92616.32115.469

在併發不是很高的時候mapping的條目可以更多。100000個條目大概只會影響整個請求15ms左右,可以忽略不計。如果說150ms的延遲是可以接受的,那麼在一個併發不是很高的情況下,mapping最多可以有100w條,還是很多的。

測試中的不足

壓測的url請求並不隨機

所有的url都被重定向到一個地方。不過從結果來看,nginx確實是根據條目一個個請求的。這點倒沒有什麼影響

沒有測試http://hostname/path?param=xxx這樣型別的url