nginx

13 Aug

Rewriting URLs for X-Forwarded-Proto and Reverse Proxies

in drupal, nginx, stackato

Reverse proxies and web servers sometimes forward HTTPS traffic to their backends using HTTP. (In other words, they handle the SSL with the client, and the backend only has to handle HTTP). This can provide a speed boost, and is generally a good thing. But smart backend code may need to ensure that the remote client is only making HTTPS requests. (See this Drupal issue, which suggests that the problem impacts Drupal, and that it will not be solved in core).

Some such reverse proxies (I know of Zeus, Stackato, and Nginx) will set a special HTTP header, typically X-Forwarded-Proto or X-Forwarded_Proto. This will have the value https if the client request was over HTTPS, and http if the client used HTTP.

Here's a simple way that a backend Apache server can rewrite a client request to instruct it to only connect via HTTPS:

  RewriteEngine on
 
  # Rewrite to SSL for anything coming off of a proxy.
  RewriteCond %{HTTP:X-Forwarded_Proto} ^http$
  RewriteRule ^(.*) https://%{SERVER_NAME}/$1 [L,R=301]

Of course, the value may also be accessed in PHP using $_SERVER['HTTP_X_FORWARDED_PROTO'].

31 Aug

The Best Tool for Web Page Speed Evaluation

in memcached, nginx, performance

It seems that, for me, this is the year of website performance optimization. From working with nginx and a crazy memcached setup to recently deploying a handful of Varnish servers, I have been deeply entrenched in the world of website page speed optimizations.
Side-by-sideSide-by-side

22 Mar

A 53,900% speedup: Nginx, Drupal, and Memcache bring concurrency up and page load time way down

in drupal, memcached, nginx, performance

With a clever hack utilizing Memcache, Nginx, and Drupal, we have been able to speed the delivery time of many of our major pages by 53,900% (from 8,100 msec to 15 msec, according to siege and AB benchmarks). Additional, we went from being able to handle 27 concurrent requests to being able to handle 3,334 concurrent requests (a 12,248% increase).

While we performed a long series of performance optimizations, this article is focused primarily on how we managed to serve data directly from Memcached, via Nginx, without invoking PHP at all.
Nginx, Memcached, and DrupalNginx, Memcached, and Drupal

Read on for the full explanation of how we achieved this huge speedup.

16 Feb

Why does Nginx return 499 errors?

in nginx, system administration

I noticed something unexpected in my nginx logs today: There were a bunch of 499 HTTP codes in the access log. Oddly, these didn't show up in Google Analytics, there were no corresponding errors in the error log, but they did show up in my AWStats. What's the deal?nginxnginx

The answer is pretty simple: Nginx uses 499 as the status code when the client unexpectedly terminates a connection. (Thus the client may have already received a 200 in the header, AFAIK). This is consistent with the usage of 4xx errors as indicating a client error condition.

A quick calculation showed me that the 499s accounted for only 0.2% of our total traffic. Not bad. And in fact, I sorta like the ability to see how many times clients terminated connections to my server.

11 Feb

Downtime-free Drupal Migration

in drupal, linux, nginx, system administration

In Jauary we migrated a Drupal site that routinely has 40k+ hits per day. We moved the site from servers in the Pacific Northwest to a datacenter in Virginia. As if that wasn't enough, we moved the servers from Apache to Nginx, as well. But what makes this remarkable to me is that we managed to pull this off without so much as a minute of downtime. This blog explains how we did it (and it uses lots of pretty diagrams, too!).

01 Feb

Nginx, tcp_nopush, sendfile, and memcache: The right configuration?

in linux, nginx, system administration

Tuning Nginx ("engine-X") seems to be something of a black art. Today, I looked closely at the tcp_nopush, sendfile, and keepalive_requests settings for pages rendered from PHP as a FastCGI, and memcached content. We discovered that with a little careful tuning, we could shave off as much as 200-400 msec per request.

I have been working on several speed improvements on the Condition Centers at Spine-Health.com. Initially, these pages were taking upwards of 3.5 seconds just to render the HTML. Through a series of optimizations that I will document in another article, we have the conditions page rendering in around 100 msec now.

Before we get going, let me mention a few details of our system:

  • We are running CentOS 5.3 (roughly equivalent to RHEL 5.3)
  • We are running Nginx 0.6, which is behind the current stable, but is the latest in the Fedora EPEL repositories that we use.
  • Since these settings make use of low-level kernel facilities (like TCP_UNCORK), other platforms may differ.