virtualenv 环境下 Django + Nginx + Gunicorn+ Supervisor 搭建 Python Web - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
OneAPM
V2EX    程序员

virtualenv 环境下 Django + Nginx + Gunicorn+ Supervisor 搭建 Python Web

  •  7
     
  •   OneAPM
    oneapm 2015-07-15 11:09:05 +08:00 6132 次点击
    这是一个创建于 3742 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在这篇文章里,我们将搭建一个简单的 Web 应用,在虚拟环境中基于 Flask 框架,用 Gunicorn 做 wsgi 容器,用 Supervisor 管理进程,然后使用 OneAPM Python 探针来监测应用性能,形成一个「闭环」 !希望能对大家有所帮助,首先简单来介绍一下环境:

    系统环境:ubuntu 14.04 Python 2.7.6

    安装组件库

    第一步安装所需要的存储库,因为打算用到虚拟环境,用到 pip 安装和管理 Python 组件,所以先更新本地包,然后安装组件:

    sudo apt-get update
    sudo apt-get install python-pip python-dev nginx

    创建虚拟环境 virtualenv

    在一个系统中创建不同的 Python 隔离环境,相互之间还不会影响,为了使系统保持干净,遂决定用 virtualenv 跑应用程序,创建一个容易识别的目录,开始安装,再创建项目目录 super,然后激活环境:

    sudo pip install virtualenv
    mkdir ~/supervisor && cd ~/supervisor
    virtualenv super
    source super/bin/activate

    安装 Flask 框架

    好了,现在在虚拟环境里面,开始安装 Flask 框架,flask 依赖两个库 werkzeug 和 jinjia2, 采用 pip 方式安装即可, pip 是一个重要的工具,Python 用它来管理包:

    pip install flask

    先用 Flask 写一个简单的 Web 服务 myweb.py ,因为后面要做一些测试,所以设置了几个请求:

    from flask import Flask
    app = Flask(__name__)
    @app.route('/')
    def index():
    return 'hello world supervisor gunicorn '
    @app.route('/1')
    def index1():
    return 'hello world supervisor gunicorn ffffff'
    @app.route('/qw/1')
    def indexqw():
    return 'hello world supervisor gunicorn fdfdfbdfbfb '
    if __name__ == '__main__':
    app.debug = True
    app.run()

    启动 Flask 看看!

    python myweb.py

    在浏览器中访问 http://127.0.0.1:5000 就可以看到了「几个路径都试一试」

    用 Gunicorn 部署 Python Web

    现在我们使用 Flask 自带的服务器,完成了 Web 服务的启动。生产环境下,Flask 自带的服务器,无法满足性能要求。所以我们这里采用 Gunicorn 做 wsgi 容器,用来部署 Python,首先还是安装 Gunicorn:

    pip install gunicorn

    当我们安装好 Gunicorn 之后,需要用 Gunicorn 启动 Flask,Flask 用自带的服务器启动时,Flask 里面的 name 里面的代码启动了 app.run()。而这里我们使用 Gunicorn,myweb.py 就等同于一个库文件,被 Gunicorn 调用,这样启动:

    gunicorn -w 4 -b 0.0.0.0:8000 myweb:app

    其中 myweb 就是指 myweb.py,app 就是那个 wsgifunc 的名字,这样运行监听 8000 端口,原先的 5000 端口并没有启用,-w 表示开启多少个 worker,-b 表示 Gunicorn 开发的访问地址。

    想要结束 Gunicorn 只需执行 pkill Gunicorn,但有时候还要 ps 找到 pid 进程号才能 kill。可是这对于一个开发来说,太过于繁琐,因此出现了另外一个神器 ---supervisor,一个专门用来管理进程的工具,还可以管理系统的工具进程。

    安装 Supervisor

    pip install supervisor echo_supervisord_conf > supervisor.conf # 生成 supervisor 默认配置文件 gedit supervisor.conf # 修改 supervisor 配置文件,添加 gunicorn 进程管理 

    在 supervisor.conf 底部下添加 myweb.py 的配置 /home/wang/supervisor/super 是我的项目目录」

    [program:myweb]
    command=/home/wang/supervisor/super/bin/gunicorn -w 4 -b 0.0.0.0:8000 myweb:app
    directory=/home/wang/supervisor
    startsecs=0
    stopwaitsecs=0
    autostart=false
    autorestart=false
    user=wang
    stdout_logfile=/home/wang/supervisor/log/gunicorn.log
    stderr_logfile=/home/wang/supervisor/log/gunicorn.err


    supervisor 的基本使用命令:

    supervisord -c supervisor.conf
    supervisorctl -c supervisor.conf status 查看supervisor的状态
    supervisorctl -c supervisor.conf reload 重新载入 配置文件
    supervisorctl -c supervisor.conf start [all]|[appname] 启动指定/所有 supervisor 管理的程序进程
    supervisorctl -c supervisor.conf stop [all]|[appname] 关闭指定/所有 supervisor 管理的程序进程

    supervisor 还有一个 web 的管理界面,可以激活。更改下配置:
    ```
    [inet_http_server] ; inet (TCP) server disabled by default
    port=127.0.0.1:9001 ; (ip_address:port specifier, *:port for alliface)
    username=wang ; (default is no username (open server)
    password=123 ; (default is no password (open server))

    [supervisorctl]
    serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
    serverurl=http://127.0.0.1:9001 ; use an http:// url to specify an inet socket
    username=wang ; should be same as http_username if set
    password=123 ; should be same as http_password if set
    ;prompt=mysupervisor ; cmd line prompt (default "supervisor")
    ;history_file=~/.sc_history ; use readline history if available

    现在可以使用 supervsior 启动 gunicorn 啦。运行命令:

    supervisord -c supervisor.conf
    ```
    浏览器访问 http://127.0.0.1:9001 可以得到 supervisor 的 web 管理界面,访问 http://127.0.0.1:8000 可以看见 gunicorn 启动的返回的页面。

    配置 Nginx

    前面我们已经在系统环境下安装了 Nginx, 安装好的 Nginx 二进制文件放在 /usr/sbin/ 文件夹下,接下来使用 Supervisor 来管理 Nginx。这里需要注意一个问题,权限问题。Nginx 是 sudo 的方式安装,启动的适合也是 root 用户,那么我们现在也需要用 root 用户启动 supervisor。在 supervisor.conf 下添加配置文件:

    [program:nginx]
    command=/usr/sbin/nginx
    startsecs=0
    stopwaitsecs=0
    autostart=false
    autorestart=false
    stdout_logfile=/home/wang/supervisor/log/nginx.log
    stderr_logfile=/home/wang/supervisor/log/nginx.err

    好了,都配置完之后,启动 supervisor:

    supervisord -c supervisor.conf

    访问页面,也可以用 ab 进行压力测试:

    ab -c 100 -n 100 http://127.0.0.1:8000/qw/1 

    -c 用于指定压力测试的并发数, -n 用于指定压力测试总共的执行次数。

    安装 Python 探针

    搭建好了 web,想实时监控应用数据,有什么好的工具,用 OneAPM 的 Python 探针试试,
    首先也是安装 Python 探针:

    pip install -i http://pypi.oneapm.com/simple --upgrade blueware

    根据 License Key 生成配置文件:

    blueware-admin generate-config (License Key)=blueware.ini

    由于是在虚拟环境下,所以要特别注意路径,修改 supervisor.conf 里面两项:

    [program:myapp]
    command = /home/wang/supervisor/super/bin/blueware-admin run-program /home/wang/supervisor/super/bin/gunicorn -w 4 -b 0.0.0.0:8000 myapp:app
    envirOnment= BLUEWARE_CONFIG_FILE=blueware.ini

    重启应用

    supervisorctl # 进入命令行
    supervisor> reload # 重新加载

    向上面一样访问页面,也可以用 ab 进行压力测试
    几分钟后有下图,可以看到页面加载时间,web 事物,页面吞吐量,其中后面是设置自定义事物「Business Transaction」。

    virtualenv 环境下 Django + Nginx + Gunicorn+ Supervisor 搭建Python Web
    virtualenv 环境下 Django + Nginx + Gunicorn+ Supervisor 搭建Python Web
    virtulenv 环境下 Django + Nginx + Gunicorn+ Supervisor 搭建Python Web

    参考文章:

    How To Serve Flask Applications with uWSGI and Nginx on Ubuntu 14.04

    OneAPM Python 探针安装

    python web 部署:nginx + gunicorn + supervisor + flask 部署笔记

    Tornado+nginx+supervisor 在生产环境上部署

    supervisor + Tornado + Nginx 使用详解

    本文系 OneAPM 工程师编译整理。OneAPM 是应用性能管理领域的新兴领军企业,能帮助企业用户和开发者轻松实现:缓慢的程序代码和 SQL 语句的实时抓取。想阅读更多技术文章,请访问OneAPM 新闻

    第 1 条附言    2015-07-17 11:44:02 +08:00
    正确标题为:Virtualenv 环境下 Flask + Nginx + Gunicorn+ Supervisor 搭建 Python Web
    11 条回复    2016-04-28 00:35:36 +08:00
    leopardwei
        1
    leopardwei  
       2015-07-15 11:33:24 +08:00
    标题可严重不符,说 django,结果是 flask
    jakes
        2
    jakes  
       2015-07-15 11:39:31 +08:00 via Android
    装好nginx就可以直接使用?不需要进行配置吗?
    Captian
        3
    Captian  
       2015-07-15 12:20:52 +08:00
    标题 + 1
    Ge4Los
        4
    Ge4Los  
       2015-07-15 13:19:59 +08:00
    这是软广吧,v2ex的广告风格真奇特。
    crazyxin1988
        5
    crazyxin1988  
       2015-07-15 13:26:13 +08:00
    即便是软广 可不可以认真点
    明明是flask
    moosoome
        6
    moosoome  
       2015-07-15 13:39:09 +08:0
    flask 和 django 你真的能分清吗...
    felixzhu
        7
    felixzhu  
       2015-07-15 15:20:42 +08:00
    可不可以不要发这么多软文。。。如果我是管理员就拉黑。。
    zhengnanlee
        8
    zhengnanlee  
       2015-07-15 23:35:06 +08:00 via Android
    对哈。。标题内容不符
    GPU
        9
    GPU  
       2015-07-16 11:53:54 +08:00
    看完之后原来是软文 ,一开始我还以为是干货呢。
    zztt168
        10
    zztt168  
       2015-07-16 12:55:27 +08:00 via iPhone
    我还以为自己落伍了,原来django没有改名叫flask。
    SR1
        11
    SR1  
       2016-04-28 00:35:36 +08:00
    挖个坟
    不错,知道了解了 gunicorn + supervisor 怎么一起用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2732 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 09:13 PVG 17:13 LAX 02:13 JFK 05:13
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86