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

Posted

技术标签:

【中文标题】分析和查找烧瓶应用程序的瓶颈---当前响应时间为 30 秒 [关闭]【英文标题】:profiling and finding bottleneck of a flask application --- current respond time is 30 second [closed] 【发布时间】:2014-02-17 12:06:40 【问题描述】:

在过去的一个月里,我的 Flask 应用程序突然变得非常非常慢,我不知道是什么变化将响应时间从 1 秒以下提高到 30 秒

我一直在使用 Flask 和 MongoEngine,Redis 也用于缓存。 MongoDB 与 Flask 应用程序放置在同一台服务器上。

我尝试分析 Flask,以下是报告:

127.0.0.1 - - [17/Feb/2014 19:51:47] "GET / HTTP/1.0" 200 -
--------------------------------------------------------------------------------
PATH: '/items'
         637497 function calls (618866 primitive calls) in 30.961 seconds

   Ordered by: internal time, call count
   List reduced from 702 to 30 due to restriction <30>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      153   30.127    0.197   30.127    0.197 method 'recv' of '_socket.socket' objects
   319965    0.150    0.000    0.150    0.000 isinstance
 1322/740    0.079    0.000    0.178    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/dereference.py:147(_attach_objects)
       77    0.079    0.001    0.079    0.001 method 'sendall' of '_socket.socket' objects
 1322/740    0.077    0.000    0.159    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/dereference.py:68(_find_references)
    54670    0.046    0.000    0.046    0.000 hasattr
   774/80    0.032    0.000    0.207    0.003 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/document.py:539(_from_son)
      774    0.031    0.000    0.119    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/document.py:35(__init__)
12932/12792    0.028    0.000    0.057    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/document.py:113(__setattr__)
    15557    0.016    0.000    0.020    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/common.py:4(_import_class)
    46648    0.016    0.000    0.016    0.000 method 'get' of 'dict' objects
     8228    0.015    0.000    0.029    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/fields.py:94(__set__)
 1532/287    0.012    0.000    0.161    0.001 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/fields.py:233(to_python)
    11901    0.012    0.000    0.061    0.000 setattr
     8960    0.010    0.000    0.010    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/document.py:547(<genexpr>)
15629/5700    0.010    0.000    0.022    0.000 /usr/lib/python2.7/json/encoder.py:335(_iterencode_dict)
3328/3207    0.009    0.000    0.019    0.000 /usr/lib/python2.7/copy.py:145(deepcopy)
   685/61    0.008    0.000    0.032    0.001 /home/deploy/shopping/env/local/lib/python2.7/site-packages/pymongo/cursor.py:843(__deepcopy)
     3660    0.008    0.000    0.024    0.000 /usr/lib/python2.7/copy.py:66(copy)
10295/5668    0.008    0.000    0.019    0.000 /usr/lib/python2.7/json/encoder.py:282(_iterencode_list)
      424    0.007    0.000    0.361    0.001 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/fields.py:189(__get__)
      740    0.007    0.000    0.348    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/dereference.py:12(__call__)
      660    0.006    0.000    0.008    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/base/datastructures.py:15(__init__)
       72    0.005    0.000    0.007    0.000 bson._cbson.decode_all
      183    0.005    0.000    0.034    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/queryset/base.py:533(clone_into)
      241    0.005    0.000    0.023    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/queryset/transform.py:31(query)
      694    0.005    0.000    0.114    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/document.py:64(__init__)
      900    0.004    0.000    0.004    0.000 sorted
5388/5387    0.004    0.000    0.007    0.000 getattr
     5940    0.004    0.000    0.004    0.000 /home/deploy/shopping/env/lib/python2.7/site-packages/mongoengine/fields.py:241(to_python)

谁能给我指出找到瓶颈的方向,或者更有用的分析方法?

【问题讨论】:

docs.mongodb.org/manual/tutorial/manage-the-database-profiler 用于 mongodb 查询分析。 您也可以使用a single stackshot,它会告诉您所有需要了解的时间(29/30 = 97% 的概率)。 这个问题已经结束,所以我不能添加新的答案,但是任何人都可以登陆这个问题 - 现在有一个line profiling tool specifically for Flask now,而不是与标准的 line_profiler 竞争。 @roganjosh 不幸的是,这个工具似乎不适用于 flask-restful(flask 仅用于 API) @roganjosh 不幸的是,这个工具似乎不适用于 flask-restful(flask 仅用于 API) 【参考方案1】:

您的 30 秒用于对 sock.recv 的 153 次调用,每次大约需要 0.2 秒。

您现在需要找出谁在调用此函数,为此您需要来自分析器的调用图报告。不幸的是,调用图不包含在 Werkzeug 分析器中间件的摘要输出中,但如果您使用 profile_dir 参数,您可以将配置文件数据保存到文件中。

一旦你有了一个数据文件,你就可以使用一个简短的 Python 脚本来获取调用图,如下所示:

import pstats
stats = pstats.Stats('tmp/GET.root.000255ms.1392663371.prof')
stats.sort_stats('time', 'calls')
stats.print_stats()
stats.print_callers()

print_stats() 调用会打印您从 Werkzeug 获得的相同报告。 print_callers() 调用打印相应的调用图。输出会很长,所以你应该把它重定向到一个文件。

如果您不喜欢查看文本报告,那么您可以使用 gprof2dot 从相同的数据生成 GraphViz 图表。

希望这会有所帮助。

【讨论】:

【参考方案2】:

http://pythonhosted.org/line_profiler/

这是一个使用两个分析工具的教程,它在类似的情况下帮助了我。

【讨论】:

这个问题已经结束,所以我不能添加新的答案,但是任何人都可以登陆这个问题 - 现在有一个 line profiling tool specifically for Flask now 而不是与标准 line_profiler 竞争。 Snakeviz 是您可能要考虑的另一个工具。一个简单的“pip install”,你就有了一个关于瓶颈所在位置的交互式图表。非常好。

以上是关于分析和查找烧瓶应用程序的瓶颈---当前响应时间为 30 秒 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

性能瓶颈定位分析

烧瓶 301 响应

“由于语音响应为空,无法将 Dialogflow 响应解析为 AppResponse”,使用烧瓶助手

Azure 长响应时间瓶颈?

性能瓶颈分析思路

每日生产万亿消息数据入库,腾讯如何突破大数据分析架构瓶颈