使用nginx进行负载平衡时,请求速度较慢

我已经将nginx设置为负载均衡器,将代理请求反向代理到2个Apache服务器。 我已经使用ab进行了基准testing,并且每秒获得约35个请求,并在两个后端服务器(不使用ip_hash)之间分配请求。 令我困惑的是,如果我通过ab直接查询后端服务器,那么每秒可以获得约50个请求。

我已经在ab中尝试了许多不同的值,其中最常见的是具有100个并发连接的1000个请求。

任何知道为什么stream量分布在2台服务器上的结果是每秒钟的请求数量比直接打到的要less?

附加信息:

我已经尝试了1到8之间的worker_processes值,1024到8092之间的worker_connections,并尝试了keepalive 0和65。

我的主要configuration目前看起来像这样:

user www-data; worker_processes 1; error_log /var/log/nginx/error.log; pid /var/run/nginx.pid; worker_rlimit_nofile 8192; events { worker_connections 2048; use epoll; } http { include /etc/nginx/mime.types; sendfile on; keepalive_timeout 0; tcp_nodelay on; gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; } 

我有一个虚拟主机(在可用的站点中),通过本地networkingredirect到/ 2后端的所有内容。

并发是我的第一个想法,因为ab中的默认并发是一个,并且添加一个负载平衡器将总是增加请求的等待时间,但您提到您将并发设置为100,所以这不应该是原因。

反向代理可能会为每个请求添加一个头。 这使得使用nginx时的响应稍微大一点。 如果你在千兆内部networking上运行这个程序,可能是一个不可察觉的变化,但是如果你是从你的办公室或家里运行这个程序,特别是如果你使用一个小文件来做这个testing的话,额外的数据可能会导致一个可测量的差别。 当然,小文件在networking上是非常正常的,所以小文件可能会成为一个更现实的基准。

高速caching还可以对后续运行产生影响,具体取决于您的基准testing运行情况。 这将使你的第一次运行比之后的所有运行慢。 当进行负载平衡时,这会更加复杂,因为有两次caching需要预热。 如果你先testing了nginx,那可能会导致不同。 您可以通过closures所有caching或忽略您的第一次运行来缓解这种情况。 得到所有的caching是非常困难的,有些甚至可能不受你的控制。 我喜欢忽略首先运行的方法。 您提到您已经完成了多个具有不同值的运行,但是要避免基于caching的不准确性,您需要做的是连续运行两次或更多次相同的基准testing,而忽略第一次运行。

另一件可能导致这种行为的东西是系统中其他地方的锁。 通过“locking”,我的意思是只有一个networking服务器可以一次使用的资源。 一个例子就是将PHP会话存储在数据库的MyISAM表中。 对PHP页面的每个请求要么在该表上执行读取请求来查找会话,要么写入请求来创build新的会话。 由于MyISAM表具有表级lockingfunction,因此在任何给定的时间,只有一个Web服务器可以使用此表,并且由于每个页面都必须使用此表,所以这可以否定完全具有两个Web服务器的优点。 系统其余部分越快,锁的相对效果就越大。 它不一定是一个数据库,它可能是SAN或NAS上的一个共享的webroot,所以即使静态文件也不能解决这类问题。 您在原始问题中没有提及任何其他系统,但是随着系统的发展,这个问题很可能会出现。

最后,有一点(它变成了很多)关于基准的一般build议。 你得到一个特定的速度(或这种基准每秒的请求数)的原因总是由于一个瓶颈。 Apache基准testing只会尽可能快地进行请求,直到某些资源达到100%利用率。 此资源可能是您的Web服务器中的CPU,也可能是反向代理服务器中的CPU。 但是,这不太可能。 磁盘访问和networking带宽(内部和外部)通常是在CPU速度成为问题之前遇到的第一个瓶颈。 即使你看到90%的资源被利用,这也不是瓶颈。 在100%的地方会有另外一个阻止这个比例超过90%。 100%的人可能在不同的系统上,它可能不是你自己的系统。 它可以是networking,这意味着一个特定的设备 ,如交换机或网卡,甚至是networking的一部分电缆。

要find真正的瓶颈,你应该从可以测量的某个值开始(比如,当前活动的nginx工作者的数量),并询问“为什么这不是更高? 如果已达到其最大值,那么你已经find了你的瓶颈。 如果不是,下一个你应该看看的地方是一个连接请求。 无论你是上游还是下游,都是直觉的本能。 在下游,nginx将要求networking插槽将请求传递给Apache。 问问自己是否开放networking连接的数量是最大的。 然后是网卡的带宽。 那么networking的带宽。 然后是Apache机器的网卡带宽。 如果答案是显而易见的,你可以跳过其中一些步骤,但不要随意猜测你的方式。 使你的任务有序和合乎逻辑。

有时你遇到的瓶颈将会在你正在运行的机器上。 发生这种情况时,基准是毫无意义的。 您所testing的全部是您正在运行的机器或networking的速度。 你会得到相同的结果基准谷歌你会你的网站。 为了确保你有一个有意义的基准,你必须find基准运行的瓶颈。 (或者至less确保它不在testing机器上。)为了提高您的网站的基准,有必要find系统的瓶颈,并扩大它,这是基准运行时最容易做到的。

像你这样testing一个大系统意味着瓶颈可以隐藏的地方数量非常大。 有时它可以帮助将您的基准缩小到系统的几个部分。 去掉nginx并转到Apache就是一个例子,并且在同一个networking上运行你的基准testing,而web服务器是另一个。 但是,您可以进一步对基准组件进行基准testing,如磁盘,networking和内存延迟以及吞吐量。

不幸的是,并不是所有的资源都有很好的简单的百分比来报告CPU和RAM的使用情况。 例如,将一个大文件写入磁盘可能会达到40MB / s,但是当编写大量小文件并同时读取(例如存储在磁盘上的PHP会话)时,您可能会获得10MB / s的速度。 为了find资源的真实大小,您必须分别在系统的每个部分上运行基准testing。 不要以为你有一个千兆交换机就能在你的内部networking上获得1000Mb / s的速度。 IP,TCP和应用程序级别的头文件(例如NFS头文件)都可以像速度较慢的NIC和电缆一样降低这一基准。 硬件错误也会影响各种基准testing,但硬件仍能正常工作,但仍低于制造商的规格。

瓶颈可能在nginx机器上。 如果是这样的话,负载均衡解决scheme比直接单一服务器慢的原因应该是显而易见的。 在这一点上,一些rmalayter的build议将是很好的遵循。 直到你知道瓶颈在哪里,你只是猜测,我们也是。 如果瓶颈是在其他地方,你应该find它,然后回到这里寻找或提出一个更具体的问题。

您正在testing的文件内容有多大?

将nginx中的日志级别转为“警告”,并检查error.log。 您可能会看到有关将代理内容写入磁盘临时文件的警告。 我怀疑你需要增加proxy_buffers数量/大小。 或完全closures代理缓冲。 对于任何合理的现代内容,nginx的默认值都太低了。

使用类似的configuration,我看到来自两个后端IIS框的静态57kB html文件的3700个请求/秒。 都是具有2 GB RAM的单CPU虚拟机。 我有proxy_buffers设置为“proxy_buffers 32 16k;”。 显然,如果你每秒只能看到50个Apache请求,你正在testing一个dynamic页面,对不对?