用于 Python Web 应用程序开发的 WSGI、uWSGI 和 uwsgi 简介
1。概述
WSGI,uWSGI 和 uwsgi 是三个相关的概念。它们是 Web 应用程序开发中使用的不同工具和协议。下面是他们的详细介绍:
WSGI(Web Server Gateway Interface)
:WSGI是Python Web应用程序与Web服务器和服务器之间的接口规范,它定义了它们之间的应用程序允许应用程序可以在不同的 Web 服务器上运行。 WSGI 规范指定了应用程序必须实现且服务器必须支持的接口方法。 WSGI协议允许不同的Python Web框架(如Flask、Django等)运行在不同的Web服务器上,可以是Apache、Nginx等。uWSGI♼❝ Web服务器。它是一个用C语言编写的Web应用容器,支持运行Python、Ruby、Perl等编程语言。 uWSGI服务器可以作为独立的应用程序服务器,也可以与其他Web服务器(例如Nginx、Apache)一起使用,通过WSGI协议与Python应用程序进行通信。
uwsgi
:uwsgi 是与 uWSGI 服务器相关的协议。 uwsgi协议是一个二进制协议,定义了uWSGI服务器和应用程序之间的通信协议。使用 uwsgi 协议,uWSGI 服务器可以与 Python 应用程序进行通信,而无需启动新进程来处理 CGI 发出的每个请求。 uwsgi协议允许uWSGI服务器和应用程序之间进行双向通信,从而提高性能。
所以,uWSGI是一个Web服务器,可以通过WSGI协议与Python应用程序通信,并使用uwsgi协议进行通信。 WSGI是Python Web应用程序和Web服务器之间的接口规范,它定义了应用程序和服务器之间的标准接口。而uwsgi是uWSGI服务器和应用程序之间的二进制通信协议。
2。安装uwsgi模块
uWSGI是一个Web服务器网关接口,可用于将Python Web应用程序与Web服务器(例如Nginx或Apache)集成。
- 使用uWSGI模块时,必须安装
uwsgi
模块,在uws thegi Web应用程序提供的Python功能模块中导入uwsgi
模块,并使用uws thegi Web应用程序。并管理Web应用程序的运行。常见的uwsgi模块函数有uwsgi.optin()、uwsgi.route()、uwsgi.applications()等。 - 此外,uWSGI模块还提供了一些高级功能,如Master/Worker模式、进程管理、负载均衡、自动扩展等使Web应用能够更好地适应高并发、高流量的情况。
1)配置pip源
国内源地址:
- pypi清华大学源:https://pypi.tuna.tsinghua.edu.cn/simplecent.cloud.tencent.com/pypi/ simple
- pypi阿里源码:https://mirrors.aliyun.com/pypi/simple/
mkdir ~/.pip/
cat >~/.pip/pip.conf<<EOF
[global]
index-url = https://repo.huaweicloud.com/repository/pypi/simple
trusted-host = repo.huaweicloud.com
timeout = 120
EOF
2)安装uwsgi模块
# 安装python3
yum -y install python3
yum -y install gcc-c++ -y
yum -y install python3-devel -y
# 安装 uwsgi flask 模块
pip3 install uwsgi flask
# 查看版本
uwsgi --version
3.示例演示(uWSGI + Nginx配置)
1)安装nginx
yum update -y
yum install epel-release
yum -y install nginx
2)创建app.py文件
创建一个名为app.py
的文件,并放入以下配置:)创建
创建一个uWSGI配置文件,例如uwsgi .ini
,包含以下信息:
[uwsgi]
module = app:app
# 相当于命令下面两行
#wsgi-file = app.py # 项目入口文件
#callable = app # flask应用对象
# 支持http+socket两种方式,这里选用socket,也可以选择http-socket,下面会讲解这三种区别
# http = 127.0.0.1:8000
socket = 0.0.0.0:8000
# 也可以使用socket文件,在nginx配置文件中配置也对应,仅限本机通信,一般也很少使用
# socket = /app/myapp.sock
# 注意记得提前创建目录
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log
uwsgi.ini 常用配置参数详细说明:
[uwsgi]
module = app:app
# 相当于命令下面两行
#wsgi-file = app.py # 项目入口文件
#callable = app # flask应用对象
# 支持http+socket两种方式,这里选用socket,也可以选择http-socket,下面会讲解这三种区别
# http = 127.0.0.1:8000
socket = 0.0.0.0:8000
# 也可以使用socket文件,在nginx配置文件中配置也对应,仅限本机通信,一般也很少使用
# socket = /app/myapp.sock
# 注意记得提前创建目录
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log
uwsgi.ini。 =/xxx /xxx # 指定项目目录。这里写下程序的根目录(即文件app.py
所在目录)对应上面的目录结构,为src
home= #指定虚拟环境变量
wsgi-file
=xxx # 指定加载 WSGI 文件 socket
=xxx # 指定你的 Socket 客户端连接的路径(whsgi 客户端是一个 UNIX 套接字) )或地址(当使用网络地址时)。 #socket协议用于与nginx通信。该端口可配置为其他端口;如果在uwsgi之前使用nginx作为代理,则需要配置socket,如:socket=0.0.0.0:5000。当然也可以使用http-socket
#如果客户端请求不经过(不搭建)Nginx代理服务器,服务请求直接到uwsgi服务器,则配置http.例如:http=0.0.0.0:5000; IP和端口与项目的启动文件app.py匹配;虽然127.0.0.1代表本地IP,但如果要在网络上访问,必须设置host=0.0.0.0以避免IP限制。callable
=app # 这个app指的是bottle项目启动程序中定义的bottle名称name。我的启动程序是 app.py ,其中定义的 Flask 的名称是 app 。 module
= mysite.wsgi # 加载一个 WSGI 模块,这里加载 mysite/wsgi.py 模块 threads
=2 # 设置每个工作进程的线程数vacuum
=true # 服务器终止时自动删除unix套接字文件和pid日志文件-mod file = 644 #指定日志文件的权限daemonize
=%(chdir)/xxx.log # 进程在后台运行,将日志打印到指定文件❀p =%(chdir)/xxx. pid # 在失去权限之前,将主进程pid写入指定文件 uid
=xxx # uWSGI服务器运行时的用户ID gid♼ =xxx # uWSGI服务器运行时的用户ID uWSGI server is running User group id
procname-prefix-spaced
=xxx # 指定worker进程名的前缀 chdir
=/x 指定项目目录,这里写程序的根目录(即app.py
文件所在目录)对应上面的目录结构: /opt/uwsgi/❙list = 120 # 设置socket的监听队列大小(默认: 100)
4) 启动uWSGI
在命令行启动uWSGI :
uwsgi --ini uwsgi.ini
###或者
uwsgi uwsgi.ini
### 重启
uwsgi --reload /opt/myapp/myapp.pid
###关闭
uwsgi --stop /opt/myapp/myapp.pid
插入 【温馨提示】其实你也可以通过带有相应参数的命令来启动,但不建议和可以测试。通常,配置文件用于启动服务。
使用http协议启动uwsgi的命令为:
uwsgi --http :8000 --ini uwsgi_conf.ini -d ./uwsgi.log --pidfile=uwsgi.pid
--http
指定端口5800启动http协议--ini-d配置-d上面指定记录到uwsgi以简化我们的调试
--pidfile
将启动的进程号写入uwsgi.pid所以我们必须停止服务器。 ?
和uwsgi_param QUERY_STRING $query_string; uwsgi_param REQUEST_METHOD $request_method; uwsgi_param CONTENT_TYPE $content_type; uwsgi_param CONTENT_LENGTH $content_length; uwsgi_param REQUEST_URI $request_uri; uwsgi_param PATH_INFO $document_uri; uwsgi_param DOCUMENT_ROOT $document_root; uwsgi_param SERVER_PROTOCOL $server_protocol; uwsgi_param REQUEST_SCHEME $scheme; uwsgi_param HTTPS $https if_not_empty; uwsgi_param REMOTE_ADDR $remote_addr; uwsgi_param REMOTE_PORT $remote_port; uwsgi_param SERVER_PORT $server_port; uwsgi_param SERVER_NAME $server_name;
【特别提示】
uwsgi_params
附带了nginx的conf文件夹。 uwsgi_pass必须与uwsgi_conf.ini中写入的地址完全相同。6) 重启Web服务器
重启Web服务器以使配置生效。
# 重启 systemctl restart nginx # 如果是之前nginx服务已经存在,只是修改了配置,可建议使用reload加载 nginx -t && nginx -s reload # 或者 systemctl reload nginx
访问(浏览器访问,curl访问也可以)
7)Nginx上游负载均衡
Nginx上游(上游)是指一组可以与Nstx服务器和客户端通信的后端服务器。转发到这些服务器。换句话说,上游服务器是Nginx代理请求的后端服务器。
Nginx的upstream支持5种分配方式,其中轮询(默认)、权重、IP Hash、自然是Nginx支持的分配方式,公平
url_hash
是第三方支持的分发方法。1。轮询(默认)
轮询是上游默认的分配方式,即每个请求按照时间顺序分配到不同的后端服务器。如果后端服务器出现故障,可以自动将其删除。
upstream backend { server 192.168.182.110:8000; server 192.168.182.111:8000; }
2。 Weight(权重)
轮询的改进版本。您可以指定投票比例。 权重与访问概率成正比。主要用于后端服务器异构的场景。 ?服务器可以解决会话一致性问题。
upstream backend { ip_hash; server 192.168.182.110:8000 weight=1; server 192.168.182.111:8000 weight=2; }
首先在另一个节点上启动 uWSGI 服务,并更改上面的示例配置:
# vi /etc/nginx/conf.d/myapp.conf upstream backend { server 192.168.182.110:8000; server 192.168.182.111:8000; } server { listen 8080; server_name myapp.com; location / { include uwsgi_params; uwsgi_pass backend; } }
192.168.182.110 节点
app.py
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello, World 192.168.182.110!\n' if __name__ == '__main__': app.run()
192。 app.py
from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello, World 192.168.182.111!\n' if __name__ == '__main__': app.run()
确认
curl 127.0.0.1:8080
从上图可以看出,勘察规划就是企业普遍想要的效果,负载均衡。 ? (例如Apache、nginx)直接暴露在公网,则使用http
;- 如果是单独的服务器(如 Apache 或 nginx),服务器会将请求转发给 uwsgi 进行处理,使用
http
协议,然后使用http-sock。 ? 进程和uwsgi协议在
worker
之间使用。 http-socket
:不生成http进程。通常在前端Web服务器不支持uwsgi
而仅支持http时使用。它生成的worker使用http协议。- 因此,
http
一般用作独立分发选项;当前端Web服务器不支持uwsgi时,使用http-socket
。如果前端Web服务器支持uwsgi,直接使用socket即可。 (TCP 或 Unix)。
【1】socket
示例 (uwsgi.ini):
[uwsgi]
module = app:app
#socket = 127.0.0.1:8000
socket = 0.0.0.0:8000
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log
nginx 配置 ❙〽❝❝❀ sgi.ini):
[uwsgi]
module = app:app
socket = 0.0.0.0:8000
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log
nginx 配置?是两种不同类型的套接字。
- TCP套接字是基于TCP/IP协议的网络套接字,用于网络上进程之间的通信。 TCP套接字需要指定IP地址和端口号,以便其他进程可以连接到该套接字进行通信。 TCP 套接字是跨越网络边界并允许不同计算机之间进行通信的套接字。 TCP套接字常用于客户端/服务器架构,例如Web服务器、数据库服务器等。
- Unix套接字是基于Unix域套接字的本地套接字,用于同一计算机上的进程之间的通信。 Unix套接字只需要指定文件路径,而不需要使用IP地址和端口号。 Unix 套接字是一种进程间通信(IPC)机制,可提供高效、可靠且安全的进程间通信。 Unix套接字通常用于本地服务器和本地客户端之间的通信,例如X Window系统中的客户端和服务器。
因此,TCP 套接字用于在网络上进行通信,而 Unix 套接字用于在同一台计算机上进行通信。虽然 TCP 套接字可以通过网络连接到不同的计算机,但 Unix 套接字提供了更高效的进程间通信机制,更适合必须在同一台计算机上运行的进程间通信。
[TCP 示例] 常用
uwsgi.ini
:
[uwsgi]
module = app:app
socket = 127.0.0.1:8000
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log
[unix 示例] 仅限于本地通信,很少使用。
uwsgi.ini
:
[uwsgi]
module = app:app
socket = /opt/myapp/myapp.socket
chdir = /opt/myapp
pidfile=/opt/myapp/myapp.pid
processes = 4
threads = 2
master = true
vacuum = true
py-autoreload = 1
daemonize = /tmp/uwsgi.log
nginx配置
server {
listen 8080;
server_name myapp.com;
location / {
include uwsgi_params;
proxy_pass unix:///opt/myapp/myapp.sock;
}
}
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。