由于Python中GIL的存在,所以为了提高并发通常使用多进程运行web程序,那么在uwsgi中该将process设置成多少呢,查阅网上,一般都是设置4个进程2个线程,还有的建议将进程数设置为CPU核心数的两倍。我们分析一下:假设一次http请求响应时间是50ms,那么在单个进程的情况下,一秒最多处理20个请求,如果有n个进程同时处理,那就是1秒内能20*n个请求。但是要注意,进程数可不是随意设置的,当你的电脑有4个核心时,你开4个进程,可以将CPU全部利用上,开的再多,由于没有更多的核心去运行进程,所以这些进程并不能同时运行,只能每个执行一段时间后,让其他进程运行,这样也就增加了单个请求的响应时间,比如设置成将uwsgi设置为8进程,这时平均响应时间大约在100ms。所以,在处理并发的时候,要考虑响应时间。在响应时间一定的情况下,单个http请求的响应时间越小,能够处理的并发越大。
下面做测试验证一下
测试机器:i5-3210(双核四线程) 内存(6G)单次http请求响应时间大约16ms (该接口基本不涉及磁盘IO,所以uwsgi没有使用多线程)
这里需要注意:上面的CPU可以理解成是四核心,但是性能会比真正的四核有损失,大约30%,具体百度。
设置uwsgi进程数为4,用ab测试,在2个、4个、8个并发的情况下的响应时间和QPS,理论上响应时间大约为
16 、 23 、45 。我们看一下实际情况:
这是并发为2的情况:
Concurrency Level: 2
Time taken for tests: 0.896 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 1157000 bytes
HTML transferred: 1119100 bytes
Requests per second: 111.55 [#/sec] (mean)
Time per request: 17.929 [ms] (mean)
Time per request: 8.964 [ms] (mean, across all concurrent requests)
Transfer rate: 1260.40 [Kbytes/sec] received
这是并发为4的情况:
Concurrency Level: 4
Time taken for tests: 0.638 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 1157000 bytes
HTML transferred: 1119100 bytes
Requests per second: 156.84 [#/sec] (mean)
Time per request: 25.504 [ms] (mean)
Time per request: 6.376 [ms] (mean, across all concurrent requests)
Transfer rate: 1772.09 [Kbytes/sec] received
这是并发为8的情况:
Concurrency Level: 8
Time taken for tests: 0.636 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 1157000 bytes
HTML transferred: 1119100 bytes
Requests per second: 157.19 [#/sec] (mean)
Time per request: 50.894 [ms] (mean)
Time per request: 6.362 [ms] (mean, across all concurrent requests)
Transfer rate: 1776.05 [Kbytes/sec] received
可以看到上图基本验证了我的猜测。并且在并发为4的时候就达到了QPS的最高值,此时再继续增大并发,只会增加单个http请求的响应时间。我们在保证响应时间在200ms的情况,通过上面的数据,估计最高并发大约为30 ,接着去验证一下:
Concurrency Level: 30
Time taken for tests: 0.649 seconds
Complete requests: 100
Failed requests: 0
Total transferred: 1157000 bytes
HTML transferred: 1119100 bytes
Requests per second: 154.10 [#/sec] (mean)
Time per request: 194.679 [ms] (mean)
Time per request: 6.489 [ms] (mean, across all concurrent requests)
Transfer rate: 1741.15 [Kbytes/sec] received
因为,以后在设置uwsgi参数时,将process设置为CPU的核心数就可以了,如果涉及到从磁盘读取数据的情况,可以考虑加上线程。如果想增大并发能力就要办法降低单个http请求的响应时间。