runserver_plus

概要:runserver_plus 命令启动测试服务,并用 Werkzeug 作为调试后台,这个命令是对原生命令 runserver 的扩展,提供了更强的错误调试功能.

简介

runserver_plus 命令需要安装 Werkzeug WSGI utilities . Werkzeug 是Python作为web服务的杀手级调试工具,还能进行基于ajax的错误断点调试(允许在出错的地方执行代码). 当然还提供了一个漂亮的错误展示页面.

开始使用

在启动Django的测试服务时,只要用 runserver_plus 命令代替 runserver 命令就可以了:

$ python manage.py runserver_plus

* Running on http://127.0.0.1:8000/
* Restarting with reloader...

Validating models...
0 errors found

Django version 0.97-newforms-admin-SVN-unknown, using settings 'screencasts.settings'
Development server is running at http://127.0.0.1:8000/
Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
Quit the server with CONTROL-C.

runserver_plus 命令接受原来的所有参数.也就是可以随意指定端口和host,跟原生的 runserver 命令一模一样.

深入使用

runserver_plus 启动的服务遇到代码抛出异常时,会得到一个 Werkzeug 的错误显示页面(不是默认的Django错误页面).

werkzeug-traceback

当鼠标划过特定错误行(堆栈)时,就会显示出当前位置的调试扩展功能,注意图片右边出现的2个按钮:

werkzeug-options

这2个选项是:

查看源码

这是点击 显示源码 后的效果:

werkzeug-source

产看错误产生的源码有助于快速定位错误原因.抛出异常的部分被高亮显示,这样更方便查看.

有一个不够人性化的地方是,点击 查看源码 后,页面没有自动滚动到底部(源码显示的地方),这容易让人觉得什么都没有发生,其实是没有看到.

命令行调试

在错误页面上点击命令行调试按钮后,会显示出一个命令行调试工具(网页里面的输入框),是不是屌爆了:

werkzeug-debugger

这样就会出现一个基于ajax的命令行调试工具,输入的命令通过ajax方式发送到后台,再把返回的结果输出,然后就可以任意发挥了.截图中,在调试框里输入了 print environ 命令来查看当前环境中给方法传入了哪些参数.

注意 : 该方法不能被用在任何正式环境中,即使是在正式环境中检测问题时也不行.命令行调试工具允许在服务器端执行Python命令,这是非常危险的.

SSL

runserver_plus 还支持SSL,这样就可以方便的调试 https 请求了.使用SSL时需要提供证书的名字, runserver_plus 会自动生成一个证书:

$ python manage.py runserver_plus --cert cert
Validating models...
0 errors found

Django version 1.6.dev20130122125534, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
Quit the server with CONTROL-C.
 * Running on https://127.0.0.1:8000/
 * Restarting with reloader
Validating models...
0 errors found

Django version 1.6.dev20130122125534, using settings 'mysite.settings'
Development server is running at http://127.0.0.1:8000/
Using the Werkzeug debugger (http://werkzeug.pocoo.org/)
Quit the server with CONTROL-C.

执行上面的命令后就可以通过 https://127.0.0.1:8000 在安全模式下访问服务了.在项目目录下会创建2个新的文件,分别是密钥文件和证书文件.重启测试服务时,这2个文件会被保留下来,这样浏览器就不用反复处理证书授权了.如果想使用指定证书文件,可以使用路径参数指向该证书文件:

$ python manage.py runserver_plus --cert /tmp/cert

使用SSL时需要安装 OpenSSL 库. Werkzeug 0.9版本后才允许重用证书文件.通过以下命令安装 OpenSSL 库:

$ pip install pyOpenSSL

配置

设置 RUNSERVERPLUS_SERVER_ADDRESS_PORT 来跳转开发环境中使用的地址和端口

如果可以通过以下命令启动服务:

$ python manage.py runserver_plus 0.0.0.0:8000

那么就可以设置开发时使用的默认地址和端口:

RUNSERVERPLUS_SERVER_ADDRESS_PORT = '0.0.0.0:8000'

添加设置, 使Werkzeug在console中输出log:

LOGGING = {
    ...
    'handlers': {
        ...
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        ...
        'werkzeug': {
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

CPU及IO的用量

这个问题 gh625 导致 runserver_plus 在系统空闲时会占用很多系统资源. 这是因为 Werkzeug 包含了一个自动重新加载的功能. 通过 stat pollingfile system events 两种方式来实现自动重新加载.

`stat polling`这种自动重新加载的方式十分简单粗暴. 导致的问题是系统资源占用率高.

安装 Watchdog_ 包后, 它会不断尝试使用 file system events 方式, 能使用就自动使用.

更多内容参考 Werkzeug 文档

通过两种方式来设置自动重新加载的参数, Django配置文件:

RUNSERVERPLUS_POLLER_RELOADER_INTERVAL = 5

或者通过命令行参数”

$ python manage.py runserver_plus –reloader-interval 5

调试 (Debugger PIN)

Werkzeug 0.11 开始调试工具受到PIN的保护. 这种方式能模拟生产环境, 真实的用户使用的情景下调试. PIN默认开启认证功能.

调试器启动时, 首先会在命令行里输出PIN, 这个PIN是通过安全方式生成的并针对当前项目的. 由环境变量 WERKZEUG_DEBUG_PIN 生成的PIN, 遇到服务重启的时候很难达到安全模式. This can be set to a number and will become the PIN. This variable can also be set to the value off to disable the PIN check entirely.

如果执行了多次错误的PIN的插入方式, 那么就需要重启当前服务了.

这个功能不是为了鼓励线上调试的. 而是为了避免攻击者利用线上调试功能. 在生产环境中, 永远不要开启调试功能.