摘要:每个请求来的时候都会先去看看中有没有,即使使用的是的方式也不免会让我对它的性能产生一些担忧,所以性能测试就必须要来一发了。注也在阿里云执行只要是为了在一个数据中心降低网络延迟。测试因为考虑到服务器比较稳定,减少压测总数。
背景
最近我操刀了leetcode的论坛迁移,整个过程持续了几周的时间,总算暂时告了一个段落。常使用leetcode论坛的用户应该已经发现论坛已经大变样了吧~
期间遇到了不少坑坑洼洼,将来也还会有好多问题等待去一一解决。关于这个迁移过程中的收货,这篇文章中就不细说了,有时间再另开一篇博文。这篇文章主要关注在url-mapping以及它的性能问题。
问:url-mapping的问题从何而来呢?
旧的论坛和新的论坛是两个不同的discuss框架。前者是phpbb,现在是nodebb。两者的 url routing 完全不一样,比如说同一个topic,在原来的url是 http://hostname/discuss/
而在广袤的互联网海洋中,旧论坛的url可能到处都存在。我们不希望在论坛迁移后,用户点那些链接就失效了。我们希望的是用户访问旧的url可以被重定向到新论坛的某个地址。所以就产生了url-mapping的问题。
方法 生成url-mapping感谢nodebb-plugin-import提供了数据迁移以后自动生成url-mapping的方式,省了我自己写脚本生成这些mapping的时间。每一条mapping大致是这样的:
~^/discuss/questions/oj/add-two-numbers(?[^/]*)*/?$ /category/10/add-two-numbers;
其中的slug和id的mapping是由插件生成的。regular expression是为了匹配url中如果有param添加的。
Nginx Map官方文档的demo可能对于刚想上手的同学来说不是那么友好,还是直接看现成的配置学得快:
http { ... map_hash_max_size 204800; map_hash_bucket_size 204800; map $request_uri $new { include /path/of/your/map/file; } include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; ... }
server { ... if ($new) { rewrite ^ https://discuss.leetcode.com$new redirect; } location / { ... } ... }
在server规则匹配中,$new值不为空,说明当前要访问的url已经在http模块的mapping文件中匹配到了,这个时候就不走各种location模块了,直接rewrite成新的地址。注:这里要是做成proxy_pass也行,后面的测试中就采用了proxy_pass。但线上的环境,担心nginx的压力太大了,就采用了rewrite方式给它减减压。
测试考虑到mapping的条目有点多,几万量级,又都是正则匹配。每个请求来的时候都会先去看看mapping中有没有,即使mapping使用的是hash的方式也不免会让我对它的性能产生一些担忧,所以性能测试就必须要来一发了。
测试方案:
在新机器上跑helloworld
自动生成随机100个url-mapping,都重定向到helloworld
使用abtest分别对helloworld和随机url作压测
增大url-mapping的条目,重复1,2
压测机器临时租了两台阿里云服务器(因为是临时的,所以我也就不在意在后文暴露ip了),配置都是:1核,2048M内存,40G硬盘。一台用作nginx和helloworld程序,一台专门做abtest。
注:abtest也在阿里云执行只要是为了在一个数据中心降低网络延迟。最后发现效果真不错,rps从100多直接飙升到2700多。
helloworld采用了nodejs的helloworld:
var http = require("http"); var i = 0; http.createServer(function (req, res) { console.log(i++); res.writeHead(200, {"Content-Type": "text/plain"}); res.end("Hello World "); }).listen(1337, "0.0.0.0"); console.log("Server running at http://0.0.0.0:1337/");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 + "(?[^/]*)*/?$ /; ") 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) |
---|---|---|---|---|
100 | 2829.44 | 1819.63 | 1765.25 | 9740.53 |
1000 | - | 1816.00 | 1509.52 | 4094.68 |
10000 | - | 1813.22 | 514.24 | 658.32 |
100000 | - | 1836.02 | 62.40 | 65.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) |
---|---|---|---|---|
100 | 0.690 | 0.922 | 0.933 | 0.507 |
1000 | - | 0.925 | 1.043 | 0.648 |
10000 | - | 0.921 | 2.340 | 1.915 |
100000 | - | 0.926 | 16.321 | 15.469 |
在并发不是很高的时候mapping的条目可以更多。100000个条目大概只会影响整个请求15ms左右,可以忽略不计。如果说150ms的延迟是可以接受的,那么在一个并发不是很高的情况下,mapping最多可以有100w条,还是很多的。
测试中的不足压测的url请求并不随机
所有的url都被重定向到一个地方。不过从结果来看,nginx确实是根据条目一个个请求的。这点倒没有什么影响
没有测试http://hostname/path?param=xxx这样类型的url
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/39309.html
摘要:每个请求来的时候都会先去看看中有没有,即使使用的是的方式也不免会让我对它的性能产生一些担忧,所以性能测试就必须要来一发了。注也在阿里云执行只要是为了在一个数据中心降低网络延迟。测试因为考虑到服务器比较稳定,减少压测总数。 背景 最近我操刀了leetcode的论坛迁移,整个过程持续了几周的时间,总算暂时告了一个段落。常使用leetcode论坛的用户应该已经发现论坛已经大变样了吧~ 期间遇...
摘要:指令正则匹配指令使用模块提供的,模块可以创建变量,这些变量的值与另外的变量值相关联。根据不同的设置网站根目录通过指令获取到自定义值后,可以做如下设置,让不同的测试人员对应不同的网站根目录这里行,网站目录可以用变量来表示。 原文链接:https://blog.tanteng.me/2016/... ,原文内容会不断完善,以原文为准。 本文介绍有关 User-Agent 的知识,以及使用 ...
摘要:本文同步在个人博客上,欢迎关注这篇文章整理了在前端开发中,在开发环境下使用重写及代理功能的方法。表示该规则是使用正则定义的,区分大小写。因此牢记在上下文中使用,而在上下文中使用。 本文同步在个人博客shymean.com上,欢迎关注 这篇文章整理了在前端开发中,在开发环境下使用nginx重写uri及代理功能的方法。 参考 nginx中文文档 前端开发者必备的 Nginx 知识 Ngin...
摘要:切图仔的小书本文陆续介绍的功能配置及一些实用场景待完善。更可贵的是配置简单文档丰富大大降低了学习的门槛。为什么选择自年发布以来,一直是服务器市场的霸主。虽然发布较晚,但是却因为在高并发下卓越的表现而迅速崭露头角。 切图仔的 Nginx 小书 本文陆续介绍 Nginx 的功能、配置、及一些实用场景(待完善...)。 一、介绍 Nginx 1. Nginx 是什么? Nginx,很多工程师...
阅读 1648·2021-11-16 11:44
阅读 2392·2021-10-11 11:07
阅读 4035·2021-10-09 09:41
阅读 662·2021-09-22 15:52
阅读 3185·2021-09-09 09:33
阅读 2699·2019-08-30 15:55
阅读 2282·2019-08-30 15:55
阅读 835·2019-08-30 15:55