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程序 | PHP | Python | Java | Node.js | Go |
|---|---|---|---|---|---|
| web框架 | -- | Django | Spring Boot | Express/Koa | Gin/Echo |
| 本地开发 | PHP 5.4及以上版本提供了一个内置的开发服务器 | python manage.py runserver | -- | 直接启动或使用forever/pm2 来启动 | 直接启动 |
| 生产环境 | 依赖 Web 服务器Nginx + PHP-FPM | 依赖 Web 服务器 gunicorn | 基于容器 内置or外置 | 可独立运行 pm2管理进程 | 独立运行 |
| 协议 | FastCGI | WSGI,ASGI |
Python项目的运行模式 Nginx + Gunicorn + Django
再详细了解一下Python项目的运行模式 Nginx + Gunicorn + Django
本地环境:开发环境中,可以使用 Django 提供的内置轻量级服务器,方便调试
命令:
python manage.py runserver
生产环境:Nginx + Gunicorn + Django
- Nginx 作为前端 Web 服务器,处理静态文件请求并转发动态请求到 Gunicorn。
- Gunicorn 使用 WSGI 协议运行 Django 应用,并处理请求。
- 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 进行对比。