使用 nginx 进行负载平衡时每秒请求数变慢

Ed *_*iot 4 nginx reverse-proxy load-balancing apache-2.2

我已将 nginx 设置为负载平衡器,可将代理请求反向发送到 2 个 Apache 服务器。我已经使用 ab 对设置进行了基准测试,并且每秒收到大约 35 个请求,请求分布在 2 个后端服务器之间(不使用 ip_hash)。令我困惑的是,如果我直接通过 ab 查询任一后端服务器,我每秒会收到大约 50 个请求。

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

知道为什么分布在 2 个服务器上的流量会导致每秒请求数比直接命中更少吗?

附加信息:

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

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

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/*;
}
Run Code Online (Sandbox Code Playgroud)

我有一个虚拟主机(在可用站点中),它将 / 下的所有内容重定向到本地网络的 2 个后端。

Lad*_*ada 5

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

反向代理可能会为每个请求添加一个标头。这使得使用 nginx 时的响应比不使用时稍大。如果您在千兆内部网络上运行它,这可能是一种难以察觉的变化,但如果您是从办公室或家中运行它,特别是如果您使用小文件进行此测试,则额外的数据可能会导致可测量的差异. 当然,小文件在网络上是很正常的,所以小文件可能会成为一个更现实的基准。

缓存还可以对后续运行产生影响,具体取决于您的基准测试的运行方式。这将使您的第一次运行比之后的所有运行都慢。这在负载平衡时更加复杂,因为要预热的缓存数量是原来的两倍。如果您首先测试了 nginx,那可能会导致差异。您可以通过关闭所有缓存或忽略您所做的第一次运行来缓解这种情况。获取所有缓存非常困难,有些甚至可能不受您的控制。我更喜欢忽略第一次运行的方法。您提到您已经使用不同的值进行了多次运行,但是为了避免基于缓存的不准确,您需要做的是连续两次或多次运行完全相同的基准测试并忽略第一次运行。

可能导致这种行为的另一件事是系统中其他地方的锁。“锁”是指一次只有一个网络服务器可以使用的资源。例如,将 PHP 会话存储在数据库的 MyISAM 表中。对 PHP 页面的每个请求要么对该表执行读取请求以查找会话,要么执行写入请求以创建新会话。由于 MyISAM 表具有表级锁定,因此在任何给定时间只有一个 Web 服务器可以使用此表,并且由于每个页面都必须使用此表,因此这完全抵消了拥有两个 Web 服务器的优势。系统的其余部分越快,锁的相对影响就越大。它也不必是数据库,它可以是 SAN 或 NAS 上的共享 webroot,所以即使是静态文件也不能幸免于这种问题。您在原始问题中没有提到任何其他系统,但是随着系统的增长,这个问题很可能会出现。

最后,关于基准测试的一些(它变成了很多)一般建议。您获得特定速度(或此类基准测试的每秒请求数)的原因始终是由于单个瓶颈。Apache 基准测试将尽可能快地继续请求,直到某些资源达到 100% 的利用率。该资源可能是您的网络服务器中的 CPU,也可能是反向代理服务器中的 CPU。然而,这不太可能。早在 CPU 速度成为问题之前,磁盘访问和网络带宽(内部和外部)通常是您遇到的第一个瓶颈。即使您看到资源利用率为 90%,这也不是瓶颈。将有另一个 100% 的地方阻止这个 90% 以上。100% 的可能在不同的系统上,它可能不是您拥有的系统。特定设备,例如交换机或 NIC,甚至是作为网络一部分的电缆。

要找到真正的瓶颈,您应该从一些您可以衡量的值(例如,当前活动的 nginx 工作线程的数量)开始,然后问“为什么这不会更高?” 如果它已达到最大值,那么您就找到了瓶颈。如果没有,您应该查看的下一个位置是连接的请求。上下游还是上下游,全凭直觉。在下游,nginx 将要求网络插槽将请求传递给 Apache。问问自己打开的网络连接数是否达到最大值。然后是网卡的带宽。然后是网络的带宽。然后是Apache机器的网卡带宽。如果答案很明显,您可以跳过其中的一些步骤,但不要只是在系统中随意猜测。使您的任务有序且合乎逻辑。

有时,您遇到的瓶颈将出现在您正在运行的机器上。发生这种情况时,基准测试毫无意义。您所测试的只是您正在运行的机器或网络的速度。您将获得与您的网站相同的 Google 基准测试结果。为了确保您有一个有意义的基准测试,您必须在基准测试运行时找到瓶颈。(或者至少确保它不在测试机器上。)为了提高站点的基准测试,有必要找到系统中的瓶颈并扩大它,这在基准测试运行时最容易做到。

测试像您这样的大型系统意味着瓶颈可能隐藏的位置数量非常多。有时,它可以帮助您将基准测试范围缩小到系统的几个部分。去掉 nginx 并使用 Apache 就是一个例子,在与网络服务器相同的网络中运行基准测试是另一个例子。但是您可以更进一步对单个组件进行基准测试,例如磁盘、网络和 RAM 延迟和吞吐量。

不幸的是,并非所有资源都有很好的简单百分比报告 CPU 和 RAM 使用情况的方式。例如,将一个大文件写入磁盘可能会达到 40MB/s,但是当写入大量小文件并同时读回它们时(例如存储在磁盘上的 PHP 会话),您可能会得到 10MB/s。为了找到资源的真实大小,您必须分别对系统的每个部分运行基准测试。不要以为您拥有千兆交换机就可以通过内部网络获得 1000Mb/s 的速度。IP、TCP 和应用程序级标头(如 NFS 标头)都可以降低这一基准,因为速度较慢的 NIC 和电缆也是如此。硬件错误也会影响各种基准测试,而硬件仍然可以运行,但低于制造商的规格。

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