Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

gunicorn + nginx: Server via socket or proxy?

I've seen two strategies for hosting a django application with gunicorn and nginx.

One strategy is to run gunicorn on a network port. For example (from http://goodcode.io/blog/django-nginx-gunicorn/):

location / {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_connect_timeout 10;
    proxy_read_timeout 10;
    proxy_pass http://localhost:8000/;
}

Another strategy is to bind gunicorn to a UNIX socket on startup (e.g. http://michal.karzynski.pl/blog/2013/06/09/django-nginx-gunicorn-virtualenv-supervisor/)

upstream hello_app_server {
    server unix:/tmp/gunicorn.sock fail_timeout=0;
}

...

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    if (!-f $request_filename) {
        proxy_pass http://hello_app_server;
        break;
    }
}

Thoughts on which strategy is superior? Any any comments on the proper way to do each? I am leaning towards the socket approach because of the overhead I imagine is introduced by TCP. I am most concerned about the differences about headers, connect timeouts and such between implementation examples I have seen.

like image 971
masonjarre Avatar asked Nov 11 '13 21:11

masonjarre


People also ask

How does Gunicorn work with Nginx?

Nginx and Gunicorn work together Gunicorn translates requests which it gets from Nginx into a format which your web application can handle, and makes sure that your code is executed when needed. They make a great team! Each can do something, which the other can't.

Is Gunicorn a proxy?

Gunicorn is designed to be an application server that sits behind a reverse proxy server that handles load balancing, caching, and preventing direct access to internal resources.

Is Nginx needed for Gunicorn?

Although there are many HTTP proxies available, we strongly advise that you use Nginx. If you choose another proxy server you need to make sure that it buffers slow clients when you use default Gunicorn workers. Without this buffering Gunicorn will be easily susceptible to denial-of-service attacks.


4 Answers

Besides the small TCP/IP overhead, there's not much of a difference. Each listen() socket gets a connection queue, and accept() just pops a connection from that queue. In gunicorn each worker just pops a new connection from that queue as its able so that won't change. The difference is performance (sockets being a bit faster) and portability (port:IP is more flexible). Unix domain sockets will give you a bit better performance, while a socket connected to localhost gives you a bit better portability if you move the server app to a different OS, you can do so by just changing the IP address from localhost to a different hostname.

like image 123
radtek Avatar answered Oct 06 '22 22:10

radtek


Here are the results of my test TCP Proxy via Unix socket:

Setup: nginx + gunicorn + django running on 4 m4.xlarge nodes on AWS. Setup of each node is uniform (from the same image).

1 million of requests are made over about 30 minute window:

4 m4.xlarge instances running TCP Proxy vs. Unix socket

One instance is at 100% CPU because of unrelated job running on one of the servers. 3 others are 70% CPU each represent real application load.

TCP vs. socket is virtually identical

Timing for making 1000000 requests

is 27 minutes for TCP proxy

and 31 minutes for the unix socket.

In this particular setup no unix socket performance advantage.

like image 35
dovka Avatar answered Oct 06 '22 22:10

dovka


Socket traffic will be an easy choice if both your webserver and app server(wsgi) exist on the same machine. However you will need network ports over network connections as sockets cannot work over network so..

  1. If webserver and appserver lie on same machine - GO SOCKET
  2. If webserver and appserver are on network - GO PORTS
like image 22
Kashif Siddiqui Avatar answered Oct 06 '22 22:10

Kashif Siddiqui


would prefer socket traffic over TCP/IP since no extra port is needed to be open. the less ports open the the more hardened your system becomes

as suggested here "be paranoid" https://hynek.me/talks/python-deployments/

"UNIX file sockets with restrictive permissions are your friends. And you can stop coming up with port numbers"

like image 8
infinityLoop Avatar answered Oct 06 '22 23:10

infinityLoop