V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
OneAPM
V2EX  ›  程序员

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

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

    在这篇文章里,我们将搭建一个简单的 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
    virtualenv 环境下 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:00
    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   ·   实用小工具   ·   1551 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:02 · PVG 01:02 · LAX 09:02 · JFK 12:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.