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的扩展。

.
image
.
image
.
.
.
.
.
.
.
.
.

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()


# 右键运行该文件,项目就起起来了!!!!!!

.
.
.
.
.
.
.
.

posted @   tengyifan  阅读(132)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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
点击右上角即可分享
微信分享提示