背景:客户端(生产者)发一个请求到后端服务器,服务器需要三个步骤来处理这个请求,第一个是网络 io,需要固定 100ms 左右,第二个是 cpu 密集型的,需要 150ms 左右;第三个也是网络 io,需要 50ms 左右,也就是整个过程平均需要耗时 300ms,而且没法减少这个处理时间。
处理:不管怎么优化,一个请求耗时 300ms 左右这个是固定的,异步和线程池之类的只能增大并发量对吧。最好的处理办法是不是线程池阻塞队列满的时候,依靠拒绝策略直接 reject 一些请求?要不然处理连接的线程都是阻塞,导致整个程序很快就没法正常工作了。还想过用消息队列,例如 python 的 lecery,但是考虑下生产者速度远远大于消费者,即使任务全部抛到消息队列,后端线程一个一个去拉消息处理,这样其实后面的任务基本是耗时越来越长对吧。
提问:这种情况只能增加服务器,靠服务器抗住?
PS:如果用异步的话,想问下,三个过程是分别异步,还是在一个线程里面处理好?
1
legendlzy 2018-02-10 10:48:46 +08:00
我觉得要根据业务场景吧,如果业务不允许 reject,那就增加服务器咯,如果是类似于秒送那种,就 reject。。。菜鸡的看法
|
2
CFO 2018-02-10 11:08:58 +08:00 via Android
背压?
|
3
Cbdy 2018-02-10 11:15:16 +08:00 via Android 1
如果不是实时性要求很高的场景,用消息队列解耦。最简单的,生产者一个队列(生产请求),消费者一个队列(消费响应)。这样消费跟不上就可以多加几个消费者实例。记得在数据层控制好数据一致性。。
|
4
ovear 2018-02-10 11:59:59 +08:00 via Android
两个解决方法
提高消费能力(包括消费者数目,消费速度,消费能力 修改模型,采用推拉操作,生产者直接入库,消费者从库中拉出来。当然,会产生堆积。 |
5
feverzsj 2018-02-10 12:05:09 +08:00 1
用 c++重写
|
6
kslr 2018-02-10 13:33:31 +08:00
首先,这要看你这是什么业务,办法还是很多的。
假如你这个数据模式一样,甚至可以丢弃一部分比较旧的。 |
7
wangxiaoer 2018-02-10 13:43:45 +08:00 via Android
用户请求是生产者
应用后台是消费者 生产者远远大于消费者不就是流量过高么,业界主流是加服务器,就是增加消费者数量。 所以有什么可说的呢 |
8
BruceHong 2018-02-10 14:17:24 +08:00
最彻底的解决办法只有一种:增加消费者能力。
|
9
binux 2018-02-10 14:26:57 +08:00 via Android
开流节源
|
10
misaka19000 2018-02-10 14:29:41 +08:00 via Android
如果对实时性要求不高,那就无所谓,慢慢处理就行了;如果有高性能要求,那么就应该用集群提供处理能力,降低延时
|
11
skadi 2018-02-10 15:35:13 +08:00
这种就是性能问题了啊.考虑 c/c++重写关键地方.
|
12
julyclyde 2018-02-10 19:43:30 +08:00
如果你把各项条件都限制死了,那最后就只能是权衡,而不可能解决了
|
13
sen506 2018-02-10 22:55:53 +08:00 via iPhone
你这个主要蛋疼的是有耗 cpu 的操作,这步看下能否单独剥离出去,例如多一个服务专门用线程池来搞,剩下的 io 密集还有与你那个处理 cpu 密集得服务间的通信直接协程或异步搞定。。这样虽然耗时不会减少,但是性能会好很多。。
|
14
sen506 2018-02-10 23:01:10 +08:00 via iPhone 1
另外,你这个耗 cpu 操作的时间太长了,看下怎么优化吧,150ms 的话,单线程 1 秒就只能处理 7 个请求。。
|
15
WinMain OP @sen506 嗯 准备弄两个线程池,一个 max 设置小点专门处理网络 IO,另外一个线程弄多点用来跑 CPU 运算的的试试看。
|
16
cchange 2018-02-11 03:04:35 +08:00 via iPhone
150ms 可否切割成多个小任务 改为轮寻
|