Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I'm currently running apache 2.2.22 on my Ubuntu 12.04 servers. It works fine. I'll be moving them to 14.04 and thus getting apache 2.4.7. I mostly use it for mod_passenger webapps and static sites.

14.04 includes nginx 1.4.6 but I'm sure the phusion guys will package 1.6 soon so I can easily upgrade to that. Is there any killer feature in nginx that I'm missing, staying with apache 2.4?



Generally speaking, nginx is lighter/faster/less flexible (though no less powerful). It really shines on low-RAM VPSes where the RAM eaten up by a big list of httpd processes really adds up.

For example, here are numbers from Apache+mod_passenger on my dev box:

	                         VSW    RSS
	root     20050  0.0  0.1 416524 21020 ?        Ss   Apr18   0:13 /usr/sbin/httpd
	root     13370  0.0  0.0 217068  1984 ?        Ssl  Apr21   0:00  \_ PassengerWatchdog
	root     13373  0.0  0.0 503104  2324 ?        Sl   Apr21   0:04  |   \_ PassengerHelperAgent
	nobody   13381  0.0  0.0 218208  3508 ?        Sl   Apr21   0:00  |   \_ PassengerLoggingAgent
	apache   13388  0.0  0.2 500060 33888 ?        S    Apr21   0:00  \_ /usr/sbin/httpd
	apache   13389  0.0  0.2 500060 33888 ?        S    Apr21   0:00  \_ /usr/sbin/httpd
	apache   13390  0.0  0.2 500060 33888 ?        S    Apr21   0:00  \_ /usr/sbin/httpd
	apache   13391  0.0  0.2 500060 34140 ?        S    Apr21   0:00  \_ /usr/sbin/httpd
	apache   13392  0.0  0.2 500132 33924 ?        S    Apr21   0:00  \_ /usr/sbin/httpd
And those same numbers on one of my production Linode instances, running nginx + passenger:

	                           VSW   RSS
	root     17824  0.0  0.0   7988   328 ?        Ss   Apr10   0:00 nginx: master process
	nobody   31676  0.0  0.5   8732  3248 ?        S    Apr23   0:08  \_ nginx: worker process
	nobody    9103  0.0  0.5   8684  3288 ?        S    Apr23   0:03  \_ nginx: worker process
	nobody    9106  0.0  0.5   8876  3416 ?        S    Apr23   0:04  \_ nginx: worker process
	nobody   22077  0.0  0.4   8400  3004 ?        S    01:23   0:02  \_ nginx: worker process
(yes, I know that ps auxf isn't the best measure of memory usage, but it ballparks to make the point)


Nginx is also non-blocking which is the main difference from Apache. I don't agree Nginx is less flexible, from my own experience it's quite the other way around - try configuring Apache as a reverse proxy, you'll see how "flexible" it really is.


As of 2.4 Apache also supports event-driven serving thanks to the event MPM.

http://httpd.apache.org/docs/2.4/mod/event.html


What's so complicated about:

    ProxyPass url1 url2
    ProxyPassReverse url1 url2
Can it get any simpler than that?

Of course, if you need to fine tune it for performance you are in the advanced category and should know what you are doing, but these two lines are all it gets to configure reverse proxy with sensible defaults.


By "flexible", I primarily mean Apache's module system vs nginx's "compile all the things" approach. Upgrading a component in nginx means recompiling the whole webserver, whereas Apache modules can be managed separately from the httpd executable.

I'm curious about the reverse proxy comment, though; mod_proxy_balancer generally does the job just fine. I do agree that nginx is easier to set up as a reverse proxy, though.


Also, mod_perl essentially lets you write your own Apache modules in Perl with access to a large chunk of the Apache API. It's a little old-fashioned now though.


Having managed a fairly complex apache based web site (lots of rewriting to maintain various legacy url schemes, a few cgi bin apps -- lots of cruft) -- I do think Apache is more flexible than nginx. Traffic server is probably more flexible still. On the other hand, you could say if you take a routing problem, and you attempt to fix it via mod_rewrite -- you now have (at least) two problems! ;-)

There was a fairly recent comparison between nginx and apache2.2/2.4 (and uwsgi and gunicorn, I believe) driven by jmeter for testing that showed apache was a little lower on throughput -- but more consistent on latency (unfortunately I can't seem to find the link again). So while I think it is generally good advice to "just use nginx", I wouldn't write off apache based on how 1.3 used to behave compared to old versions of nginx.

I would normally advice an architecture where you have a reverse proxy in front of application servers (even if that means php with fastcgi) if you can, and when it makes sense. Possibly with ssl termination and/or caching (varnish) in front of that. I'm not sure that using nginx is actually any better than, say, HAproxy -- unless you need a static webserver in addition to your appserver. As always YMMV -- choose the stack that fits your needs.


> I would normally advice an architecture where you have a reverse proxy in front of application servers

My understanding too is that as we containerize more applications (whether this be Jails, Zones or Docker) then for shared-IP addresses (e.g. VirtualHosts) we need a reverse proxy to do the mapping to the correct container.

Do you know anything about this, as my research hasn't found anything?


Well, if you're not using ipv6 it can be a bit tricky to map a (public) ip to each application server/container/whatnot. For web services you need a front-end router/proxy that understands http host headers and/or SNI (for ssl). If you have that, you can map stuff in DNS, and still use just port 80/443 on the "user facing" side:

client sends "host: some.service.example.com" -> proxy (alias for some.service.example.com) routes -> internal-ip:port

If you have enough public ips (be that ipv4 or ipv6) the "proxy" can just be a firewall rule that maps/NATs public-ip:80 to service:80 (or whatever). Not that that is necessarily a good idea.

Virtualhosting and proxying are related to containerizing (containing?) services -- but you could for example set up your reverse proxy in one container, map all traffic there, and then after deciphering host-headers and/or SNI route traffic to different back-ends.

It depends on what your needs are. For low traffic services, simply having the container answer on an external ip might be fine.

If you want to do more sophisticated load-balancing some system needs to take care of that, typically between the client and the back-end server (DNS only allows for round-robin distribution, barring tricks like giving different replies depending on who (from where) is asking).

Personally I'm leaning towards moving my "internal" ip-related stuff to ipv6 and only multihoming my outward facing points to ipv4 -- for simplicity. It does mean I actually have to set up firewall rules again, as most "internal" systems are now technically exposed. I guess it depends on how one draws the line -- does the container manage its own SSL/TLS termination (if applicable)?


Thanks, it's interesting to hear about the different options. I've not even thought about IPv6 yet and the options I'd have using that internally. I'm never going to have enough public IPv4 addresses for the number of containers so something has to happen.


Said link on apache vs nginx (among others):

http://www.atlanticdynamic.com/web-server-performance-analys...


Linode just upgraded me to 2GB RAM for the same price, and apache doesn't seem to be taking all that much RAM. I guess the benefits aren't all that important for my setup. I may as well spend the time improving other things.


Phusion Passenger author here.

Use passenger-memory-stats. It measures the Private Dirty RSS which is a more accurate measure of the actual memory usage because it takes shared memory into amount.


Thanks. I'd forgotten about that. Anyhow, the point remains :)

Production (nginx + passenger)

        17824  1      7.8 MB  0.0 MB   nginx: master process /etc/nginx/sbin/nginx -c /etc/nginx/conf/nginx.conf
	3247   17824  8.3 MB  1.0 MB   nginx: worker process
	3685   17824  8.3 MB  1.0 MB   nginx: worker process
	3696   17824  8.2 MB  0.8 MB   nginx: worker process
	3699   17824  8.2 MB  1.0 MB   nginx: worker process
	### Processes: 5
	### Total private dirty RSS: 3.71 MB

	----- Passenger processes -----
	PID    VMSize    Private  Name
	-------------------------------
	17806  5.5 MB    0.0 MB   PassengerWatchdog
	17809  36.1 MB   2.1 MB   PassengerHelperAgent
	17814  10.9 MB   0.0 MB   PassengerLoggingAgent
	3385   424.6 MB  48.7 MB  Passenger ClassicRailsApp
	### Processes: 4
	### Total private dirty RSS: 50.79 MB
Development (Apache + mod_passenger, no Rails apps running through it at the moment)

        ---------- Apache processes ----------
	PID    PPID   VMSize    Private  Name
	--------------------------------------
	13388  20050  488.3 MB  18.8 MB  /usr/sbin/httpd -DFOREGROUND
	13389  20050  488.3 MB  18.8 MB  /usr/sbin/httpd -DFOREGROUND
	13390  20050  488.3 MB  18.8 MB  /usr/sbin/httpd -DFOREGROUND
	13391  20050  488.3 MB  18.9 MB  /usr/sbin/httpd -DFOREGROUND
	13392  20050  488.4 MB  18.9 MB  /usr/sbin/httpd -DFOREGROUND
	20050  1      406.8 MB  1.1 MB   /usr/sbin/httpd -DFOREGROUND
	### Processes: 6
	### Total private dirty RSS: 95.45 MB

        ----- Passenger processes -----
	PID    VMSize    Private  Name
	-------------------------------
	13370  212.0 MB  0.3 MB   PassengerWatchdog
	13373  491.3 MB  0.3 MB   PassengerHelperAgent
	13381  213.1 MB  0.6 MB   PassengerLoggingAgent
	### Processes: 3
	### Total private dirty RSS: 1.18 MB


I would add "less bloated", but it might be a tastes matter


(my) rule of thumb: unless there's no equivalent for an apache module you need, use nginx instead of apache. For balance, "Don't break what (apache) is working" applies too.


Nginx is much more scalable and utilizes less resources than apache. Apache uses a thread per socket , where as nginx is non blocking and runs with fewer threads .


> 14.04 includes nginx 1.4.6 but I'm sure the phusion guys will package 1.6 soon so I can easily upgrade to that.

Yup. We're working on 14.04 packages too.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: