构建高性能web之路------web服务器长连接

web服务器都提供长连接的方式,所谓长连接就是客户端一次请求完后,不关闭连接,保持一段时间的连接,下次此客户端再次请求时,不用创建新连接,复用所保持的连接即可。从理论上,长连接可以免去大量建立和关闭连接的资源消耗,但同时也有大量连接被占用的代价。因此可以初步判断长连接比短连接能带来更高的TPS,更低的CPU消耗,更少的IO,更高的内存占用,下面通过实战来验证。

服务器环境和测试工具可以见工具和环境准备篇

本次web服务器选用apache prefork模式,apache长短连接的选择可以配置httpd.conf里的KeepAlive选项,如:

KeepAlive On:长连接

KeepAlive Off:短连接

另外如果选择长连接还需配置KeepAliveTimeout和MaxKeepAliveRequests,其中KeepAliveTimeout为每个长连接服务端保持时长,默认配置为15秒,MaxKeepAliveRequests为每个长连接服务请求最大数,默认配置为100次,本次试验保持默认配置。

使用ab来压apache,如:

短连接环境下: /usr/alibaba/install/httpd-2.0.63-prefork/bin/ab -c 100 -n 1000000 http://localhost/

长连接环境下: /usr/alibaba/install/httpd-2.0.63-prefork/bin/ab -c 100 -n 1000000-khttp://localhost/

同时都已100个并发请求apache默认首页1000000次

然后通过ab测试结果、nmon收集资源消耗和strace跟踪实际调用三个维度来考察短连接和长连接的区别。

1)ab测试结果

短连接:

[python]view plaincopy
  1. ConcurrencyLevel:100
  2. Timetakenfortests:190.754776seconds
  3. Completerequests:1000000
  4. Failedrequests:0
  5. Writeerrors:0
  6. Totaltransferred:1891115351bytes
  7. HTMLtransferred:1456088816bytes
  8. Requestspersecond:5242.33[#/sec](mean)
  9. Timeperrequest:19.075[ms](mean)
  10. Timeperrequest:0.191[ms](mean,acrossallconcurrentrequests)
  11. Transferrate:9681.50[Kbytes/sec]received
  12. ConnectionTimes(ms)
  13. minmean[+/-sd]medianmax
  14. Connect:083.7844
  15. Processing:1103.8979
  16. Waiting:073.0761
  17. Total:4185.717101

长连接:

[python]view plaincopy
  1. ConcurrencyLevel:100
  2. Timetakenfortests:59.509558seconds
  3. Completerequests:1000000
  4. Failedrequests:0
  5. Writeerrors:0
  6. Keep-Aliverequests:990148
  7. Totaltransferred:1927566346bytes
  8. HTMLtransferred:1456007280bytes
  9. Requestspersecond:16804.02[#/sec](mean)
  10. Timeperrequest:5.951[ms](mean)
  11. Timeperrequest:0.060[ms](mean,acrossallconcurrentrequests)
  12. Transferrate:31631.71[Kbytes/sec]received
  13. ConnectionTimes(ms)
  14. minmean[+/-sd]medianmax
  15. Connect:000.1012
  16. Processing:0522.511406
  17. Waiting:0522.411405
  18. Total:0522.511409

从中不然发现,在其他参数和环境相同的情况下,长连接比短连接的TPS高很多,16804.02/sec vs 5242.33/sec,另外也不难发现长连接在connection上花的时间几乎为0

2)nmon的测试结果

cpu消耗:

短连接

构建高性能web之路------web服务器长连接

长连接

构建高性能web之路------web服务器长连接

以上数据表明长连接比短连接消耗CPU较少

IO占用:

短连接

构建高性能web之路------web服务器长连接

长连接

构建高性能web之路------web服务器长连接

以上数据表明长连接比短连接IO占用更少

内存空闲:

短连接

构建高性能web之路------web服务器长连接

长连接

构建高性能web之路------web服务器长连接

以上数据表明长连接比短连接占用更多内存

3)strace结果

apache的prefork模式是每个请求由单独的子进程来响应,因此通过对其中的一个子进程跟踪来比较调用系统资源的次数

短连接:

[python]view plaincopy
  1. %timesecondsusecs/callcallserrorssyscall
  2. --------------------------------------------------------------
  3. 44.240.187941199997accept
  4. 40.220.1708871017738poll
  5. 2.580.01097606771617737read
  6. 2.490.0105830599649994lstat
  7. 2.190.0093190499709994stat
  8. 1.740.007388039976setsockopt
  9. 1.420.00604519997shutdown
  10. 1.250.005312029988close
  11. 1.060.004499019989open
  12. 0.710.003003019994fcntl
  13. 0.570.00242609994write
  14. 0.450.00191109994writev
  15. 0.380.00159809994sendfile
  16. 0.350.00150309997getsockname
  17. 0.340.00143909997gettimeofday
  18. 0.000.00000212fstat
  19. 0.000.00000111lseek
  20. 0.000.00000111mmap
  21. 0.000.00000111munmap
  22. --------------------------------------------------------------
  23. 100.000.42483537531037725total

长连接:

[python]view plaincopy
  1. %timesecondsusecs/callcallserrorssyscall
  2. --------------------------------------------------------------
  3. 37.050.03299739919write
  4. 21.900.01950329940poll
  5. 10.380.009248039676setsockopt
  6. 7.860.0070000495959919stat
  7. 7.460.0066420595149919lstat
  8. 5.350.0047640497209941read
  9. 3.540.003156019839open
  10. 2.270.00201809919sendfile
  11. 1.950.001735019941close
  12. 1.280.00114309919writev
  13. 0.920.00081609921gettimeofday
  14. 0.020.0000140200fcntl
  15. 0.010.0000070100accept
  16. 0.010.0000070100getsockname
  17. 0.010.00000601001shutdown
  18. 0.000.00000212fstat
  19. 0.000.00000111lseek
  20. 0.000.00000111mmap
  21. 0.000.00000111munmap
  22. --------------------------------------------------------------
  23. 100.000.08906128840829780total

以上数据表明,长连接accept和shutdown次数仅为100次,而短连接为9997次,近100倍的差距,从这里就不难发现为什么长连接的TPS那么高了,省了这么多次系统调用,不快才怪啊。

本次试验得出验证来开始的理论分析:长连接比短连接能带来更高的TPS,更低的CPU消耗,更少的IO,更高的内存占用,更少的系统调用