zoukankan      html  css  js  c++  java
  • uwsgi的使用示例+django

    -https://docs.djangoproject.com/zh-hans/3.2/howto/deployment/wsgi/uwsgi/

    uwsgi基本了解
    前置条件:uWSGI¶
    uWSGI 百科介绍了几种 安装流程。Pip (Python 包管理器)能让你仅用一行代码就安装任意版本的 uWSGI。例子:

    # Install current stable version.
    $ python -m pip install uwsgi
    
    # Or install LTS (long term support).
    $ python -m pip install https://projects.unbit.it/downloads/uwsgi-lts.tar.gz
    

    uWSGI 模块¶
    uWSGI 以客户端-服务端模型运行。Web 服务器(例如 nginx,Apache)与一个 django-uwsgi "worker" 进程交互,提供动态内容。

    配置并启动用于 Django 的 uWSGI 服务器¶
    uWSGI 支持多种配置进程的方式。参考 uWSGI 的 配置文档。

    以下是个示例命令,用于启动一个 uWSGI 服务器:

    uwsgi --chdir=/path/to/your/project 
        --module=mysite.wsgi:application 
        --env DJANGO_SETTINGS_MODULE=mysite.settings 
        --master --pidfile=/tmp/project-master.pid 
        --socket=127.0.0.1:49152       # can also be a file
        --processes=5                  # number of worker processes
        --uid=1000 --gid=2000          # if root, uwsgi can drop privileges
        --harakiri=20                  # respawn processes taking more than 20 seconds
        --max-requests=5000            # respawn processes after serving 5000 requests
        --vacuum                       # clear environment on exit
        --home=/path/to/virtual/env    # optional path to a virtual environment
        --daemonize=/var/log/uwsgi/yourproject.log      # background the process
    

    假设你有个叫做 mysite 的顶级项目包,期中包含一个模板 mysite/wsgi.py,模块包含一个 WSGI application 对象。如果你使用的是较新的 Django,这就是你运行 django-admin startproject mysite (使用你的项目名替换 mysite)后得到的目录结构。若该文件不存在,你需要创建它。参考文档 如何使用 WSGI 进行部署 看看你需要配置的默认内容,以及你还能添加什么。

    Django 指定的参数如下:

    chdir:需要包含于 Python 的导入路径的目录的路径——例如,包含 mysite 包的目录。
    module:要使用的 WSGI 模块——可能是 startproject 创建的 mysite.wsgi 的模块。
    env:至少要包括 DJANGO_SETTINGS_MODULE。
    home: 可选的路径,指向你工程的虚拟环境。
    示例 ini 配置文件:

    [uwsgi]
    chdir=/path/to/your/project
    module=mysite.wsgi:application
    master=True
    pidfile=/tmp/project-master.pid
    vacuum=True
    max-requests=5000
    daemonize=/var/log/uwsgi/yourproject.log
    

    示例 ini 配置文件语法:

    uwsgi --ini uwsgi.ini
    

    uwsgi源码分析-工作流程
    参考:

    uwsgi 是一个用 c 写的 webserver, 经典的 master/worker 进程模式。

    uwsgi采用的是经典的 单master/多worker 并发模型。master负责信号处理,初始化,创建并管理worker进程,以及绑定监听sockets。worker的每个线程,处在这样的一个循环中:accept -> recv -> handle request -> send response。
    
    一开始进入main函数,启动这个就是主进程了,uwsgi_setup函数(主进程)里面针对选项参数做一些处理,执行环境设置,执行一些hook,语言环境初始化(python),如果没有设置延迟加载app,则app在主进程加载;如果设置了延迟加载,则在每一个worker进程中都会加载一次。uwsgi_setup函数还执行了插件的初始化(eg http、python:http是gateway类型的插件,这种插件是向外暴露http服务的,python的 requests 类型的插件,用来服务请求的)、tcp socket的绑定与监听(这个是指http与work之间的通信,且它的端口是自动产生的)。最后uwsgi主进程fork了指定worker进程用来接收(accept)请求。虽然在setup中就fork了子进程,但是现在还没有开始accept。
    主进程执行部分是一个无限循环,他可以执行特定的hook以及接收信号等,总之是用来管理worker进程以及一些定时或者事件触发任务。worker部分:注册型号处理函数,执行一些hook,循环接收(accept)请求。在启动woker时可以根据–threads参数指定要产生的线程个数,否则只在当前进程启动一个线程。这些线程循环接收请求并处理。
    worker中接收请求的函数wsgi_req_accept有一个锁:thunder_lock,这个锁用来串行化accept,防止“惊群”现象:主进程绑定并监听socket,然后调用fork,在各个子进程进行accept。无论任何时候,只要有一个连接尝试连接,所有的子进程都将被唤醒,但只有一个会连接成功,其他的会得到一个EAGAIN的错误,导致巨大的CPU资源浪费,如果在进程中使用线程,这个问题被再度放大。一个解决方法是串行化accept,在accept前防止一个锁。
    

    nginx + uwsgi + django部署的原理
    参考:

    首先客户端请求服务资源,
    nginx作为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析,
    如果是静态文件请求就根据nginx配置的静态文件目录,返回请求的资源,
    如果是动态的请求,nginx就通过配置文件,将请求传递给uWSGI;uWSGI 将接收到的包进行处理,并转发给wsgi,
    wsgi根据请求调用django工程的某个文件或函数,处理完后django将返回值交给wsgi,
    wsgi将返回值进行打包,转发给uWSGI,
    uWSGI接收后转发给nginx,nginx最终将返回值返回给客户端(如浏览器)。
    *注:不同的组件之间传递信息涉及到数据格式和协议的转换
    

    uwsgi常用配置
    uwsgi.ini

    # uwsgi --http :8000  --ini uwsgi.ini # http启动命令
    # uwsgi --master --https 0.0.0.0:443,foobar.crt,foobar.key,HIGH --chdir /workdir/bean/ --module bean.wsgi # https启动命令
    
    [uwsgi]
    
    # close tlsv1.0 1.1
    ssl-enable3 = false
    ssl-option = 67108864
    ssl-enable-tlsv1 = false
    
    https = 0.0.0.0:9443,/path/cert/server.pem,/path/cert/server.key,HIGH
    # http-to = /tmp/uwsgi.sock
    
    # 路径 可不指定workdir
    wsgi-file = bean/wsgi.py
    
    # auto load py
    # py-autoreload = 1
    
    # static map
    static-map=/static=/static
    
    # 重启时间
    # harakiri = 10
    
    # 主进程
    master = true
    
    # 4个进程/workers
    processes = 4
    
    # 两个核心
    # threads = 1
    
    ; 将写入 log 的工作委托给 master 进程
    log-master = true
    
    ; 单独开一个线程进行 log 写入工作,这样有更好的性能
    threaded-log = true
    
    # 避免惊群效应 multiprocess + multithread
    # https://stackoverflow.com/questions/34824487/when-is-thunder-lock-beneficial
    thunder-lock = true 
    
    # 开启线程
    enable-threads = false
    
    # 单个进程最大请求数
    max-requests = 5000
    
    # 解包缓冲区大小
    buffer-size = 65536
    
    # 平滑重启时间
    reload-mercy = 5
    worker-reload-mercy = 5
    
    # 状态监听地址
    stats = 127.0.0.1:5000 # uwsgi --connect-and-read 127.0.0.1:5000查看uwsgi的连接状态
    
    # master进程位置,用于停止和重新加载
    pidfile = /var/run/uwsgi.pid
    
    # 退出后自动清理socket pid文件,停止后将无法重启
    vacuum = true
    
    # 日志分块大小
    # log-maxsize = 50000000
    
    # 不记录请求日志,只记录错误及内部消息
    # disable-logging = true
    
    # logto 指定日志存储位置及文件名
    # logto = /var/log/itp/itpserver/logs/uwsgi.log
    
    
  • 相关阅读:
    BZOJ2144跳跳棋——LCA+二分
    BZOJ[Usaco2017 Jan]Promotion Counting——线段树合并
    BZOJ4551[Tjoi2016&Heoi2016]树——dfs序+线段树/树链剖分+线段树
    BZOJ1559[JSOI2009]密码——AC自动机+DP+搜索
    BZOJ1222[HNOI2001]产品加工——DP
    [IOI2018]狼人——kruskal重构树+可持久化线段树
    BZOJ3091城市旅行——LCT区间信息合并
    Link-Cut Tree(LCT)&TopTree讲解
    BZOJ3669[Noi2014]魔法森林——kruskal+LCT
    BZOJ4530[Bjoi2014]大融合——LCT维护子树信息
  • 原文地址:https://www.cnblogs.com/davis12/p/15512226.html
Copyright © 2011-2022 走看看