遇到真正的高并发问题了,特来求助

2018 年 9 月 16 日
 abcbuzhiming
以前做的项目,要么服务器够多,要么访问量比较分散,一天虽然人多,但是都是不同时段。所以没遭遇到访问瓶颈。这次真刀真枪的需要进行一次单服优化,然后就发现单服性能不可思议的低。大致情况如下:
应用服务器是 Tomcat,在阿里云上的 4 核心的 xero,8GB 内存,10MB 带宽,技术实现是 spring mvc,并不是特别复杂的计算业务,说难听点仅仅是 crud,而且输出的是纯粹的 json,没有其它的静态文件之类的东西。然后 MySQL 数据库在和应用服务器同一区域的另外一台阿里云服务器上,类似的配置,4 核心,8GB 内存,用的是高效 SSD。
这样的两台(一组)服务器,能抗住多少并发呢,500 不到。。。

然后开始初步分析,发现一个问题,就是哪怕是单纯的数据库读业务,从浏览器请求到服务器,服务器从数据库读取完毕到返回给前端,最快也要 20-30ms 左右,稍微复杂点的数据结构就上 100ms 了,如果按这个计算,每秒每个线程的处理能力理论最快也就 50 个并发请求,4 核心的机器上,JVM 的线程池一般也就核心的 1.5-2 倍,顶多不到 10 个线程,这样一算,单服理论并发处理能力确实只有 500 不到。。。

我不死心于是回头去找以前的类似服务器做测试,结果发现性能是类似的,只不过当年是靠着服务器够多顶住了罢了。

我知道肯定会有人说,上缓存啊,我当然知道上缓存,我的困惑是,难道只有上缓存一条路,那些并发上 w 的都是靠缓存顶住的吗?不上缓存的话,我现在服务器的性能指标到底是否正常?
37588 次点击
所在节点    程序员
183 条回复
Mush
2018 年 9 月 17 日
@Allianzcortex #135 需不需要改逻辑要看实际情况. 我是用的 Python, 写个缓存的装饰器就 ok 了. 拓展硬件也能解决问题, 但不还得多花钱么. 要多快好省地建设社会主义.
PazuLee
2018 年 9 月 17 日
插一句:
1:服务器从数据库读取完毕到返回给前端,最快也要 20-30ms 左右
2:稍微复杂点的数据结构就上 100ms 了
=============
建议看下 avg,最快可能对 QPS 评估意义不大;
看下简单和复杂情况下,avg 的差距是因为什么;如果是数据库就升级 DB,如果是服务器考虑扩容+优化配置;如果是网络就买带宽;或者是多个综合原因,按权重*成本,计算一下方案
Mrbird
2018 年 9 月 17 日
可以将接口改为异步,提高吞吐量
GoForce5500
2018 年 9 月 17 日
带宽是 10Mb 而不是 10MB 吧?
相当于 1.2MB/s,1.2/500=0.0024MB
如果 JSON 较大,都很容易把带宽打满,何况中间还有其它步骤。
jason19659
2018 年 9 月 17 日
感觉没啥问题吧。。
monsterj
2018 年 9 月 17 日
@doggg 相当低?敢问你大一压榨的那次,接口业务复杂不?一个复杂的接口和一个简单的查询接口,并发量简直是两码事
exmario
2018 年 9 月 17 日
楼主你先直接把数据写死(绕过 mysql )做个测试看看吧,500 并发不管怎么看都算低
exmario
2018 年 9 月 17 日
纯静态数据随便上 w~
raysmond
2018 年 9 月 17 日
建议先把所有数据缓存起来,测一把 qps ;全部走数据库,测一把 qps。
就知道缓存到底作用有多大了。
opengps
2018 年 9 月 17 日
@exmario 数据库 1k 块大小(单行数据带下),你写个 sql 循环读取试试, 读取可能会多一点
我之前项目因为压力在写不在读,所以只测的写入,阿里云高效云盘,写入是只有 400 行每秒,几个语句同时执行也顶多 500
lscho
2018 年 9 月 17 日
@v2orz 看题主说的什么。。。从浏览器到服务器。。。难道他在阿里云上的浏览器做的测试?第一反应是在本地的浏览器吧。。。这个测试方法本来就有问题。
CFM880
2018 年 9 月 17 日
JProfiler 分析一下
abcbuzhiming
2018 年 9 月 17 日
@GoForce5500 对,就是 10Mb,也就是 10M 位,但是阿里云平台的监控表明,最高也才被吃掉了 5Mb 不到。所以带宽的问题,貌似不是当前问题
blless
2018 年 9 月 17 日
以前写 c#用过线程池,线程数量到 100 左右 cpu 切换就感觉消耗很大了,但是 100 以内线程池感觉还是可以的。而且哪怕是阻塞队列 500tps 按楼主说法一个请求 20ms 也就 10 个线程… 500 并发真的不算高…
abcbuzhiming
2018 年 9 月 17 日
@lscho 我当然是在本地用浏览器的 debug 工具来测试和阿里云服务器之间交互的时间。那到底如何测试才是对的?或者说,本地浏览器和服务器交互的时间,其实在服务器看来是不算在计算时间里的?
lynnworld
2018 年 9 月 17 日
确认是 500 并发? avg 20ms 的话,qps 已经是 2.5w 了,单机不错了
danc
2018 年 9 月 17 日
一台机器 500 并发已经很不错了呢。你得加机器了
iyaozhen
2018 年 9 月 17 日
有些回复没看全,说实话,单机 500 并发实际算高的了。

一次请求耗时 20-30ms 我觉得没啥优化空间了。
一些建议:
1.「 JVM 的线程池一般也就核心的 1.5-2 倍,顶多不到 10 个线程」因为对 JAVA 不精通这个楼主感觉可以再测试下,高峰期的使用 dump 一下线程,看看是否都在工作,是否可以多开点线程
2. 机器是否达到瓶颈?看看 cpu、内存和带宽,还有富余的话是否可以多实例,前面挂个 nginx。
iyaozhen
2018 年 9 月 17 日
@abcbuzhiming 你要测试服务器的时间最简单的就是 tomcat access log,打印一下耗时。
lscho
2018 年 9 月 17 日
@abcbuzhiming 看来你不了解压力测试。。如果是测性能,就要尽量减少网络和带宽的影响。。比如在阿里云同机房开一台测试。

如果你在本地测试,就要考虑网络和带宽的影响。。。比如你 ping 一下你的服务器,这个时间就是网络延迟,这个不能计算在内的。。。然后要考虑带宽,比如 1m 带宽,上行也就 120k 左右。。你如果有 120k 的数据,再怎么优化,也不可能低于 800ms 的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.ih06.com/t/489883

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX