我想知道什么是人们使用他们的networking服务常见的背压战略?
想象一下,你的服务在重负载下运行,并且在某个时候负载达到你容量的120%。 你怎么处理这个?
我能想到的最好的策略是开始拒绝连接。 所以,如果一个主机达到了最高容量(例如,所有Apache员工都很忙),我会开始拒绝TCP连接,直到其中一个工作人员释放。 通过这种方式,所有被接受的连接都将被立即处理而不需要排队(所以延迟很小),过多的20%被拒绝,允许负载均衡器重新分配给其他主机或执行任何其他的负载减less策略(例如,redirect到静态/caching内容)。
我认为这种快速的方法比任何排队方式都要优越得多。 小的队列可以吸收短暂的stream量爆炸,但是由于过多的排队,您的系统在重负载下可能会失败。 例如,在没有任何AQM的FIFO队列处理的情况下,当所有处理的请求在客户端已经超时时,它可以进入状态,因此系统不进行前进。
我感到惊讶的是,这个策略听起来并不容易实现。 我的方法是在Web服务器上设置一个小的收听积压,期待所有不适合的连接被拒绝。 但是由于Linux内核2.2的变化,这种策略分崩离析(参见http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html )。
较新的Linux内核无条件地接受你的连接。 SYN-ACK响应被发送到客户端,根本不考虑监听积压大小。 启用tcp_abort_on_overflow选项也没有多大帮助。 这个选项使内核在连接不适合接受队列时发送RST,但此时客户端已经考虑了连接ESTABLISHED并可能已经开始发送数据。
这对HAProxy尤其有问题。 如果连接成功build立,它不会将请求重新发送到其他服务器,因为这个请求可能在服务器上有一些副作用。
所以我想我的问题是:
提前致谢!
回答你的第一个问题:是的。 那么,无论如何,我个人认为,不要个人认为。 问题是,你正试图设置你的TCP栈的限制,而你有自己的负载均衡器前面有很多计数器和选项。 如果将自己限制在TCP堆栈中,那么当遇到这些限制时,会遇到更多的问题。 我会检查并保持loadbalancer本身的限制。 设置会话计数器,或者创build一些健康脚本来validation服务器的健康状况。 在达到限制时,您可以拒绝新的传入请求,或者在将后端设置为已满时将其redirect到另一个服务器。 你被Apache的限制所束缚,而不是你的操作系统或haproxy,所以要尽量远离系统限制,通过控制你的Apache到达它的负载。
我想这也是你的第二个问题。
第三个问题的答案比较复杂,我不认为你想深入这个问题的深处。 在我看来,达到TCP溢出状态在调整服务器以维持高负载和stream量方面已经太过分了。
这是我的两分钱,希望它有帮助。