Do I need gunicorn for internal async microservices? - http

As far as I read all over the Internet - the best practice for deploying Flask/Django applications is to put the behind a web server such as nginx and bundle them with a pre-fork server such as gunicorn or uWSGI.
This is good for many reasons, such as ssl-termination, protection against HTTP attacks (nginx), forking to threads for concurrency, restarting the application after a memory leak, or other exceptions (gunicron).
I want to deploy an internal API micro-service on sanic with pm2, as it's not customer facing, but rather will only be called from internal services the SSH termination and protection against HTTP attacks is irrelevant, the concurrency is guaranteed by sanic's asyncio nature and the restarting upon exception is handled by pm2.
Do I still need gunicorn and nginx? Can't I just run the application process as is and let it talk directly to its callers?

You absolutely do not need to have gunicorn in front of your stack. Sanic can run just fine without having a web server in front of it since it has its own internal server.
I still would advocate for using nginx to terminate TLS and to handle static files (even though sanic could do both of these), since it is efficient at it.
here's a link to another answer I've given on the same question: https://community.sanicframework.org/t/gunicorn-uwsgi-vs-build-in-http-server/47/2?u=ahopkins

You don't need it. Look at http://supervisord.org/ to start, restart, autorestart, etc. your servies.
That said I use gunicorn and supervisord in conjunction.

Related

How do web servers stay alive?

I am wondering how web servers i.e. Nginx, Flask, Django stay alive and wait for requests. And how I can write my own program which stays alive and waits for a request before launching an action.
The short answer for the overwhelming number of cases involving nginx is systemd service. When you install nginx it sets itself up as a systemd service which is configured to start nginx on boot and keep it running.
You can adapt systemd to load and keep your own services (like Flask, etc.) alive and waiting for requests as well. Here is an article that explains the basics.
An alternative to systemd (which is built into most of the Linux systems you would be using on a server) is supervisord. Like systemd, supervisord can be configured to monitor, start, and keep your service running in the background, waiting for a request.

Running flask server on AWS EC2 with only gunicorn but no nginx

I have a simple flask application deployed on an AWS EC2 instance. The flask app accepts the incoming HTTP request, then do some (potentially heavy and lengthy) computations with the request, and then return the results.
Based on my limited understanding, it is recommended to always use nginx + gunicorn stack for a true flask app. As I try to keep things on the simple side, I just used gunicorn with 8 workers. The app works just fine, as I can query the EC2 instance, and got the result as expected. There is no (or very little) static contents for the app.
As for the traffic, I won't expect many simultaneous requests to the site (maybe ~10 requests at the same time), since it is for internal use. My question is, given my use case, will this (no nginx) harm me in the near future?
have you deployed using Elastic Beanstalk or EC2?
If the later, i recommend for this app using Elastic Beanstalk as it handles a lot of the configuration for you.
From AWS:
Elastic Beanstalk uses nginx as the reverse proxy to map your application to your load balancer on port 80. If you want to provide your own nginx configuration, you can override the default configuration provided by Elastic Beanstalk by including the .ebextensions/nginx/nginx.conf file in your source bundle. If this file is present, Elastic Beanstalk uses it in place of the default nginx configuration file.
Otherwise, at this stage not having NGINX isn't going to affect your App performance however since it's not best practise/future proof, there's no harm in including it. There's a lot of content out there, describing how to do just that.
Cheers!

How to enable a maintenance page on the frontend server while you are restarting the backend service?

I am trying to improve the user experience while a backend service is down due to maintenance, shutdown manually.
We do had a frontend web proxy, which happens to be nginx but it could also be something else like a NetScaler instance. An important note is that the frontend proxy is running on a different machine than the backend application.
Now, for the backend service it takes a lot of time to start, even more than 10 minutes in some cases.
Note, I am asking this question on StackOverflow, as opposed to ServerFault because providing a solution for this problem is more likely to require writing some bash code inside the daemon startup script.
What we want to achive:
service mydaemon stop should enable the maintenance page on the frontend proxy
service mydaemon start should disabled the maintenance page on the frontend proxy
In the past we used to create a maintenance.html page and had nginx configured to check the existence of this page using try, before falling back to the backend.
Still, because we decided to move nginx to another machine we cannot do this and doing this using ssh raises security concerns.
We already considered writing this file to a NFS drive which would be accessible by both machine, but even this solution does not scale for a service that has a lot of traffic. Nginx will end-up trying this for every request, slowing down the responses quite a lot.
We are looking for another solution for this problem, one that would ideally be more flexible.
As a note, we still want to be able to trigger this behaviour from inside the daemon script of the backend application. So if the backend application stops responsing for other reasons, we do expect to see the same from the frontend.

Can Nginx be used instead of Gunicorn to manage multiple local OpenERP worker servers?

I'm currently using Nginx as a web server for Openerp. It's used to handle SSL and cache static data.
I'm considering extending it's use to also handle fail over and load balancing with a second server, using the upstream module.
In the process, it occurred to me that Nginx could also do this on multiple Openerp servers on the same machine, so I can take advantage of multiple cores. But Gunicorn seems to the the preferred tool for this.
The question is: can Nginx do a good job handling traffic to multiple local OpenERP servers, bypassing completely the need for Gunicorn?
Let first talk what they both are bascially.
Nginx is a pure web server that's intended for serving up static content and/or redirecting the request to another socket to handle the request.
Gunicorn is based on the pre-fork worker model. This means that there is a central master process that manages a set of worker processes. The master never knows anything about individual clients. All requests and responses are handled completely by worker processes.
If you see closely Gunicorn is Designed from Unicron, Follow the link for the detail more diff
which show the ngix and unicrom same model work on Gunicron also.
nginx is not a "pure web server" :) It's rather a web accelerator capable of doing load balancing, caching, SSL termination, request routing AND static content. A "pure web server" would be something like Apache - historically a web server for static content, CGIs and later for mod_something.

Can a load balancer recognize when an ASP.NET worker process is restarting and divert traffic?

Say I have a web farm of six IIS 7 web servers, each running an identical ASP.NET application.
They are behind a hardware load balancer (say F5).
Can the load balancer detect when the ASP.NET application worker process is restarting and divert traffic away from that server until after the worker process has restarted?
What happens during an IIS restart is actually a roll-over process. A new IIS worker process starts that accepts new connections, while the old worker process continues to process existing connections.
This means that if you configure your load balancer to use a balancing algorithm other than simple round-robin, that it will tend to "naturally" divert some, but not all, connections away from the machine that's recycling. For example, with a "least connections" algorithm, connections will tend to hang around longer while a server is recycling. Or, with a performance or latency algorithm, the recycling server will suddenly appear slower to the load balancer.
However, unless you write some code or scripts that explicitly detect or recognize a recycle, that's about the best you can do--and in most environments, it's also really all you need.
We use a Cisco CSS 11501 series load balancer. The keepalive "content" we are checking on each server is actually a PHP script.
service ac11-192.168.1.11
ip address 192.168.1.11
keepalive type http
keepalive method get
keepalive uri "/LoadBalancer.php"
keepalive hash "b026324c6904b2a9cb4b88d6d61c81d1"
active
Because it is a dynamic script, we are able to tell it to check various aspects of the server, and return "1" if all is well, or "0" if not all is well.
In your case, you may be able to implement a similar check script that will not work if the ASP.NET application worker process is restarting (or down).
It depends a lot on the polling interval of the load balancer, a request from the balancer has to fail in order before it can decide to divert traffic
IIS 6 and 7 restart application pools every 1740 minutes by default. It does this in an overlapped manner so that services are not impacted.
http://technet.microsoft.com/en-us/library/cc770764%28v=ws.10%29.aspx
http://forums.iis.net/t/1153736.aspx/1
On the other hand, in case of a fault, a good load balancer (I'm sure F5 is) can detect a fault with one of the web servers and send requests to the remaining, healthy web servers. That's a critical part of a high-availability web infrastructure.

Resources