查看完整版本: New Nginx.conf with optimizations

ELM 2007/11/5 08:37

New Nginx.conf with optimizations

I have been working on optimizing my nginx.conf file as I use it on more and more sites. Thanks to folks on the nginx and mongrel mailing lists for some of these fixes. Main improvements is in gzip of dynamic and other content as well as setting the proxy buffers to 0 and a few improvemets in the proxy header settings. This conf also includes a second vhost for ssl that points to the same mongrel cluster so you can hanlde ssl and non ssl with the same cluster and rails request.ssl? helper will work correctly.

Another big improvement is with static file handling. The credit on this one goes to Zed Shaw. He notcies that the rewrites and regex tests for rails cached pages were getting run for every request including static images. So a request for /images/foo.jpg woudl get served in this manor:

/images/foo.jpg/index.html  # no file found continue
/images/foo.jpg.html  # no file found continue
/images/foo.jpg # good send it!

This is obviously a performance hit for static files as it has two extra regexes and two extra file stats for every static image. Suck, I wish I found this sooner. To fix this all we need to do is add this test right at the top before the other rewrite tests:

      # If the file exists as a static file serve it directly without
      # running all the other rewite tests on it
      if (-f $request_filename) {
        break;
      }

In my benchmarks this does increase the speed of static files about 8%. Also allowing gzip on HTTP 1.0 requests made sure that the proper static assets are gzipped when possible. Also we force all proxied requests to be gzipped if they are the right content type. I also added more gziped content types and corrected a wrong one for javascript.

This is an important lesson about your production environment folks. With regards to what you accept as gospel from someone like me. “Trust but verify”. Zed was trying to track down how to do a custom rewrite for alternate cache directories and so he at my behest turned on the debug logging and consequently saw the rewrites happening on every static file. I haven’t been in the rewrite log for a while since I thought my config was good. So when you get config files from people like me off the net, please trust but verify on your own systems.

This new config is running close to 100 instances of nginx at Engine Yard. Nginx has proven to be an excellent choice for a front end proxy balancer for mongrel. It beats apache in all my tests now as far as non gzipped proxy requests, static file requests and it ties with apache for gzipped proxy requests. And its about 30 times more lightweight then apache.

If you were holding off to try nginx until it was proven out by others then let me tell you it has proven itself to me time and time again already as a very easy to manage, high performance options for rails deployment on mongrel. I don’t personally use apache2.2 right now for anything other than mod_svn for subversion over HTTP. But there is stirring of upcoming support for nginx and svn over webdav so stay tuned. When that happens I will happily drop apache from our rotation entirely. Of course take this with a grain of salt as always, I don’t have to support any php apps or legacy stuff right now, just rails. I haven’t personally used php with nginx yet but I see others getting fantastic results so I am not worried for when I may need it.

All in all this new config file performs significantly better then my old one. Somewhere on the order of 20% total improvement overall over the last config file. I have updated the link to poitn from the old article to the right confi file and I am linking it here again for your enjoyment:

New Nginx.conf[code]# user and group to run as
user  ez ez;

# number of nginx workers
worker_processes  6;

# pid of nginx master process
pid /var/run/nginx.pid;

# Number of worker connections. 1024 is a good default
events {
  worker_connections 1024;
}

# start the http module where we config http access.
http {
  # pull in mime-types. You can break out your config
  # into as many include's as you want to make it cleaner
  include /etc/nginx/mime.types;

  # set a default type for the rare situation that
  # nothing matches from the mimie-type include
  default_type  application/octet-stream;

  # configure log format
  log_format main '$remote_addr - $remote_user [$time_local] '
                  '"$request" $status  $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

  # main access log
  access_log  /var/log/nginx_access.log  main;

  # main error log
  error_log  /var/log/nginx_error.log debug;

  # no sendfile on OSX
  sendfile on;

  # These are good default values.
  tcp_nopush        on;
  tcp_nodelay       off;
  # output compression saves bandwidth
  gzip            on;
  gzip_http_version 1.0;
  gzip_comp_level 2;
  gzip_proxied any;
  gzip_types      text/plain text/html text/css application/x-javascript text/xml application/xml
application/xml+rss text/javascript;


  # this is where you define your mongrel clusters.
  # you need one of these blocks for each cluster
  # and each one needs its own name to refer to it later.
  upstream mongrel {
    server 127.0.0.1:5000;
    server 127.0.0.1:5001;
    server 127.0.0.1:5002;
  }


  # the server directive is nginx's virtual host directive.
  server {
    # port to listen on. Can also be set to an IP:PORT
    listen 80;
   
    # Set the max size for file uploads to 50Mb
    client_max_body_size 50M;

    # sets the domain[s] that this vhost server requests for
    # server_name www.[engineyard].com [engineyard].com;

    # doc root
    root /data/ez/current/public;

    # vhost specific access log
    access_log  /var/log/nginx.vhost.access.log  main;

    # this rewrites all the requests to the maintenance.html
    # page if it exists in the doc root. This is for capistrano's
    # disable web task
    if (-f $document_root/system/maintenance.html) {
      rewrite  ^(.*)$  /system/maintenance.html last;
      break;
    }

    location / {
      # needed to forward user's IP address to rails
      proxy_set_header  X-Real-IP  $remote_addr;

      # needed for HTTPS
      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect false;
      proxy_max_temp_file_size 0;
      
      # If the file exists as a static file serve it directly without
      # running all the other rewite tests on it
      if (-f $request_filename) {
        break;
      }

      # check for index.html for directory index
      # if its there on the filesystem then rewite
      # the url to add /index.html to the end of it
      # and then break to send it to the next config rules.
      if (-f $request_filename/index.html) {
        rewrite (.*) $1/index.html break;
      }

      # this is the meat of the rails page caching config
      # it adds .html to the end of the url and then checks
      # the filesystem for that file. If it exists, then we
      # rewite the url to have explicit .html on the end
      # and then send it on its way to the next config rule.
      # if there is no file on the fs then it sets all the
      # necessary headers and proxies to our upstream mongrels
      if (-f $request_filename.html) {
        rewrite (.*) $1.html break;
      }

      if (!-f $request_filename) {
        proxy_pass http://mongrel;
        break;
      }
    }

    error_page   500 502 503 504  /500.html;
    location = /500.html {
      root   /data/ez/current/public;
    }
  }

  # This server is setup for ssl. Uncomment if
  # you are using ssl as well as port 80.
  server {
    # port to listen on. Can also be set to an IP:PORT
    listen 443;
   
    # Set the max size for file uploads to 50Mb
    client_max_body_size 50M;

    # sets the domain[s] that this vhost server requests for
    # server_name www.[engineyard].com [engineyard].com;

    # doc root
    root /data/ez/current/public;

    # vhost specific access log
    access_log  /var/log/nginx.vhost.access.log  main;

    # this rewrites all the requests to the maintenance.html
    # page if it exists in the doc root. This is for capistrano's
    # disable web task
    if (-f $document_root/system/maintenance.html) {
      rewrite  ^(.*)$  /system/maintenance.html last;
      break;
    }

    location / {
      # needed to forward user's IP address to rails
      proxy_set_header  X-Real-IP  $remote_addr;

      # needed for HTTPS
      proxy_set_header X_FORWARDED_PROTO https;

      proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect false;
      proxy_max_temp_file_size 0;
      
      # If the file exists as a static file serve it directly without
      # running all the other rewite tests on it
      if (-f $request_filename) {
        break;
      }

      # check for index.html for directory index
      # if its there on the filesystem then rewite
      # the url to add /index.html to the end of it
      # and then break to send it to the next config rules.
      if (-f $request_filename/index.html) {
        rewrite (.*) $1/index.html break;
      }

      # this is the meat of the rails page caching config
      # it adds .html to the end of the url and then checks
      # the filesystem for that file. If it exists, then we
      # rewite the url to have explicit .html on the end
      # and then send it on its way to the next config rule.
      # if there is no file on the fs then it sets all the
      # necessary headers and proxies to our upstream mongrels
      if (-f $request_filename.html) {
        rewrite (.*) $1.html break;
      }

      if (!-f $request_filename) {
        proxy_pass http://mongrel;
        break;
      }
    }

    error_page   500 502 503 504  /500.html;
    location = /500.html {
      root   /data/ez/current/public;
    }
  }


}[/code]

ELM 2007/11/5 08:37

From: [url]http://brainspl.at/articles/2007/01/03/new-nginx-conf-with-optimizations[/url]
页: [1]
查看完整版本: New Nginx.conf with optimizations