如何分析 `paster serve` 的启动时间?

2 投票
3 回答
561 浏览
提问于 2025-04-15 15:49

在Python中,使用 paster serve app.ini 启动应用程序时,准备好处理第一个请求的时间比我预期的要长。

我知道怎么用中间件来分析请求的性能,但我该怎么分析初始化的时间呢?我希望它在准备好服务后,不要再创建线程池,并且能尽快退出,这样准备好后的时间就不会被算在分析里。

3 个回答

1

一般来说,你可以在代码的不同部分周围设置时间块,然后添加一些日志记录的语句。至于初始化后的关闭部分,我对你使用的具体内容不太了解。

补充:我用过这个中间件来帮助我找到性能瓶颈。它现在是一个werkzeug中间件,你可能可以根据自己的需要进行调整。希望对你有帮助。

import re
re_profile = re.compile(ur'(^|&|\?)prof($|=|&)')
class ProfilerMiddleware(BaseProcessor):
    def process_runner(self, runner, environ):
        self.profiler = None
        if (environ['REMOTE_ADDR'] in settings_static.internal_ips or settings_static.local_server) and re_profile.match(environ['QUERY_STRING']):
            self.profiler = cProfile.Profile()
            def wrap(*args, **kwargs):
                return self.profiler.runcall(runner, *args, **kwargs)
            return wrap

    def process_response(self, request, response):
        if self.profiler:
            self.profiler.create_stats()
            out = StringIO.StringIO()
            old_stdout, sys.stdout = sys.stdout, out
            #from dozer.profile import buildtree, write_dot_graph
            #write_dot_graph(self.profiler.getstats(), buildtree(self.profiler.getstats()), "/tmp/output.gv")
            self.profiler.print_stats(1)
            sys.stdout = old_stdout
            response.response = [u'<pre>%s</pre>' % to_unicode(out.getvalue())]
            response.content_type = 'text/html'
1

即使你对它进行性能分析,我也怀疑能得到多少优化的建议。

我们在 mod_wsgi 的环境中使用 Paster,为了减少启动时间,让用户不会感到影响,并确保像 toscawidgets 这样的组件能够正确设置,我们这样做:

app = paste.fixture.TestApp(application)
# TODO-dir: FIXME, must go away!
try:
    app.get("/")
except:
    pass

这里的应用程序当然是已经初始化和加载的 Paster 应用。

1

在开发的时候,我几乎总是使用 paster serve --reload ... 这个命令。这个命令会自己启动一个子进程(它是用 subprocess 模块来执行自己的脚本,而不是用 fork())。

这个子进程会监测源代码的变化,一旦发现有变化就会退出,然后由父进程 paster serve --reload 重新启动它。

也就是说,如果你想要分析 paster serve 本身的性能,就不要加上 --reload 这个参数。使用中间件分析单独的请求无论如何都是可以的。

我遇到的具体问题是,pkg_resources 在第一次调用时会花费与所有已安装包数量成正比的时间。我通过重建我的虚拟环境,去掉不必要的包来解决了这个问题。

撰写回答