在请求到达服务器之前突然开始经历漫长的等待时间

在请求到达服务器之前突然开始经历漫长的等待时间

我们的 Web 应用每天的浏览量为 2 万到 3 万次,并且还在稳步增长。大约 4 天前,我们突然发现 HTML 加载前需要等待 30 到 40 秒,而前一天的页面加载时间仅为 1 秒。

在 New Relic Synthetics 中,这些时间仅显示为“等待”。通过监控 nginx 日志,我可以看到这些时间对应于传入请求到达服务器所需的时间。

这是一个在 2GB droplet 上运行 Unicorn 和 Nginx 的 Rails 应用。我之前根据这篇文章优化了我的 Unicorn 配置:https://www.digitalocean.com/community/tutorials/how-to-optimize-unicorn-workers-in-a-ruby-on-rails-app,我们的内存使用率往往徘徊在 50% 左右。尽管如此,我还在上面的同一篇日志输出中注意到了一堆这样的内容:

2016/03/15 06:52:36 [error] 9460#0: *1110377 connect() to unix:/tmp/unicorn.streamfeed.sock failed (11: Resource temporarily   unavailable) while connecting to upstream, client: 66.226.75.13, server: streamfeed.com, request: "GET /watch HTTP/1.1", upstream: "http://unix:/tmp/unicorn.streamfeed.sock:/watch", host: "streamfeed.com", referrer: "http://google.com/"

在没有更好的想法的情况下,我认为这可能意味着我们获得的流量超过了我们的 Unicorn 工作者数量所能处理的流量(我们的流量一直在稳步增长,前几天我们刚刚度过了有史以来最忙碌的一天)。所以我将我们的 droplet 升级到 4GB,并将 Unicorn 工作者的数量增加了一倍,但这并没有解决问题——有时我会看到这 11 个错误,有时是 110 个。

这不是我代码优化的问题——请求最终通过后,相关操作仍然需要 1-2 秒才能实际处理(根据 New Relic),包括任何数据库查询。延迟发生在请求到达服务器之前。我们的两个 droplet(应用服务器和数据库)的 CPU 使用率均低于 50%,内存使用率也是如此。Unicorn 日志中没有错误。我尝试了在线找到的每一种调整/优化 nginx 和 unicorn 的方法,但没有任何变化——如果有的话,加载时间会继续增加。我们现在看到处理请求需要等待 40-50 秒,这实际上意味着我们的网站瘫痪了。在这种情况开始发生之前,我很长时间没有更改任何相关设置或代码。我已经将相关文件回滚到这种情况开始发生时的状态,因为我所做的任何调整/更改都没有任何变化。我迫切希望我们的网站再次运行……希望有人能帮忙。

nginx.conf:

upstream unicorn {
  server unix:/tmp/unicorn.streamfeed.sock fail_timeout=0;
}

server {
  server_name www.streamfeed.com;
  rewrite ^(.*) http://streamfeed.com$1 permanent;
}

server {
  listen 80 default_server deferred;
  # server_name example.com;
  server_name streamfeed.com;
  root /home/deployer/apps/streamfeed/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    location ~* \.(js|css)$ {
      add_header Access-Control-Allow-Origin *;
    }
  }

  location ^~ /fonts/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    location ~* \.(ttf|ttc|otf|eot|woff|svg|font.css)$ {
      add_header Access-Control-Allow-Origin *;
    }    
  }

  try_files $uri/index.html $uri @unicorn;
  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://unicorn;
  }

  error_page 500 502 503 504 /500.html;
  client_max_body_size 4G;
  keepalive_timeout 30;
}

独角兽.rb:

root = "/home/deployer/apps/streamfeed/current"
working_directory root
pid "#{root}/tmp/pids/unicorn.pid"
stderr_path "#{root}/log/unicorn.log"
stdout_path "#{root}/log/unicorn.log"

listen "/tmp/unicorn.streamfeed.sock"
worker_processes 11
timeout 60

config.ru:# 此文件由基于 Rack 的服务器用来启动应用程序。

if ENV['RAILS_ENV'] == 'production' 
  require 'unicorn/worker_killer'

  max_request_min =  500
  max_request_max =  600

  # Max requests per worker
  use Unicorn::WorkerKiller::MaxRequests, max_request_min, max_request_max

  oom_min = (240) * (1024**2)
  oom_max = (260) * (1024**2)

  # Max memory size (RSS) per worker
  use Unicorn::WorkerKiller::Oom, oom_min, oom_max
end

require ::File.expand_path('../config/environment',  __FILE__)
run Rails.application

相关内容