python常用的符合WSGI协议的web服务器的具体使用方法!!!
.
.
.
.
客户端(浏览器,app) 跟 服务端(web框架)之间的东西 ,又叫服务器中间件
# nginx apache 是一类东西,就是做请求转发
# uWSGI,wsgiref 是一类东西 针对于python的web框架
浏览器--》--Nginx--》--web服务器--》--web框架
WSGI:Web Server Gateway Interface
Web服务器 和 Web框架之间的 一种通用的接口协议,或者说是web服务器和web框架之间的接口标准
# 符合WSGI协议的web服务器有哪些:uWSGI gunicorn wsgiref werkzeug(是个工具包,
# 但里面包含了一个服务器) 等
# uWSGI:
符合wsgi协议的web服务器,用c写的,性能比较高,咱们通常用来部署django,flask
# 一句话总结:一个符合WSGI协议的 web服务器,
# 处理发来的请求及返回响应。
# cgi:(Common Gateway Interface/CGI)通用网关接口协议
规定了web服务器(nginx,apache)到 请求处理程序(django,flask,
等web框架)之间传输数据的标准
所有bs架构软件都是遵循CGI协议的
一句话总结:一个标准,定义了客户端浏览器与服务器之间如何传输数据
-------------------------------------------------------------------
uWSGI 与 gunicorn
gunicorn只支持在unix系统上运行
.
.
.
原始的http请求的数据 是请求首行,请求头,请求体 一大串字符串
web服务器将http请求的数据,组织成了一个environ字典,传到web框架里面去了
web框架又将environ字典包装成立request对象了!!!
.
.
.
.
.
.
利用gevent来配置uwsgi提高django项目并发量
参考博客 https://www.cnblogs.com/wangkun122/articles/11118453.html
.
.
.
.
.
Django3创建项目会自动生成文件asgi.py和wsgi.py
WSGI, Web Server Gateway Interface,Web服务网关接口,用来描述Web 服务器如何与Web 应用通信的规范。
Django 的主要部署平台是 WSGI,它是 Web 服务器和 Web 应用的 Python 标准。
常见的Web服务器: Nginx, Apache等。
常见的Web应用: Flask, Django等。
-----------------------------------------
ASGI,异步服务网关接口, 一个介于网络协议服务和Python应用之间的标准接口,
能够处理多种通用的协议类型,包括HTTP,HTTP2和WebSocket。
同 WSGI 一样,Django 也支持使用 ASGI 来部署,
它是为了支持异步网络服务器和应用而新出现的 Python 标准。
-----------------------------------------
WSGI和ASGI的区别在哪里?
WSGI是基于HTTP协议模式的,不支持WebSocket,
而ASGI的诞生则是为了解决Python常用的WSGI不支持当前Web开发中的一些新的协议标准。
同时,ASGI对于WSGI原有的模式的支持和WebSocket的扩展,即ASGI是WSGI的扩展。
.
.
.
.
.
.
.
.
.
.
.
uwsgi服务器的使用!!!
uWSGI 是一个用于部署 Python Web 应用程序的高性能 Web 服务器。
它支持与多种 Web 框架(如 Flask、Django 等)集成,并提供了许多配置选项和性能调优参数。
你可以使用 uWSGI 来运行和测试你的 Python 后端项目。
它提供了一个本地的 Web 服务器环境,可以模拟生产环境中的部分功能,
例如多进程/线程处理请求、负载均衡等。
--------------------------------------------------
uwsgi官网地址
https://pypi.org/project/uWSGI/2.0.20/#files
下载并解压
windows系统下 安装uwsgi 好像搞不定!!!
后续再说吧!!!
--------------------------------------------------
--------------------------------------------------
.
.
.
.
.
.
.
但请注意,在实际上线部署项目时,可能需要使用其他工具和技术来管理和监控你的应用程序,
例如 Nginx、Supervisor 等。
# 上线的时候,uwsgi启动项目的步骤
# 使用uwsgi步骤
#-写一个uwsgi的配置文件(ini, 我们使用xml)
# 切到项目路径下
vim luffyapi.xml # 新建打开该文件,粘贴下面代码,保存退出
<uwsgi>
<socket>127.0.0.1:8888</socket> <!-- 内部端口,自定义 -->
<chdir>/home/project/luffy_api/</chdir> <!-- 项目根路径 -->
<module>luffy_api.wsgi</module> <!-- 小路飞下的wsgi.py所在目录名-->
<processes>4</processes> <!-- 进程数 -->
<daemonize>uwsgi.log</daemonize> <!-- uwsgi的日志文件 -->
</uwsgi>
# 1 socket意思就是 uwsgi要跑着阿里云服务器的本地127.0.0.1:8888
# 2 chdir 意思是 运行的项目的路径是/home/project/luffy_api/
# 3 我的项目路径是 /home/project/aaaa/
# 4 module
# 把注释删掉后,保存,不然可能会出错
-----------------------------------------
-----------------------------------------
# 使用uwsgi启动djagno项目
uwsgi -x ./luffyapi.xml # 指定配置文件去启动uwsgi
ps aux |grep uwsgi # 确认一下,看到有四个进程说明没问题
# 现在访问8888,没有响应
-uWSGI:配置文件是socket,说明它只能监听 uwsgi协议
浏览器发出去的是http协议,它不能响应
# 只能http请求发送到nginx上!!!使用nginx把http请求,转发到uwsgi,
# nginx支持把http协议转成uwsgi协议!!!
-----------------------------------------
-----------------------------------------
# 需要让nginx能够监听8080端口,然后转发给uwsgi监听的8888端口
# 再修改nginx 配置文件,完成对http请求的转发
# cd /usr/local/nginx/conf/
# vim nginx.conf # 打开配置文件
# 把下面代码放到第一个监听的server下面去
server {
listen 8080;
server_name 127.0.0.1;
charset utf-8;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8888;
uwsgi_param UWSGI_SCRIPT luffy_api.wsgi;
uwsgi_param UWSGI_CHDIR /home/project/luffy_api/;
}
}
# 访问8080的根路径/
# 会用uwsgi协议转发给阿里云服务器本地的127.0.0.1:8888
# 阿里云服务器本地的8888 被uwsgi服务监听着
# 一个server监听一个端口,所以现在nginx监听了80与8080两个端口了!!!
-------------------------------------------------
-------------------------------------------------
# cd /usr/local/nginx/conf/ # 先切到配置文件夹下
# 重启nginx
nginx -s reload
# 访问前端,查看,此时访问的就是8080
http://47.100.95.236:8080/api/v1/home/banner/
# 注意看下redis有没有启动!!! 新建一个会话把redis启动
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
gunicorn服务器的使用!!!
Gunicorn是基于unix系统,被广泛应用的高性能的Python WSGI HTTP Server。
用来解析HTTP请求的网关服务。
它的运行模型基于pre-fork worker 模型,即就是支持eventlet,也支持greenlet。
--------------------------------------------------
gunicorn特点
其特点:
1、能和大多数的Python Web框架兼容;
2、简单易上手;
3、轻量级的资源消耗;
# 4、目前,gunicorn只能运行在Linux环境中,不支持windows平台!!!
---------------------------------------------------
gunicorn的工作模式一般分为同步worker使用和异步worker使用。
同步worker(Sync Worker)
每个worker进程,一次只处理一个请求;如果此时又有其他请求被分配到了这个worker进程中,
那只能被堵塞了,只能等待第一个请求完成。并且,一个请求一个进程,并发时,是非常消耗CPU和内存的。
注:因此,只能适合在访问量不大、CPU密集而非I/O的情形。
但是也有好处,好处就是,即使一个worker的进程crash了,也只会影响到一个请求。不会影响其他的请求
-------------------------------------------------------
# 异步workers(Async Worker)
异步worker有Gevent和Eventlet两种,都是基于Greenlet实现的。
当使用了异步worker,就能同时处理不止一个请求,
就不会出现上面同步worker那样,当一个请求未完成就把后续请求都block堵塞住了。
-------------------------------------------------------
# 注:gunicorn允许通过设置对应的worker类来使用这些异步Python库。
例如:我们想在单核机器上运行的gevent: 这里的main是启动文件的文件名
gunicorn --worker-class=gevent --worker-connections=1000 --workers=3 main:app
解释:worker-connection 是对于 gevent worker 类的特殊设置。
(2CPU)+1 仍然是建议的worker数量。 因为这里是单核,我们设置的是3个worker。
# 在这种情况下,最大的并发请求数是3000(3个worker1000个连接数/worker)
# 也就是说gunicorn通过gevent异步库,让一个工作进程能同时处理请求了!!!!!!
# gunicorn启动产生多个工作进程,每个工作进程就是一个项目服务
-------------------------------------------------------
# gunicorn是如何实现高并发的?
对于gunicorn而言,当启动时,就已经把worker进程预先fork出来了。
当多个请求到来的时候,会轮流复用这些worker进程,从而能提高服务器的并发负载能力。
-------------------------------------------------------
# gunicorn部署
1 先创建虚拟环境,激活虚拟环境
python3 -m virturalenv venv
source venv/bin/activate
2 然后根据 requirements.txt 文件安装依赖包
pip3 install -r requirements.txt
3 安装gunicorn
pip3 install gunicorn
4 在项目根目录下创建一个wsgi.py文件
from app import create_app
application = create_app('production')
if __name__ == '__main__':
application.run()
# 这个代码不太理解,后续再说!!!
5 启动django的服务:
gunicorn -w 4 -b 127.0.0.1:8000 wsgi:application
-------------------------------------
-------------------------------------
-------------------------------------
.
.
.
.
.
.
.
也就是说 gunicorn或者uwsgi它们可以同时启动后端项目进程,当从ngnix过来的请求过来后,
由gunicorn或者uwsgi去控制,该请求由哪个项目进程来处理该请求!!!
.
.
.
.
.
.
.
.
.
nginx 与 supervisor
一般情况下,在生产环境中,进程的启停和状态的监控最好应用supervisor之类的监控工具。
然后在gunicorn的前端,放置一个http proxy server,比如nginx。
# 下面是supervisor、gunicorn以及nginx的配置
# supervisor_gunicorn.conf
[program:gunicorn_demo]
process_name=%(program_name)s
numprocs=1
priority=901
directory = /opt/gunicorn_demo/
command = /opt/virtualenv/bin/python /opt/virtualenv/bin/gunicorn -c gunicorn_demo.py gunicorn_demo:app
autostart = true
startsecs = 20
autorestart = true
startretries = 3
user = root
redirect_stderr = true
stdout_logfile_maxbytes = 20MB
stdout_logfile_backups = 10
stdout_logfile = /dev/null
------------------------------------------------
# gunicorn本身的配置文件
-c gunicorn_demo.py,即就是gunicorn本身的配置文件,
gunicorn_demo.py 【gunicorn的基本配置文件】
import multiprocessing
bind = '127.0.0.1:8000'
workers = multiprocessing.cpu_count() * 2 + 1
backlog = 2048
worker_class = "gevent"
worker_connections = 1000
daemon = False
debug = True
proc_name = 'gunicorn_demo'
pidfile = './log/gunicorn.pid'
errorlog = './log/gunicorn.log'
---------------------------------------
当然了,配置文件还可以设置的更加复杂,根据实际情况而言:
假如:配置文件为:gunicorn_test.py
import logging
import logging.handlers
from logging.handlers import WatchedFileHandler
import os
import multiprocessing
bind = '127.0.0.1:8000' #绑定ip和端口号
backlog = 512 #监听队列
chdir = '/home/test/server/bin' #gunicorn要切换到的目的工作目录
timeout = 30 #超时
worker_class = 'gevent' # 使用gevent模式,还可以使用sync 模式,默认的是sync模式
workers = multiprocessing.cpu_count() * 2 + 1 # 进程数
threads = 2 # 指定每个进程开启的线程数
loglevel = 'info' # 日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"'
#设置gunicorn访问日志格式,错误日志无法设置
accesslog = "/home/test/server/log/gunicorn_access.log" #访问日志文件
errorlog = "/home/test/server/log/gunicorn_error.log" #错误日志文件
----------------------------------------------------------
那么此时执行命令就为:gunicorn -c gunicorn_test.py test:app # 不知道test从哪来的
# 好像是项目启动文件的文件名(没有.py)
# test.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return "hello"
if __name__ == '__main__':
app.run()
----------------------------------------------------------
# nginx.conf 的部分配置
server {
listen 80;
server_name sam_rui.com;
access_log /var/log/nginx/access.log;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
----------------------------------------------------------
gunicorn相关参数说明
1)-c CONFIG,–config=CONFIG
指定一个配置文件(py文件)
2)-b BIND,–bind=BIND
与指定socket进行绑定
3)-D,–daemon
后台进程方式运行gunicorn进程
4)-w WORKERS,–workers=WORKERS
工作进程的数量
5)-k WORKERCLASS,–worker-class=WORKERCLASS
工作进程类型,包括sync(默认),eventlet,gevent,tornado,gthread,gaiohttp
6)–backlog INT
最大挂起的连接数
7)–log-level LEVEL
日志输出等级
8)–access-logfile FILE
访问日志输出文件
9)–error-logfile FILE
错误日志输出文件
------------------------------------------------------
.
.
.
.
.
.
.
.
.
supervisor
参考博客 https://www.cnblogs.com/tengyifan888/articles/17514620.html
# 安装Supervisor:
乌班图的 sudo apt install -y supervisor
centos的 yum install -y supervisor
要是用yum装 提示无可用的软件包,就再装个扩展包 yum install -y epel-release
然后再用yum装
-----------------------------------------
-----------------------------------------
# 服务器进程使用的配置文件一般为 /etc/supervisord.conf,格式为 Windows-INI
# 子进程配置文件在文件夹 /etc/supervisor/conf.d/,可通过上述配置文件的最后一行指定
supervisord.conf # 这个是supervisor的主配置文件
supervisord.d 可以把配置文件写在这个目录下
supervisor/conf.d # 一般把子进程的配置文件写在这个目录下
# 创建子进程配置文件路径 mkdir -p /etc/supervisor/conf.d/
# 修改配置文件 sudo vim /etc/supervisord.conf 将最后一部分改为
[include]
files=/etc/supervisor/conf.d/*.conf
-----------------------------------------
-----------------------------------------
# 下面这两个是子进程配置文件的示例
# 子进程配置文件1 就是gunicorn的配置文件
[program:server_shctwl_qr_transfer_station] # 项目名
directory = /home/user/server_shctwl_qr_transfer_station/ # 工作目录
# 要执行的脚本执行命令!!! 就是用gunicorn启动几个后端项目的进程
# service_server 是项目的启动文件名
command = sudo /home/user/server_shctwl_qr_transfer_station/venv/bin/gunicorn --worker-class=gevent -w 3 -b 0.0.0.0:9090 service_server:app --preload
# --error-log=/home/user/server_shctwl_qr_transfer_station/logs/log_app.log --log-level=info --access-logfile=/home/user/server_shctwl_qr_transfer_station/logs/log_app.log
startsecs = 0 # 子进程启动多少秒后状态为running则认为启动成功,默认为1s
stopwaitsecs = 0 # 在SIGKILL之前等待的最大秒数,默认为10
autostart = true # 在supervisor启动时自动启动,默认为true
autorestart = true # 在意外退出时重新启动
stopasgroup=true # 是否把整个子进程的进程组停止,发送stop信号,默认为false
killasgroup=true # 是否把整个子进程的进程组停止,发送kill信号,默认为false
# stderr的输出文件,默认为AUTO
stderr_logfile=/home/user/server_shctwl_qr_transfer_station/logs/logs_supervisor.log
-----------------------------------------
-----------------------------------------
-----------------------------------------
# 子进程配置文件2
[program:server_shctwl_qr_transfer_station_manager_scheduler]
directory = /home/user/server_shctwl_qr_transfer_station/
command = sudo /home/user/server_shctwl_qr_transfer_station/venv/bin/python service_manager_scheduler.py
startsecs = 0
stopwaitsecs = 0
autostart = true
autorestart = true
stopasgroup=true
killasgroup=true
stderr_logfile=/home/user/server_shctwl_qr_transfer_station/logs/logs_supervisor_manager_scheduler.log
-----------------------------------------
# 更新配置
sudo supervisorctl update
# 把supervisor重启下
sudo supervisorctl restart all
# 启动所有子进程 主要是针对supervisor启动时不自动启动子进程的情况下用的
supervisorctl start all
# 重启所有子进程
supervisorctl restart all
# 启动指定子进程 ( 主要是针对子进程配置文件里面 )
# ( autostart = false supervisor启动时不自动启动子进程的情况下用的情况)
supervisorctl start <name>
-----------------------------------------
.
.
.
.
.
.
.
.
.
.
.
.
gevent也有一个 WSGIServer 服务器
# 示范启动flask项目
# service_server.py 启动文件
import os, sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from utils.uwsgi_server.server_gevent import *
from src import *
app = create_app()
if __name__ == "__main__":
print('土壤系统接口服务启动……')
server = uwsgi_server(app=app, address='192.168.11.18', port=5000)
# server = uwsgi_server(app=app, address='0.0.0.0', port=39090)
server.start()
---------------------------------------
# server_gevent.py 文件
import os, sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from gevent import monkey
from gevent.pywsgi import WSGIServer
monkey.patch_all()
import urllib3
urllib3.disable_warnings()
class uwsgi_server():
def __init__(self, app, address='0.0.0.0', port=5000) -> None:
self.server = WSGIServer((address, port), app)
def start(self):
self.server.serve_forever()
---------------------------
.
.
.
.
用gevent,启动django项目!!!
# 示范启动django项目
from gevent import monkey;
monkey.patch_all()
from gevent.pywsgi import WSGIServer
import os
import sys
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test2023.settings')
import django
django.setup()
from django.core.handlers.wsgi import WSGIHandler as DjangoWSGIApp
application = DjangoWSGIApp()
server = WSGIServer(("127.0.0.1", 8099), application)
print("Starting server on http://127.0.0.1:8099")
server.serve_forever()
# 右键运行该文件,项目就起起来了!!!!!!
.
.
.
.
.
.
.
.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY