A summary of what I was talking about in a tech community, Slack.
Be careful as it probably contains speculation.
I usually use aiohttp Server when developing web applications in Python.
main.py
from aiohttp import web
from app import app
web.run_app(app)
I almost always create a file like this, and when I run it in a production environment, I just run python main.py
(in a Docker container). It's not difficult, it simply runs a web application.
However, when I was developing a web application in Flask before, I used a server called uWSGI to run it in production.
What is that? Why did you need uWSGI at that time and not this time?
No, I know that WSGI is an interface for web applications and uWSGI is one of its implementations.
Once upon a time, when I was writing a web application in Perl (Amon2) I was using Plack (PSGI server), and when I was writing it in Ruby (Sinatra) I was using Unicorn (Rack server). Languages I've touched in the past have a similar mechanism. But it wasn't in Node.js + Express. [^ pm2] What's the difference between Node.js and other languages?
[^ pm2]: I used to use forever and pm2 for process monitoring, but I ignored them this time because they are different.
To summarize the questions, it looks like this.
-** Why does Perl + Amon2 and Ruby + Sinatra use Plack and Unicorn, but Node.js + Express does not? ** ** -** Why is the same Python web application framework using uWSGI in Flask but not in aiohttp Server? ** **
As far as I understand, the conclusion is ** "because the web application framework speaks or does not speak HTTP" **.
Specifically:
--The application implemented in Amon2 does not speak HTTP (only PSGI is supported) --Applications implemented in Sinatra do not speak HTTP (only support Rack) --Applications implemented in Express speak HTTP [^ express] --Applications implemented in Flask do not speak HTTP [^ flask](only WSGI support) --Applications implemented on aiohttp Server speak HTTP [^ aiohttp]
[^ express]: To be precise, the Express app is served with the standard Node.js http module, but it does not define a unique interface like WSGI, so it says that it speaks HTTP directly. It's no exaggeration (I think) [^ flask]: Flask has a built-in server function (ʻapp.run () `), so it looks like it speaks HTTP, but it's a WSGI server implementation after all, and it's a simple implementation, so it's suitable for production use. No [^ aiohttp]: Since aiohttp Server is a "module that handles HTTP with asyncio" rather than a "web application framework", it's strange that you have to speak HTTP.
Applications that do not speak HTTP cannot run on their own and must be combined with a compatible web server. [^ a]
[^ a]: I was misunderstanding that all of the frameworks listed above can speak HTTP and also support interfaces like WSGI.
So why do frameworks speak or don't speak HTTP?
It seems that it is because "the web server and the web application should be separated (the web application itself does not have to speak HTTP)".
The Web server needs to process a large number of HTTP requests at high speed, and it is costly and wasteful for each framework to implement a server to realize it. Once you have developed an interface like WSGI, you can separate the Web server and Web application and use them in any combination. (Thinking about that, the idea is, "If you speak HTTP anyway, make sure that you can do everything with Nginx, including SSL termination and static content distribution." But I think that the Nginx Unit came out of that idea. Convinced)
So why are Node.js + Express and Python + aiohttp Server speaking HTTP directly without using an interface like WSGI?
The two have something in common, both supporting non-blocking IO with an event loop.
Node.js is an event loop in the runtime itself, and is non-blocking IO regardless of the framework.
Python is a blocking IO language, so a straightforward HTTP-speaking implementation can result in no performance at all, for example, while processing one request, it blocks all other requests. Therefore, we will consider parallel processing in threads and event loops, but if parallel processing is performed under the constraint that there is a GIL, it may be better to do it in event loops than in threads (?). The aiohttp Server is a non-blocking IO of this type because it relies on asyncio (event loop).
What happens if the application itself can handle parallel processing? Even if you implement it by speaking HTTP in a straightforward manner, you can handle requests in parallel normally. After that, you can handle a large number of requests by simply starting multiple processes and load balancing. So you don't have to use WSGI to separate your web server from your web application.
--In web application frameworks such as Ruby and Python, it is difficult to implement a mechanism to handle HTTP requests in parallel, so after formulating an interface like WSGI, the roles are separated by throwing it to other mechanisms (and Seem) --Originally implemented based on non-blocking IO Node.js + Express and Python asyncio, aiohttp Server can perform parallel processing by the application itself, so there is a problem even if you speak HTTP directly without using a mechanism like WSGI. Not (probably)
Recommended Posts