如何分析烧瓶端点?

Posted

技术标签:

【中文标题】如何分析烧瓶端点?【英文标题】:How to profile flask endpoint? 【发布时间】:2020-01-28 18:57:59 【问题描述】:

我想分析一个烧瓶应用程序端点,以查看它在执行端点函数时减速的地方。我曾尝试使用 Pycharms 内置分析器,但输出告诉我大部分时间都花在等待功能上,即等待用户输入。我已经尝试安装flask-profiler,但由于项目结构与包的预期不同而无法设置。任何帮助表示赞赏。谢谢!

【问题讨论】:

你试过cProfile吗? 我相信 cProfile 是 Pycharm 默认使用的 我在大多数情况下使用 Bottle 框架,cProfile 非常适合。 每当我使用 cProfile 运行我的开发服务器一段时间时,它都会报告我想要的一切。 所以我认为您可以使用 cProfile 分析您的烧瓶 webapp 并使用 snakeview 或其他方式可视化结果。 【参考方案1】:

Werkzeug 有一个基于 cProfile 的内置 application profiler。

在this gist 的帮助下,我设法进行了如下设置:

from flask import Flask
from werkzeug.middleware.profiler import ProfilerMiddleware
from time import sleep

app = Flask(__name__)
app.wsgi_app = ProfilerMiddleware(app.wsgi_app)

@app.route('/')
def index():
    print ('begin')
    sleep(3)
    print ('end')
    return 'success'

对该端点的请求,会在终端中产生以下摘要:

 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
begin
end
--------------------------------------------------------------------------------
PATH: '/'
         298 function calls in 2.992 seconds

   Ordered by: internal time, call count

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    2.969    2.969    2.969    2.969 built-in method time.sleep
        1    0.002    0.002    0.011    0.011 /usr/local/lib/python3.7/site-packages/flask/app.py:1955(finalize_request)
        1    0.002    0.002    0.008    0.008 /usr/local/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py:173(__init__)
       35    0.002    0.000    0.002    0.000 built-in method builtins.isinstance
        4    0.001    0.000    0.001    0.000 /usr/local/lib/python3.7/site-packages/werkzeug/datastructures.py:910(_unicodify_header_value)
        2    0.001    0.000    0.003    0.002 /usr/local/lib/python3.7/site-packages/werkzeug/datastructures.py:1298(__setitem__)
        1    0.001    0.001    0.001    0.001 /usr/local/lib/python3.7/site-packages/werkzeug/datastructures.py:960(__getitem__)
        6    0.001    0.000    0.001    0.000 /usr/local/lib/python3.7/site-packages/werkzeug/_compat.py:210(to_unicode)
        2    0.000    0.000    0.002    0.001 /usr/local/lib/python3.7/site-packages/werkzeug/datastructures.py:1212(set)
        4    0.000    0.000    0.000    0.000 method 'decode' of 'bytes' objects
        1    0.000    0.000    0.002    0.002 /usr/local/lib/python3.7/site-packages/werkzeug/wrappers/base_response.py:341(set_data)
       10    0.000    0.000    0.001    0.000 /usr/local/lib/python3.7/site-packages/werkzeug/local.py:70(__getattr__)
        8    0.000    0.000    0.000    0.000 method 'get' of 'dict' objects
        1    0.000    0.000    0.008    0.008 /usr/local/lib/python3.7/site-packages/flask/app.py:2029(make_response)
        1    0.000    0.000    0.004    0.004 /usr/local/lib/python3.7/site-packages/werkzeug/routing.py:1551(bind_to_environ)
        1    0.000    0.000    0.000    0.000 /usr/local/lib/python3.7/site-packages/werkzeug/_internal.py:67(_get_environ)
        1    0.000    0.000    0.001    0.001 /usr/local/lib/python3.7/site-packages/werkzeug/routing.py:1674(__init__)

[snipped for berevity]

您可以通过传递 restrictions 参数来稍微限制结果:

restrictions (Iterable[Union[str, int, float]]) – 一组过滤统计信息的限制。见pstats.Stats.print_stats()

因此,例如,如果您对位于 /code/app.py 的 python 文件感兴趣,您可以改为定义探查器,如下所示:

app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=('/code/app.py',))

导致输出:

 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
begin
end
--------------------------------------------------------------------------------
PATH: '/'
         300 function calls in 3.016 seconds

   Ordered by: internal time, call count
   List reduced from 131 to 2 due to restriction <'/code/app.py'>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    3.007    3.007 /code/app.py:12(index)
        1    0.000    0.000    2.002    2.002 /code/app.py:9(slower)


--------------------------------------------------------------------------------

通过一些调整,这可能有助于解决您的问题。

【讨论】:

以上是关于如何分析烧瓶端点?的主要内容,如果未能解决你的问题,请参考以下文章

分析和查找烧瓶应用程序的瓶颈---当前响应时间为 30 秒 [关闭]

烧瓶 api 端点使用邮递员返回正确的响应,但不使用浏览器(chrome)

如何使用烧瓶设置可插入视图的动态限制?

使用 Google Cloud Platform 运行 Websocket

错误:流式传输作业失败:流分析作业存在验证错误:当前不支持到端点的多个输入列

Spring boot 使用@Endpoint注解自定义端点, 不能通过 Restfult 访问问题 原因分析