跳到主要内容

web 服务启动模式(PHP, Node, Python, Go, Java)

十年前上大学的时候,图书馆里、网络上到处都是 LAMP 的黄金组合,Linux+Apache+MySQL+PHP;而如今十年过去了,Linux 和 MySQL 的市场依旧不错,而 Apache 和 PHP 已经渐近明日黄花。

了解这几种项目的运行方式​

当时PHP启动时需要 Apache 或者 Nginx 搭配 php-fpm 来运行;不是很了解 fpm 和 FastCGI 是什么东西,没有深究;

后来用 Node.js 启动服务,就没有类似fpm的模块,而是使用 pm2 进行服务部署,不用也可以,反正前面是Nginx,后面是Node.js ,通过HTTP反向代理来链接;

而如今用 Django 写 Python 服务,有遇到了类似 FastCGI 的东西,WSGI 协议,本地开发时使用 python manage.py runserver 来启动项目,生产环境则使用 gunicorn main.wsgi 来运行,奇怪这又是什么,明明可以直接启动,用 gunicorn 有啥用。

同时我还在写 Go 项目,go就没那么多事儿,build生成二进制文件,直接运行即可。

还有就是国内市场份额最高的 Java 项目,并不是特别了解,早年SSH项目,用tomcat容器运行;现在主流是 Spring Boot 更推荐把容器跟项目打包在一起打成jar包,直接运行。

上面说了五种常见的语言或运行环境:PHP, Node.js, Python, Go, Java。或多或少接触过,感觉大致可以分成两类,Node.js 和 Go,内置 http 模块,独立启动运行;另一类 PHP, Python, Java 需要单独的 http 模块或容器来协助运行,或者它们本身也有简单轻量级的http服务,可以本地开发使用,不宜用在生产环境。

Web程序PHPPythonJavaNode.jsGo
web框架--DjangoSpring BootExpress/KoaGin/Echo
本地开发PHP 5.4及以上版本提供了一个内置的开发服务器python manage.py runserver--直接启动或使用forever/pm2 来启动直接启动
生产环境依赖 Web 服务器Nginx + PHP-FPM依赖 Web 服务器 gunicorn基于容器 内置or外置可独立运行 pm2管理进程独立运行
协议FastCGIWSGI,ASGI

Python项目的运行模式 Nginx + Gunicorn + Django​

再详细了解一下Python项目的运行模式 Nginx + Gunicorn + Django

本地环境:开发环境中,可以使用 Django 提供的内置轻量级服务器,方便调试

命令:python manage.py runserver

生产环境:Nginx + Gunicorn + Django

  1. Nginx 作为前端 Web 服务器,处理静态文件请求并转发动态请求到 Gunicorn。
  2. Gunicorn 使用 WSGI 协议运行 Django 应用,并处理请求。
  3. Gunicorn 将响应返回给 Nginx,Nginx 将其发送到客户端。

Gunicorn 是什么​

  • Gunicorn 是一个 Python WSGI HTTP 服务器,
  • Gunicorn 实现了 WSGI 标准,可以托管任何兼容 WSGI 的 Python Web 框架。
  • Gunicorn 非常轻量级,易于配置且运行效率高。
  • Gunicorn 支持多进程模式,使用预创建的工作进程池处理多个请求,充分利用多核 CPU,提高并发能力。

Gunicorn 的运行方式基于 主进程-工作进程模型:​

  • 主进程:
    • 管理工作进程的启动、停止、和重启。
    • 监听指定的端口,并将请求分发给工作进程。
  • 工作进程:
    • 处理 HTTP 请求和响应。
    • 通过 WSGI 协议与 Python 应用程序交互。

看完这些光鲜的特点,我去看了一眼他的代码仓库,99.9%的Python代码,那我产生了大大的疑问,Gunicorn 也是用python写的,为什么不能在 Python 原生或者 Django 项目中直接实现 Gunicorn 的功能,而是要他单独拿出来。

后来一顿查询才明白,有以下几个原因。

  • Gunicorn 使用 多进程模型 来规避 GIL 的限制,使每个进程独立运行,充分利用多核 CPU 性能。GIL(Global Interpreter Lock) 是 Python 的 CPython 实现中的一个限制,阻碍了多线程的并行计算。
  • 多进程管理能有效防止单点故障;即使某个工作进程崩溃,主进程会自动重启它,从而保证服务的稳定性。
  • **充分利用系统的高效 IO。**Gunicorn 不直接处理低层次的网络通信,而是依赖操作系统和第三方库(如 select、epoll 或 kqueue 等),这些库是经过高度优化的,用于高效处理并发网络请求。
  • 主进程的设计是事件驱动的,这种模型高效且占用资源少。

进程管理有点儿像Nginx的模式,事件驱动和异步IO 则在 Nginx和 Node.js 中都有广泛应用。

时间不早了,今天就先到这儿,后面再学习一下 Gunicorn 的源码,与 Nginx 和 Node.js 进行对比。