我刚刚使用HAProxy来平衡我的应用程序,它当前运行五个后端应用程序实例。 我的设置是相对简单的。 我有一个使用光纤,EventMachine和瘦的Ruby应用程序尽可能保持非阻塞。 所以大多数请求会很快返回,或者至less不会阻塞应用程序服务器,所以它可以一次处理多个请求。
但是,有一些请求(例如需要访问shell命令的映像上传)可能会很慢并阻止应用程序服务器。
我所发现的是,一种简单的循环式的平衡方式在这里是没有意义的,因为可以同时处理和返回的请求在请求缓慢的情况下被快速回补。 处理这个问题的最好方法是什么?
我考虑过:
有一个频繁运行的健康检查(比方说每250毫秒)来检查服务器是否响应。 如果不是的话,假设它是“down”(很可能会阻塞一个长请求),这将导致HAProxy在它周围发送请求。 但是在这种情况下,所有5个实例都有可能被阻塞。
有一个预先定义的慢请求URL列表,指定2或3个应用程序后端只处理缓慢的请求,并将所有其他请求路由到“快速”后端。 理论上来说,快速请求永远不会被阻塞,但是这种方法似乎更加脆弱,因为我需要确保如果URL改变了,我记得更新我的HAProxyconfiguration。
我认为后一种方法可能是最好的,但是由于devops不是我的强项,我想我会检查一下在这种情况下的最佳做法。
当然,“最佳实践”可能会将所有长时间运行的请求转移到后台任务,但在这种情况下,假设我现在没有时间来处理后续任务:-)
从列A稍微,从列B一点:)
为了正常运行时间,无论如何你都应该在HAProxy中使用健康检查。 如果其中一个后端节点发生故障,您希望HAProxy停止向其发送请求。 失败不一定在你的应用程序中,可能是硬件,networking,不pipe。 这是非常简单的configuration:
option httpchk GET /test HTTP/1.0\r\n
250ms听起来像一个非常频繁的检查。 以这样的速度,你的后端服务器可能花费大量的时间来处理健康检查。 您需要在应用程序开销方面与运行状况检查的成本进行权衡,以及如何快速地让死亡节点脱机。
第二个策略是我以前用过的。 找出您的应用程序可以处理的并发连接总数。 然后,在HAProxy中,将请求分为慢速和快速,并将一定比例的总连接分配给每个请求。 例如,
frontend myfrontend bind *:80 acl url-slow path /some-long-running-request use_backend slow-backend if url-slow default_backend regular-backend backend slow-backend ... server backend1 1.2.3.4:80 maxconn 10 backend regular-backend ... server backend1 1.2.3.4.:80 maxconn 90
所以说,后端1可以处理100个并发连接。 在上面,我们分配了90个连接到“常规”请求和10个连接,以减缓运行请求。 即使你用尽了所有的慢速连接,“常规”请求仍然会被处理。
祝你好运!