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