101
kran 2018-09-17 00:31:06 +08:00 via iPhone
要不你算算请求 /响应体大小,看看带宽吞吐能力是不是到极限了
|
102
micean 2018-09-17 00:32:07 +08:00
@jokerlee
CompletableFutrue 其实和 stream 一样为了跑并发的…… 异步性能最好的还是 callback hell 那样 java 的协程好像是 Quasar 的作者在做?但是 Quasar 真的慢…… |
103
cominghome 2018-09-17 00:49:06 +08:00
@ittianyu 真的是张嘴就来,几万并发到你这好像分分钟就灰飞烟灭了
|
104
des 2018-09-17 00:49:36 +08:00 via Android
同 50 楼,感觉是 MySQL 那台服务器 io 不太好。
先看看是不是响应时间随并发数增长的,以及看看有没有超长响应时间的请求 |
105
blless 2018-09-17 01:37:36 +08:00 via Android
500 不高吧…我还以为 java 下高并发场景已经很普遍了呢…我们以前用 python+gevent 方案感觉都不止 500,而且 python 最大问题是 GIL 只能用单核,后来转 go 以后压测一下基本限制都是数据库瓶颈
|
106
ETiV 2018-09-17 04:09:19 +08:00 via iPhone
我觉得应该用数据说话,比较科学。
就好比你去看大夫,都要验血验尿、拿到指标才行。不看指标的可能是中医 -。- 如果能单一请求就能复现出 20-30ms 或者更长的响应时长的话,你单机做一下 Profiling 比较好… 或者,简单点儿的做法,你打点计时。 在关键步骤分别记下处理逻辑中此行代码的当前时间, 然后分别追加在 json 文件内部或者放 http response header 里,一并输出。 |
107
veelog 2018-09-17 06:05:42 +08:00 via iPhone
以前也做过类似的分析,最后定位到瓶颈就在 mysql
|
108
veelog 2018-09-17 06:12:19 +08:00 via iPhone
压测的时候可以监控下 cpu 内存,磁盘 io 网络 这些看看哪里占用高
|
109
bobuick 2018-09-17 06:28:06 +08:00
猜是猜不到的。压测+ profile 就知道了
|
111
opengps 2018-09-17 07:58:16 +08:00 via Android
查看一下硬盘队列吧。我看了目前题主的说法,依然认为出在硬盘 io 上
|
112
doggg 2018-09-17 08:02:15 +08:00 1
500 不管是 QPS 还是 TPS 都是相当低的水平。
大一曾经试图压榨一台 1c1g 的腾讯云服务器,Tomcat 与 MySQL 同服务器的情况下 QPS 达到 3000,TPS 达到 2000。没有任何 Redis 缓存之类的。 服务器的性能短板很难定位,但可以自己试着排除一下: 带宽问题:CND,OSS 存静态文件,减少业务服务器带宽输出,Tomcat 也可以配置 Gzip。 池优化:Tomcat 的线程池必须配置,数据库的连接池请选择 Tomcat 或者 Tomcat JDBC pool 或者 HikariCP,这两种数据库连接池差距微乎其微,几乎可以忽略不计。包括一些参数优化。 MySQL 连接参数:cachePrepStmts,prepStmtCacheSize,prepStmtCacheSqlLimit,useServerPrepStmts。 磁盘 IO 问题:这个也得自己诊断一下。 如果业务很复杂,楼主所说的 500 并发,每一个请求需要好几个 SELECT 话,那就是 500*N,那 QPS 应该是没问题的,再花点精力也许可以稍微提高一下。 |
113
xuanbg 2018-09-17 08:23:13 +08:00
根据楼主描述,似乎瓶颈就在数据库上,那么解决方案很简单:
1、换高性能 RDS,大概性能可以提升 10 倍。 2、优化 SQL,这个能提升多少不确定。 |
114
D3EP 2018-09-17 08:38:11 +08:00 via iPhone
@neoblackcap 现在大多数语言和大多数框架都是同步模型啊。除了 nodejs 这种天热异步的,其它语言都是同步模型占绝对主流。
|
115
D3EP 2018-09-17 08:43:02 +08:00 via iPhone
@neoblackcap 你说的第二种方案就是绝大多数框架的方案。关键问题是对于 MySQL 这种耗时操作的处理方案,是应该挂起来等待,还是请求后塞入事件队列。
|
116
D3EP 2018-09-17 08:46:08 +08:00 via iPhone
@xiaoshenke 人家说的是业务层面的同步异步模型。绝大多数还是同步写法。dubbo 也就是 io 的时候是异步的,后面的操作还是塞入线程池,业务逻辑还是同步写的。
|
118
alwayshere 2018-09-17 08:48:40 +08:00
与其大量优化代码和 cache,真的不如省点时间加点钱堆硬件配置,过来人之谈
|
119
v2orz 2018-09-17 08:52:23 +08:00
应该是 tomcat 没配置好。调一下参数或者用 resin
不过“单纯的数据库读业务,从浏览器请求到服务器,服务器从数据库读取完毕到返回给前端,最快也要 20-30ms ” 肯定不正常 |
120
star7th 2018-09-17 09:06:49 +08:00
合理使用缓存能让单机服务器的性能提高数倍,尤其是 web 服务,基本瓶颈都在数据库查询上。把结果缓存到内存中,跟每次从磁盘读,差别很大的。
|
121
jswh 2018-09-17 09:19:19 +08:00
@abcbuzhiming 浏览器前端到服务器数据返回,其中包含了网络延时的。建议看看内网的查询数据。
|
122
zqyisasd 2018-09-17 09:26:59 +08:00
之前公司的 tomcat 线上并发只有 100 多一点,不敢说话了。
|
123
lscho 2018-09-17 09:31:15 +08:00 via Android
@v2orz 有什么不正常?网络延迟不计算吗? 20 多 ms 的网络延迟已经很低了。。。又不是内网测试
|
124
lttzzlll 2018-09-17 09:32:09 +08:00 via Android
先确定是不是数据库的问题,查询的部分可以直接返回假的内容。单独测试一下查询语句耗时。
|
125
sagaxu 2018-09-17 09:32:43 +08:00 via Android
|
126
lauix 2018-09-17 09:46:47 +08:00
单线程服务 500 已经很不错了,大多数都是 DB 不行,可以考虑 缓存 异步。
|
127
codingKingKong 2018-09-17 10:12:37 +08:00
看一下 GC, 之前我有一次是因为频繁 gc, 导致的吞吐量下降
|
128
q397064399 2018-09-17 10:15:53 +08:00
@neoblackcap #85 说实话我还是看好 Go 这种用户态线程的做法,异步 IO 回调这种方法始终是令人难受的
|
129
tailf 2018-09-17 10:21:27 +08:00
并发上万都是靠架构顶住的,单机 java+MySQL 500 这个数字已经很强了,换 PHP 估计也就 100。
|
130
Mush 2018-09-17 10:23:39 +08:00 1
缓存大法好, 适当的加缓存能显著提高响应速度. 我们公司有个请求量比较大(6 千万一天)的服务, 用了 1.75 个虚拟 cpu 就够了, 平均响应时间小于 5ms. 因为业务逻辑很简单, 多数请求直接命中缓存了.
|
131
mars0prince 2018-09-17 10:24:01 +08:00
差不多了,mysql 最简单的 select 每条平均执行时间也要 10ms
|
132
mars0prince 2018-09-17 10:25:54 +08:00
优化方法无非就是加机器,加缓存,读写分离,分库分表
|
133
tanranran 2018-09-17 10:26:07 +08:00
@mars0prince #131 #131 10ms 有问题吧
|
134
9684xtpa 2018-09-17 10:32:07 +08:00
感觉是资源加载太多,贷款的瓶颈啊,你们公司的网站的数据是不是都在服务器里啊,图片、视频啥的没有走 CDN,如果是的话,用户加载图片视频网页都会占用带宽的啊。
单纯的 curd,用 springmvc 和 mysql 不会有这么多大的延迟,只要你保证你的 sql 性能没问题,框架用的都是主流框架,剩下的除非一些框架 bug,没了。 加宽带把 |
135
Allianzcortex 2018-09-17 10:54:37 +08:00
@Mush 加缓存还需要改代码逻辑吧~如果能通过扩展硬件来解决的话感觉会简单诶
|
136
sorra 2018-09-17 11:03:34 +08:00
@rogerchen 似乎多数人只想要个简单直接的答案,不愿意哪怕多分析一下
面试看到爱动脑的都想赶紧发 offer,然而人家也很抢手啊 |
138
9684xtpa 2018-09-17 11:07:50 +08:00
@dragonsky #137 哈哈,我刚特地看了一下我的输入法,第一个是贷款,第二个才是带宽。。。。。。。。尴尬,说到贷款估计就是和房子有关系呗,生活不易啊
|
139
meetocean 2018-09-17 11:12:03 +08:00
找到原因,才能针对性的解决问题。
|
140
v2orz 2018-09-17 11:13:08 +08:00
@lscho #123
前面描述限制那么多,难道性能分析的时候会找一个网络延迟那么大的环境吗?除非阿里云傻了,同一可用区网络延迟能那么惨烈。但是按题主前面的回复,可以排除这个情况 基本查询耗费 20ms 以上这难道还能是正常情况啊? |
141
Mush 2018-09-17 11:34:21 +08:00
@Allianzcortex #135 需不需要改逻辑要看实际情况. 我是用的 Python, 写个缓存的装饰器就 ok 了. 拓展硬件也能解决问题, 但不还得多花钱么. 要多快好省地建设社会主义.
|
142
PazuLee 2018-09-17 11:34:50 +08:00
插一句:
1:服务器从数据库读取完毕到返回给前端,最快也要 20-30ms 左右 2:稍微复杂点的数据结构就上 100ms 了 ============= 建议看下 avg,最快可能对 QPS 评估意义不大; 看下简单和复杂情况下,avg 的差距是因为什么;如果是数据库就升级 DB,如果是服务器考虑扩容+优化配置;如果是网络就买带宽;或者是多个综合原因,按权重*成本,计算一下方案 |
143
Mrbird 2018-09-17 11:40:51 +08:00
可以将接口改为异步,提高吞吐量
|
144
GoForce5500 2018-09-17 11:50:56 +08:00
带宽是 10Mb 而不是 10MB 吧?
相当于 1.2MB/s,1.2/500=0.0024MB 如果 JSON 较大,都很容易把带宽打满,何况中间还有其它步骤。 |
145
jason19659 2018-09-17 11:56:42 +08:00
感觉没啥问题吧。。
|
147
exmario 2018-09-17 12:11:30 +08:00
楼主你先直接把数据写死(绕过 mysql )做个测试看看吧,500 并发不管怎么看都算低
|
148
exmario 2018-09-17 12:12:38 +08:00
纯静态数据随便上 w~
|
149
raysmond 2018-09-17 12:20:50 +08:00
建议先把所有数据缓存起来,测一把 qps ;全部走数据库,测一把 qps。
就知道缓存到底作用有多大了。 |
150
opengps 2018-09-17 12:23:22 +08:00
@exmario 数据库 1k 块大小(单行数据带下),你写个 sql 循环读取试试, 读取可能会多一点
我之前项目因为压力在写不在读,所以只测的写入,阿里云高效云盘,写入是只有 400 行每秒,几个语句同时执行也顶多 500 |
151
lscho 2018-09-17 12:28:01 +08:00 via Android
@v2orz 看题主说的什么。。。从浏览器到服务器。。。难道他在阿里云上的浏览器做的测试?第一反应是在本地的浏览器吧。。。这个测试方法本来就有问题。
|
152
CFM880 2018-09-17 12:52:28 +08:00
JProfiler 分析一下
|
153
abcbuzhiming OP @GoForce5500 对,就是 10Mb,也就是 10M 位,但是阿里云平台的监控表明,最高也才被吃掉了 5Mb 不到。所以带宽的问题,貌似不是当前问题
|
154
blless 2018-09-17 12:54:25 +08:00 via Android
以前写 c#用过线程池,线程数量到 100 左右 cpu 切换就感觉消耗很大了,但是 100 以内线程池感觉还是可以的。而且哪怕是阻塞队列 500tps 按楼主说法一个请求 20ms 也就 10 个线程… 500 并发真的不算高…
|
155
abcbuzhiming OP @lscho 我当然是在本地用浏览器的 debug 工具来测试和阿里云服务器之间交互的时间。那到底如何测试才是对的?或者说,本地浏览器和服务器交互的时间,其实在服务器看来是不算在计算时间里的?
|
156
lynnworld 2018-09-17 13:00:39 +08:00
确认是 500 并发? avg 20ms 的话,qps 已经是 2.5w 了,单机不错了
|
157
danc 2018-09-17 13:25:20 +08:00
一台机器 500 并发已经很不错了呢。你得加机器了
|
158
iyaozhen 2018-09-17 13:28:39 +08:00
有些回复没看全,说实话,单机 500 并发实际算高的了。
一次请求耗时 20-30ms 我觉得没啥优化空间了。 一些建议: 1.「 JVM 的线程池一般也就核心的 1.5-2 倍,顶多不到 10 个线程」因为对 JAVA 不精通这个楼主感觉可以再测试下,高峰期的使用 dump 一下线程,看看是否都在工作,是否可以多开点线程 2. 机器是否达到瓶颈?看看 cpu、内存和带宽,还有富余的话是否可以多实例,前面挂个 nginx。 |
159
iyaozhen 2018-09-17 13:30:11 +08:00
@abcbuzhiming 你要测试服务器的时间最简单的就是 tomcat access log,打印一下耗时。
|
160
lscho 2018-09-17 13:41:47 +08:00 via Android
@abcbuzhiming 看来你不了解压力测试。。如果是测性能,就要尽量减少网络和带宽的影响。。比如在阿里云同机房开一台测试。
如果你在本地测试,就要考虑网络和带宽的影响。。。比如你 ping 一下你的服务器,这个时间就是网络延迟,这个不能计算在内的。。。然后要考虑带宽,比如 1m 带宽,上行也就 120k 左右。。你如果有 120k 的数据,再怎么优化,也不可能低于 800ms 的。 |
161
lscho 2018-09-17 13:46:01 +08:00 via Android
@iyaozhen 所以 20ms 的话,如果算上你电脑网络到机房的网络延迟,已经算是很低了,并且你离机房还比较近。。如果北京到广州,绝对不可能低于 30ms 的。
还有你说复杂点的数据结构就超过 100ms,这个根据你的描述,没法判定原因。你要先确定不是网络带宽原因,再去看是不是服务器或者数据库的问题。 |
162
liuxu 2018-09-17 13:49:03 +08:00
可以看看 112,133 楼的建议
|
163
exmario 2018-09-17 14:11:50 +08:00
@abcbuzhiming 当然不能公网做性能测试,那会受带宽或网络限制,本地的数据测试才是性能测试,你做的那个叫综合访问测试,已经不是单性能问题了
|
164
exmario 2018-09-17 14:15:00 +08:00
正确做法应该是申请 2 台同网段的阿里云服务器,然后 2 服务器之间内网 ip 互连测试
|
165
flight2006 2018-09-17 14:36:38 +08:00
没做特殊优化的话单机 500qps 到头了,优化还是有空间的,从数据库到 jvm gc 到 tomcat 线程池
|
166
wph95 2018-09-17 14:46:00 +08:00
你这个 500 并发是 500 qps 吗, 感觉楼主信息给的不足。// 虽然感觉要么 RDS 瓶颈了(写的 sql 有问题),要么 Tomcat 调好
我建议找个 apm 软件装上,跑个几天收集些信息。(反正常见几家 APM 公司都提供免费试用) |
167
sampeng 2018-09-17 15:23:03 +08:00
哦。阿里云是么?
突然想到。。阿里云有个压力测试服务。不知道现在是否免费。可以用他那个测。 |
168
doggg 2018-09-17 15:33:30 +08:00
@monsterj 晚点肛我。我已经说明 500 如果是接口的并发量,如果每次请求都需要 N 次 SELECT 那性能应该没什么大问题,如果 500 并发=500SELECT 那绝对存在问题。我的回答已经表明这个疑问了咯。
|
169
fakeJas0n 2018-09-17 15:36:45 +08:00
换 jetty 试试?
|
170
ala2008 2018-09-17 15:44:33 +08:00
我一直以为是单个 tomcat 的上限是几百左右啊
|
172
wjygamedev 2018-09-17 16:14:53 +08:00
楼主:是否考虑到做缓存。
1. memcached. 2. Redis 看看怎么上缓存方便,在同步读取数据库并返回的地方,用缓存做个隔离带,并发应该有所提升。 不过有时间的话,还是简易,从入口到出口,把统计数据做一下,这样更能有的放矢。 |
173
wawehi 2018-09-17 16:28:17 +08:00
把数据库用云 DB 测试看看, VPS 不适合建 Mysql, IO 太低
|
174
linuxchild 2018-09-17 16:31:01 +08:00
看看慢查询呗~
|
175
dudesun 2018-09-17 16:44:04 +08:00
数据库用高效云盘不合理,建议 ssd 云盘或者直接 RDS
|
176
abcbuzhiming OP @wawehi 我用的是阿里云 ECS 建立的 MySQL 服务器,ECS,高 IO 类型,SSD 硬盘
|
177
sagaxu 2018-09-17 17:06:57 +08:00 via Android
@yhvictor 逻辑简单用 queue 没问题,复杂的时候,异步编程风格心智负担太重了。如果异步写起来轻松,就不会搞协程解放双手了。
|
178
jjx 2018-09-17 17:13:52 +08:00
阿里云的 云 ssd 同本地 ssd 性能差距一倍以上
|
179
wawehi 2018-09-17 18:04:45 +08:00
@abcbuzhiming 直接用阿里云 DB, 自建的 DB 远比不上他们建的.
|
180
woostundy 2018-09-17 18:40:04 +08:00
CPU 都没吃满一定是连接数太少了,把服务线程池加大到 CPU 到 80+%
|
181
KingHL 2018-09-17 18:51:52 +08:00
我觉得同步变异步,或者加大线程数可以解决。
|
182
wmlhust 2018-09-17 19:30:37 +08:00
感觉很多时间都浪费在等待数据库返回结果了啊,如果数据库不是瓶颈。那么增加线程数应该是管用的,更好的是同时换成异步的方式。
|
183
ml071987 2018-09-17 19:59:04 +08:00
说实话,单机 500 并发,没加 redis,已经很厉害了
|