我读过关于龙卷风的文章:
另一方面,如果您已经有了WSGI应用程序并希望运行它在炽热的龙卷风上httpserver.httpserver,用龙卷风。wsgi.wsgi容器。但你需要小心。自从你原始应用程序不是为异步服务器准备的,并且将进行大量IO/计算,它将阻止其他请求,同时生成响应(将接受并缓冲进一步的请求但是排队等待稍后的处理)。
Guincorn说:
用于UNIX的Python WSGI HTTP服务器。这是一个前叉工人模型移植自Ruby的Unicorn项目。
- 那么Gunicorn将生成工作进程来处理请求
- 每个员工一个同意请求
- 龙卷风将使用
epoll
或kqueue
在一个过程中完成工作(没有主/工人过程) - 因此,如果我使用阻塞调用(如处理程序的get/post函数中的
requests.get
),这将阻塞所有请求处理,还是只阻塞正在处理的当前请求
如果您在Tornado之上运行WSGI应用程序,那么Tornado和gunicorn之间没有太大区别,因为只要应用程序在特定过程中处理WSGI请求,就不会发生任何其他事情。在gunicorn的情况下,因为它只有一个线程来处理请求,在Tornado的情况下因为主事件循环在这段时间内永远无法运行来处理任何并发请求。
在龙卷风的情况下,实际上还有一个隐患。
对于gunicorn,由于只有一个请求线程,工作进程一次只接受一个web请求。如果有并发请求到达服务器,它们将由任何其他可用的工作进程处理,因为它们都共享同一个侦听器套接字。
不过,对于Tornado,WSGI应用程序下的层的异步特性意味着一个进程可以同时接受多个请求。它们最初将在读取请求标头和内容时交错,Tornado在调用WSGI应用程序之前将其预先读取到内存中。当整个请求内容被读取后,控制权将移交给WSGI应用程序来处理该请求。与此同时,由尚未读取请求标头和内容的同一进程处理的并发请求将被阻止,直到WSGI应用程序处理第一个请求为止。
现在,如果你只有一个Tornado进程,这没什么大不了的,因为请求无论如何都会串行化,但如果你使用gunicorn的Tornado工作模式,以便使多个Tornadon工作进程共享相同的侦听器套接字,这可能会非常糟糕。这是因为异步层导致的单个进程的贪婪性质,意味着当可能有另一个工作进程可以处理请求时,请求可能会在进程中被阻止
总之,对于单个Tornado web服务器进程,您一次只能处理一个请求。在gunicorn中,您可以有多个工作进程来允许并发处理请求。不过,使用Tornado的多进程设置可能会导致请求被阻止。
因此,Tornado对于非常小的自定义WSGI应用程序来说是非常好的,因为它们做得不多,所以响应非常快,但如果在阻塞的WSGI应用软件下运行长时间的请求,它可能会受到影响。因此,Gunicorn会更好,因为它具有处理并发请求的适当能力。由于gunicorn是单线程的,需要多个工作进程,因此它将使用更多的内存。
因此,它们都有折衷方案,在某些情况下,使用通过多线程和多个工作进程提供并发性的WSGI服务器会更好。这允许您处理并发请求,但不会因为需要许多工作进程而耗尽内存使用。同时,您需要在使用多个进程的情况下平衡每个进程的线程数,以免在CPU密集的应用程序中受到GIL的影响。
具有多线程功能的WSGI服务器的选择包括mod_WSGI、uWSGI和女服务员。对于女服务员来说,尽管你只限于一个工人的过程。
总之,哪个是最好的WSGI服务器在很大程度上取决于web应用程序的具体情况。没有一个WSGI服务器在所有方面都是最好的。