我正在设置一个对响应时间有严格要求的系统。如果 Apache2 未得到服务,我该如何强制它在 200 毫秒后丢弃队列中的请求?
背景
我们的一项内部服务需要与另一项服务交互。另一项服务要求我们在很短的时间内做出所有响应。对于少量查询,我们能够在所需的时间内处理请求。但是,一旦系统加载了大量请求,响应时间就会受到影响。
由于负载几乎是连续的,我们遇到了交通拥堵的情况,较旧的查询正在排队,然后得到服务,但那时请求已经过期。我如何确保我们在有限的时间内处理请求,或者干脆放弃请求?
答案1
Apachehttpd
有一个超时旋钮,TimeOut
如果客户端没有及时向服务器发送数据(以及其他一些事情),则处理 TCP 发送和接收操作的超时。这是以秒为单位提供的,默认为 300 秒。这是什么惯于做的是超时一个需要 5 秒才能在本地处理的请求。
唯一的排队httpd
是ListenBacklog
对于位于套接字侦听积压任务等待当前繁忙的 httpd 工作线程/子线程拾取。根据 Apache 的说法,它们的“时间”直到它们被工作线程拾取后才开始。您可以使用一个小的ListenBacklog
设置,这样当服务器开始变慢时,新的请求就会被拒绝。实际上,如果您的客户端在 200 毫秒后结束连接,这可能并不重要,因为积压请求永远不会像 http 请求那样正确启动。
只有当您有以下情况时,连接才会进入积压状态:MaxClients
或者ServerLimit
/ThreadLimit
/TheadsPerChild
当前正在使用的连接数。您可以将这些值调低到您的服务能够更好地生存的水平。
否则,请求将由工作子线程/线程处理httpd
,并且不会在不到 200 毫秒的时间内产生 http 响应,我怀疑这就是您遇到的问题。如果响应全部在“处理中”处理,那么httpd
除了修复触发问题的任何因素之外,您无能为力。如果您有一个应用程序在httpd
生成响应的顶部运行,如果httpd
切断连接,它会如何反应?数据库(如果位于下方)如何处理切断的连接?通常,它们会在不知情的情况下继续完成请求,直到它们尝试将数据写回到最后的套接字。处理超时是需要在每个级别的堆栈中处理的事情,以便它能够端到端地工作。
就你所说的水平而言,我认为你需要一些完全不同的东西来httpd
实现你的要求。也许杂种2通过基于队列的工作分配可以处理前端超时更容易吗?也许定制基于事件的 http 服务器可以处理超时吗?正如 David 提到的,即使 TCP 也难以达到您要求的级别。除非您内置了一些可以计算往返时间的智能功能(而 http 没有),否则请求的 TCP 组件甚至不会计入您实现的服务器端应用程序级超时。
答案2
抱歉,这不合理。TCP 根本就不是用来提供低延迟服务的。延迟 ACK 和 Nagle 算法等因素相互作用,使其不适合需要低延迟的应用程序。