1

我正在对基于 Python/Redis 的 API 进行原型设计,并使用 Bottle 提供 JSON,但不幸的是,开箱即用的 Bottle 在负载和高并发下表现不佳。对真实流量的一些初始测试导致 python 脚本崩溃而没有终止,这意味着 API 没有响应并且没有重新启动*。

目前在性能和文档方面扩展 Python/Redis API 的最佳解决方案是什么。我发现瓶子+greenlet 解决方案的文档记录很差,对于像我这样的 Python 初学者来说也不容易实现。我听说tornado 很好,但它与Redis 的集成比Bottle 慢。

*似乎当瓶子无法将HTTP请求的主体发送到客户端时,服务器会出现“[Errno 32] Broken pipe”错误,这似乎是服务器停止工作的一个不好的理由

4

3 回答 3

3

您是否已经阅读过有关此主题的Bottle 文档

Bottle 在重负载下表现得非常好——我用它每天处理数百万个请求——但如果你需要并发或高性能,你不能使用它的默认 HTTP 服务器。(默认情况下,Bottle 只使用wsgiref.WSGIServer,它是单线程的,不适用于任何高性能应用程序。)

在生产中,我使用mod_wsgi在 Apache 中运行 Bottle 。(这是一个例子。)扩展性非常好;瓶子本身增加的开销可以忽略不计。

换句话说:您的性能瓶颈不是由 Bottle 引起的,而是由您的 HTTP 服务器引起的。选择可扩展的服务器,您会看到更好的性能。

希望有帮助!


编辑 2015

我发现 Bottle 有其局限性,对于更高的并发性(每个核心数千 QPS),Bottle 不会这样做。(瓶颈似乎是 Bottle 对线程本地存储的使用和 gevent 的 TLS 实现之间的交互。)我没有使用falcon它,它在高负载下的性能比 Bottle 更好。

于 2013-11-05T14:16:48.910 回答
1

如果您是初学者,则不应从 evented (twisted/tornado/gevent/eventlet...) 库开始。

它会带你去你不知道的地方!

如果您需要扩展添加机器并使用负载平衡器平衡负载。

于 2013-11-05T11:09:35.187 回答
0

根据您的应用程序的特定要求,您可能会从尝试我的多线程 Python WSGIServer实现中受益。(这是我自己博客上的页面。)

它是 的直接替代品wsgiref.WSGIServer,因此您可以将其与 Bottle 一起使用,只需进行最少的更改。

基本上,它有点像 Apache 的workerMPM(但只有一个进程):每个请求都将由 N 个预分配线程池中的自己的线程处理。

我发现它在我希望在我的 Bottle 应用程序中实现并发但我不喜欢使用 Apache 或引入任何其他重要的服务器依赖项的情况下很有用。

这是一个例子:

import bottle
import time

app = bottle.Bottle()

@app.route('/')
def foo():
    time.sleep(2)
    return 'hello, world!\n'

app.run(server=MTServer, host='0.0.0.0', port=8080, thread_count=3)

# Here, app is nonblocking; it will handle up to 3 requests concurrently.
# A 4th concurrent request would block until one of the first 3 completed.

如果你试一试,请告诉我,它是如何工作的。(欢迎提出建议和贡献。谢谢!)

(将其添加为单独的答案,因为它比我之前的答案更激进。)

于 2013-11-05T14:35:11.880 回答