在Google App Engine上分析/优化网站的最佳方法

15 投票
4 回答
3938 浏览
提问于 2025-04-15 10:58

我现在正在尝试优化我的网站,这个网站是运行在谷歌的应用引擎上的。这个任务并不简单,因为我没有使用任何强大的工具。

有没有人有经验可以分享,如何优化Python代码来达到这个目的?你们有没有找到好的Python性能分析工具?

4 个回答

3

为了分析API调用的情况,Guido van Rossum发布了一个叫做Appstats的库,它可以记录并展示你应用程序的很多有用信息。

你可以在这里获取这个库:https://sites.google.com/site/appengineappstats/

我在我的博客上写了一篇关于它的文章(里面有一些截图):http://blog.dantup.com/2010/01/profiling-google-app-engine-with-appstats

Appstats http://blog.dantup.com/pi/appstats_4_thumb.png

8

App Engine Mini Profiler 是一个新的应用引擎性能工具,可以直接使用。它能提供 API 调用的性能信息(通过 Appstats)以及所有函数调用的标准性能数据(通过 cProfiler)。

https://github.com/kamens/gae_mini_profiler

13

我发现 Gprof2Dot 非常有用。我尝试过的性能分析模块输出的结果看起来都不太容易理解。

Gprof2Dot 可以把 cProfile 的输出转换成一个漂亮的图表,最慢的那条链会被突出显示,并且每个函数会有一些信息,比如函数名、在这个函数上花费的时间百分比和调用次数。

这是一个示例图表 (1429x1896px)

我对 App Engine 的了解不多,但在分析非网页应用的脚本时,我通常会分析运行所有单元测试的脚本,这可能和实际情况不太一样。

一种(更好的?)方法是写一个脚本,模拟一个假的 WSGI 请求,然后对这个请求进行分析。

WSGI 是一个非常简单的协议,基本上就是一个接受两个参数的函数,第一个是请求信息,第二个是一个回调函数(用于设置头信息等)。可能像下面这样(这是可能工作的伪代码)……

class IndexHandler(webapp.RequestHandler):
    """Your site"""
    def get(self):
        self.response.out.write("hi")

if __name__ == '__main__':
    application = webapp.WSGIApplication([
        ('.*', IndexHandler),
    ], debug=True)

    # Start fake-request/profiling bit
    urls = [
        "/",
        "/blog/view/hello",
        "/admin/post/edit/hello",
        "/makeanerror404",
        "/makeanerror500"
    ]

    def fake_wsgi_callback(response, headers):
        """Prints heads to stdout"""
        print("\n".join(["%s: %s" % (n, v) for n, v in headers]))
        print("\n")

    for request_url in urls:
        html = application({
        'REQUEST_METHOD': 'GET',
        'PATH_INFO': request_url},
        fake_wsgi_callback
        )
        print html

实际上,App Engine 的文档解释了一种更好的分析应用程序性能的方法:

来自 http://code.google.com/appengine/kb/commontasks.html#profiling

要分析你应用程序的性能,首先把你应用程序的 main() 函数重命名为 real_main()。然后,添加一个新的主函数,命名为 profile_main(),像下面这样:

def profile_main():
    # This is the main function for profiling 
    # We've renamed our original main() above to real_main()
    import cProfile, pstats
    prof = cProfile.Profile()
    prof = prof.runctx("real_main()", globals(), locals())
    print "<pre>"
    stats = pstats.Stats(prof)
    stats.sort_stats("time")  # Or cumulative
    stats.print_stats(80)  # 80 = how many to print
    # The rest is optional.
    # stats.print_callees()
    # stats.print_callers()
    print "</pre>"

[...]

要在你的应用程序中启用性能分析,设置 main = profile_main。要正常运行你的应用程序,只需设置 main = real_main

撰写回答