快速开始Python—wsig应用程序

官方参考文档

安装 uwsgi

  • 安装
pip install uwsgi
uwsgi --version # 查看 uwsgi 版本
  • 测试 uwsgi 是否正常

新建一个测试文件 helloworld.py

def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return [b'hello world',]
  • 启动并监听 9090 端口
uwsgi --http :9090 --wsgi-file helloworld.py
  • 添加并发性和监视调优

uwsgi 默认是单进程单线程启动的

添加多进程使用 --processes 选项, 添加多线程使用 --threads 选项

uwsgi --http :9090 --wsgi-file helloworld.py --master --processes 4 --threads 2
# 表示启动 4 个进程,每个进程 2 个线程;一个主进程,当进程挂掉后从新生成新的进程

监测是一个重要的任务。在生产环境中知道发生了什么是至关重要的

stats 子系统允许你以 json 格式导出 uwsgi 的内部统计信息

uwsgi --http :9090 --wsgi-file helloworld.py --master --processes 4 --threads 2 --stats 127.0.0.1:9091
# 添加监测,通过 127.0.0.1:9091 访问 json 格式的统计信息
# 把 stats 绑定到一个私有地址,否则所有人都可以访问这个统计信息 uwsgitop 一个类似 top 的监控 uwsgi 的工具
pip install uwsgitop
  • 把 uwsgi 放到web服务器后端(nginx, apache等)

uwsgi可以使用 HTTP, FastCGI, SCGI, uwsgi 协议,其中性能最好的是 uwsgi,nginx 支持 uwsgi 协议,apache 在添加对应的模块后也可以支持 uwsgi 协议

一个常见的 nginx 配置如下:

location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
# 使用 uwsgi 协议将每个请求转发到绑定 3031 端口的服务器

使用 uwsgi 协议启动 uwsgi 服务器

uwsgi --socket 127.0.0.1:3031 --wsgi-file helloworld.py --master --processes 4 --threads 2 -stats 127.0.0.1:9191

如果你的代理前端服务器使用的是 http 协议,你必须让 uwsgi 也使用 http 协议

uwsgi --http-socket 127.0.0.1:3031 --wsgi-file helloworld.py --master --processes 4 --threads 2 --stats 127.0.0.1:9091

# --http 和 --http-socket 不一样,--http 自带一个代理
  • 开机自动启动 uwsgi

在使用脚本来启动 uwsgi 之前,看是否可以使用其他进程管理程序来启动 uwsgi,比如:

Upstart, Systemd
supervisord, god, monit, circus

uwsgi 可以很好的与以上的进程管理器集成,如果有大量的应用需要部署,建议使用 uWSGI Emperor

  • 部署 django

假设 django 项目路径是: /home/foobar/myproject

uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --wsgi-file myproject/wsgi.py --master --processes 4 --theads 2 --stats 127.0.0.1:9191

--chdir 切换到 django 的项目路径下,这是 django 正确加载模块所必须的

以上这个很长的命令行命令可以写在一个 uwsgi 的 .ini 格式的配置文件中,比如 foo.ini

[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
wsgi-file = myproject/wsgi.py
processes = 4
threads = 2
stats = 127.0.0.1:9191

使用配置文件启动

uwsgi foo.ini

如果使用的是旧版本的django(< 1.4),需要多加一下配置

uwsgi --socket 127.0.0.1:3031 --chdir /home/foobar/myproject/ --pythonpath .. --env DJANGO_SETTINGS_MODULE=myproject.settings --module "django.core.handlers.wsgi:WSGIHandler()" --processes 4 --threads 2 --stats 127.0.0.1:9191
[uwsgi]
socket = 127.0.0.1:3031
chdir = /home/foobar/myproject/
pythonpath = ..
env = DJANGO_SETTINGS_MODULE=myproject.settings
module = django.core.handlers.wsgi:WSGIHandler()
processes = 4
threads = 2
stats = 127.0.0.1:9191

旧版本的 django(< 1.4) 需要设置 env,module, pythonpath(允许获取到 myproject.settings 模块)

  • 部署 flask

部署flask

  • 关于线程的说明

如果没有使用多线程启动 uwsgi,那么在应用里面生成的线程不会运行

可以使用 --enable-threads 选项,enable-threads = true .ini文件配置项,在不使用多线程启动 uwsgi 时支持应用内的多线程运行

  • python 虚拟环境

uwsgi 支持 python 虚拟环境内查找 python 模块,只需要添加配置项 virtualenv = <path>

  • 安全和可用性

安全性

不要使用 root 用户运行 uwsgi,可以使用 uid 和 gid 移除特权

[uwsgi]
https = :9090,foobar.crt,fooar.key
uid = foo
gid = bar
chdir = path_to_web2py
module = wsgihandler
master = true
processes = 8

如果要使用特权端口(如 443),可以使用共享 socket

[uwsgi]
shared-socket = :443
https = 0, foobar.crt, foobar.key
uid = foo
gid = bar
chdir = path_to_web2py
module = wsgihandler
master = true
processes = 8

可以性

请求阻塞问题,可以设置一个 harakiri 定时器,在指定时间后销毁被阻塞的 worker

[uwsgi]
shared-socket = :443
https = =0,foobar.crt,foobar.key
uid = foo
gid = bar
chdir = path_to_web2py
module = wsgihandler
master = true
processes = 8
harakiri = 30

如果一个请求阻塞了 30 秒,那么这个 worker 会被销毁

可以通过 stats 子系统实时查看每个worker,thread 或者 async 工作情况

  • 线程卸载

uwsgi offloading 子系统在特定匹配模式或可以使用纯C线程时,可以很快的释放掉 worker,比如:从文件系统发送静态文件,从网络发送数据等

意思是:worker把请求中的特定操作(发送文件,发送数据等)分配给其他的进程线程,从而使得 worker 可以被尽快释放,处理跟多的请求

添加 --offload-threads <n> 选项启用,(建议每个CPU启用 1 个线程)

  • 多 python 版本支持

最好的方法是内置一个独立于语言的特性的二进制文件,并为每个Python版本提供一个按需加载的插件

编译时使用 PROFILE=nolang

make PROFILE=nolang

编译python 插件

PYTHON=python3.4 ./uwsgi --build-plugin "plugins/python python34"
PYTHON=python2.7 ./uwsgi --build-plugin "plugins/python python27"
PYTHON=python2.6 ./uwsgi --build-plugin "plugins/python python26"

会得到3个插件:python34_plugin.so, python27_plugin.so, python26_plugin.so

将这些复制到您想要的目录中,默认情况下,uWSGI在当前工作目录中搜索插件。

现在可以在 uwsgi 配置文件中使用这些插件,添加在最顶端

[uwsgi]
plugins-dir = <path_to_your_plugin_directory>
plugin = python26

2019-2-20 by achxku@163.com

快速开始Python/WSGI应用程序的更多相关文章

  1. 程序员带你十天快速入门Python,玩转电脑软件开发(四)

    本系列文章立志于从一个已经习得一门编程语言的基础之上,全面介绍Python的相关开发过程和相关经验总结.本篇文章主要是基于上一篇的程序员带你十天快速入门Python,玩转电脑软件开发(三)的基础之上, ...

  2. 程序员带你十天快速入门Python,玩转电脑软件开发(三)

    声明:本次教程主要适用于已经习得一门编程语言的程序员.想要学习第二门语言.有梦想,立志做全栈攻城狮的你 . 如果是小白,也可以学习本教程.不过可能有些困难.如有问题在文章下方进行讨论.或者添加QQ群5 ...

  3. 程序员带你十天快速入门Python,玩转电脑软件开发(二)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  4. 程序员带你十天快速入门Python,玩转电脑软件开发(一)

    关注今日头条-做全栈攻城狮,学代码也要读书,爱全栈,更爱生活.提供程序员技术及生活指导干货. 如果你真想学习,请评论学过的每篇文章,记录学习的痕迹. 请把所有教程文章中所提及的代码,最少敲写三遍,达到 ...

  5. 快速掌握用python写并行程序

    目录 一.大数据时代的现状 二.面对挑战的方法 2.1 并行计算 2.2 改用GPU处理计算密集型程序 3.3 分布式计算 三.用python写并行程序 3.1 进程与线程 3.2 全局解释器锁GIL ...

  6. 怎么快速学python?酒店女服务员一周内学会Python,一年后成为程序员

    怎么快速学python?有人说,太难!但这个女生却在一个星期内入门Python,一个月掌握python所有的基础知识点. 说出来你应该不信,刚大学毕业的女生:琳,一边在酒店打工,一边自学python, ...

  7. java程序员快速掌握python系列——概述

    这一系列主要是总结学习python过程中的方方面面(已经学完,时间大概是一周左右).当然限于个人水平java也就是够用,python短时间内也不可能深入到哪里去.所以这次的分享的目的是能够快速使用py ...

  8. Python 学习笔记13:Python + wsgi + django 配置。坑爹的python3和wsgi不兼容的解决

    今人不见古时月,今月曾经照古人.生命是如此的美丽与短暂! 学习Python已经两个月了,Python的语法通过做简单的语法题和看Python语法介绍,有了初步的了解.但上班还是要做别的事情,所以感觉学 ...

  9. python wsgi

    什么是wsgi? wsgi是一个web组件的接口防范,wsgi将web组件分为三类:web服务器,web中间件,web应用程序 wsgi基本处理模式为:wsgi Server -> wsgi m ...

随机推荐

  1. svn 命令

    svn基本的操作流程就是: 你刚刚进入一个新的公司,让你接手一个正在进行的项目,你打开终端写下了:svn co svn://192.168.1.1/pro/domain 然后就可以在当前目录里面找到一 ...

  2. LeetCode4. 两个排序数组的中位数

    4. 两个排序数组的中位数 问题描述 There are two sorted arrays nums1 and nums2 of size m and n respectively.Find the ...

  3. Flask之flask-migrate 数据库迁移

    简介 flask-migrate是flask的一个扩展模块,主要是扩展数据库表结构的. 官方文档:http://flask-migrate.readthedocs.io/en/latest/ 使用fl ...

  4. python-repr()和val()函数

    1. repr() 函数将对象转化为供解释器读取的形式. 语法 以下是 repr() 方法的语法: repr(object) 参数 object -- 对象. 返回值 返回一个对象的 string 格 ...

  5. 51nod - 1163 巧妙的并查集 O(1)维护区间

    有N个任务,每个任务有一个最晚结束时间以及一个对应的奖励.在结束时间之前完成该任务,就可以获得对应的奖励.完成每一个任务所需的时间都是1个单位时间.有时候完成所有任务是不可能的,因为时间上可能会有冲突 ...

  6. HDU - 4825 01字典树套路题

    /*H E A D*/ struct Trie{ int son[maxn<<2][2]; int b[67],tot; void init(){ // memset(son,0,size ...

  7. Hadoop基础入门

    一.hadoop是什么? (1)Hadoop是一个开源的框架,可编写和运行分布式应用处理大规模数据,是专为离线和大规模数据分析而设计的,并不适合那种对几个记录随机读写的在线事务处理模式.Hadoop= ...

  8. [转] domeOS 环境搭建 自动化构建部署

    [From]http://dockone.io:82/article/4150 系统:CentOS Linux 7A机子(domeos服务器):1. gitlab安装(私有仓库):yum -y ins ...

  9. [转] 完全卸载删除gitlab

    [From] https://yq.aliyun.com/articles/114619 完全卸载删除gitlab 1.停止gitlab gitlab-ctl stop 2.卸载gitlab(注意这里 ...

  10. poj3262

    一.题意:有n头牛,每头牛每分钟会吃D个菜,把这头牛赶回去需要时间T(人再返回又需要T),一次只能赶回去一头牛,也就是说剩下的牛会继续吃菜.求牛最少吃多少菜 二.思路:贪心.按D/T将牛进行排序,然后 ...