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

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

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

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

知道为什么分布在两台服务器上的流量会导致每秒的请求数比直接访问任何一台服务器都要少吗?

附加信息:

我尝试过将 worker_processes 的值设置为 1 到 8 之间,将 worker_connections 的值设置为 1024 到 8092 之间,还尝试过将 keepalive 的值设置为 0 到 65 之间。

我的主要配置目前如下所示:

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/*;
}

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

答案1

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

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

根据基准测试的运行方式,缓存也会对后续运行产生影响。这将使你的第一次运行比之后的所有运行都慢。在负载平衡时,这种情况会进一步加剧,因为需要预热的缓存数量是原来的两倍。如果你先测试了 nginx,那可能会造成差异。你可以通过关闭所有缓存或忽略第一次运行来缓解这种情况。获取所有缓存非常困难,有些缓存甚至可能不在你的控制范围内。我倾向于忽略第一次运行的方法。你提到你已经用不同的值进行了几次运行,但为了避免基于缓存的不准确性,你需要做的是运行一模一样连续进行两次或多次基准测试并忽略第一次运行。

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

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

要找到真正的瓶颈,您应该从可以测量的某个值开始(例如,当前活动的 nginx 工作进程的数量),然后问“为什么这个值没有再增加?”如果它已经达到最大值,那么您就找到了瓶颈。如果没有,您应该查看的下一个地方是连接请求。您是向上游还是向下游走取决于直觉。在下游,nginx 将请求网络插槽以将请求传递给 Apache。问问自己打开的网络连接数是否已达到最大值。然后是 NIC 的带宽。然后是网络的带宽。然后是 Apache 计算机的 NIC 的带宽。如果答案很明显,您可以跳过其中一些步骤,但不要只是随机猜测系统。让您的探索有序且合乎逻辑。

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

测试像您这样的大型系统意味着瓶颈可能隐藏的地方数量相当多。有时,将基准测试范围缩小到系统的几个部分会有所帮助。切断 nginx 并转向 Apache 就是一个例子,在与 Web 服务器相同的网络中运行基准测试是另一个例子。但您可以更进一步,对磁盘、网络和 RAM 延迟和吞吐量等单个组件进行基准测试。

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

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

答案2

您测试的文件内容有多大?

关闭日志记录级别在 nginx 中将其设置为“警告”,并检查 error.log。您可能会看到有关将代理内容写入磁盘临时文件的警告。我怀疑您需要增加代理缓冲区数量/大小。或者完全关闭代理缓冲。nginx 的默认值太低,无法用于任何合理的现代内容。

使用类似的配置,我看到来自两个后端 IIS 框的静态 57kB html 文件每秒有 3700 个请求。所有都是具有 2 GB RAM 的单 CPU 虚拟机。我将 proxy_buffers 设置为“proxy_buffers 32 16k;”。显然,如果您使用 Apache 每秒只看到 50 个请求,那么您正在测试动态页面,对吗?

相关内容