Apache 对于并发请求很慢
Apache is slow with concurrent requests
我目前在 windows 上使用 mod_wsgi 和 python 2.7.10 安装了 apache 运行 web2py。我注意到的是,当我有并发连接时,每个请求的响应时间会增加。这种增加可能从 1 个连接的 20ms 到 5 个并发连接的 200ms。如果我得到最多 20 个并发连接,我的响应时间为 800 毫秒 - 对于一个只有 545 B 的请求,响应时间为 1 秒。
添加像 nginx 这样的前端是否有助于解决这个问题,或者是否可以在 apache 配置中更改某些内容?
我当前的 apache 配置限制是:
Threadlimit 100
ThreadsPerChild 100
MaxRequestsPerChild 10000
AcceptFilter http none
AcceptFilter https none
KeepAlive On
正在执行的代码是:
Javascript:
$(function () {
function refresh(){
$.get('/database/domath_stuff', {num:document.getElementById('mathstuff').innerHTML}, function (response) {
document.getElementById('mathstuff').innerHTML = response
})
}
window.setInterval(refresh, 1000);
});
python是:
def domath_stuff():
number = int(request.vars.num)
number = number + 1
return number
nginx 通常比 Apache 快,但是对于低请求服务器来说这无关紧要。发生这种情况的原因有很多;这是一个非常普遍的事情,称为瓶颈。最简单的解释是,您的应用程序消耗的资源和接受的并发事务比您的服务器能够处理的要多,但是由于您的请求非常低,您可以用一只手来计算它们,显而易见的答案是:您的应用程序很慢。
如果问题出在您的 Python 代码中,那么其他人建议改进的 nginx 服务器根本无济于事。这是因为请求不是在 nginx 中处理的,而是在您使用的任何单独的 Python 网络托管机制中处理的。
Python 应用程序中可能出现问题,原因是应用程序或框架中某些资源的锁定不正确,导致请求处理序列化。 CPU 由于 Python 全局解释器锁,绑定任务也可能导致问题。
由于 Apache MPM 配置不佳,您很可能会加剧问题。您的线程指令值不一致。 ThreadsPerChild
在 1000 是错误的,因为它大于 Threadlimit
。由于 Python GIL 问题,在 Python 应用程序中使用大量线程也是一个坏主意。一个人会倾向于少量线程和多进程。
很遗憾,您正在使用 Windows,这是一个非常不适合 运行 Python 网络应用程序的平台。您的 Apache 无法处理多个进程。
根据您用于测试的 HTTP 客户端,使用 KeepAlive
也可能会使事情复杂化并导致请求序列化。
根据 Graham 的反馈,我切换到 IIS,现在我获得了 20 个并发连接 < 200 毫秒的响应时间,这对我的需求来说还不错。我在设置 IIS 时遵循了 web2py 文档,因此它被配置为 "out of the box" 任何有同样问题的人。
我目前在 windows 上使用 mod_wsgi 和 python 2.7.10 安装了 apache 运行 web2py。我注意到的是,当我有并发连接时,每个请求的响应时间会增加。这种增加可能从 1 个连接的 20ms 到 5 个并发连接的 200ms。如果我得到最多 20 个并发连接,我的响应时间为 800 毫秒 - 对于一个只有 545 B 的请求,响应时间为 1 秒。
添加像 nginx 这样的前端是否有助于解决这个问题,或者是否可以在 apache 配置中更改某些内容?
我当前的 apache 配置限制是:
Threadlimit 100
ThreadsPerChild 100
MaxRequestsPerChild 10000
AcceptFilter http none
AcceptFilter https none
KeepAlive On
正在执行的代码是:
Javascript:
$(function () {
function refresh(){
$.get('/database/domath_stuff', {num:document.getElementById('mathstuff').innerHTML}, function (response) {
document.getElementById('mathstuff').innerHTML = response
})
}
window.setInterval(refresh, 1000);
});
python是:
def domath_stuff():
number = int(request.vars.num)
number = number + 1
return number
nginx 通常比 Apache 快,但是对于低请求服务器来说这无关紧要。发生这种情况的原因有很多;这是一个非常普遍的事情,称为瓶颈。最简单的解释是,您的应用程序消耗的资源和接受的并发事务比您的服务器能够处理的要多,但是由于您的请求非常低,您可以用一只手来计算它们,显而易见的答案是:您的应用程序很慢。
如果问题出在您的 Python 代码中,那么其他人建议改进的 nginx 服务器根本无济于事。这是因为请求不是在 nginx 中处理的,而是在您使用的任何单独的 Python 网络托管机制中处理的。
Python 应用程序中可能出现问题,原因是应用程序或框架中某些资源的锁定不正确,导致请求处理序列化。 CPU 由于 Python 全局解释器锁,绑定任务也可能导致问题。
由于 Apache MPM 配置不佳,您很可能会加剧问题。您的线程指令值不一致。 ThreadsPerChild
在 1000 是错误的,因为它大于 Threadlimit
。由于 Python GIL 问题,在 Python 应用程序中使用大量线程也是一个坏主意。一个人会倾向于少量线程和多进程。
很遗憾,您正在使用 Windows,这是一个非常不适合 运行 Python 网络应用程序的平台。您的 Apache 无法处理多个进程。
根据您用于测试的 HTTP 客户端,使用 KeepAlive
也可能会使事情复杂化并导致请求序列化。
根据 Graham 的反馈,我切换到 IIS,现在我获得了 20 个并发连接 < 200 毫秒的响应时间,这对我的需求来说还不错。我在设置 IIS 时遵循了 web2py 文档,因此它被配置为 "out of the box" 任何有同样问题的人。