当调用相同的端点时,带有 CherryPy 的 Bottle 不会表现为多线程

Bottle with CherryPy does not behave multi-threaded when same end-point is called

据我所知,当与 CherryPy 服务器一起使用时,Bottle 应该是多线程的。我有一个简单的测试程序:

from bottle import Bottle, run
import time

app = Bottle()

@app.route('/hello')
def hello():
    time.sleep(5)

@app.route('/hello2')
def hello2():
    time.sleep(5)

run(app, host='0.0.0.0', server="cherrypy", port=8080)

当我通过打开 2 个选项卡并同时刷新它们来调用 localhost:8080/hello 时,它们不会同时 return 但其中一个在 5 秒后完成并且另一个在 5 秒后完成。

但是当我同时在一个选项卡中调用 /hello 并在另一个选项卡中调用 /hello2 时,它们会同时完成。

为什么同一个端点被调用两次时 Bottle 不表现为多线程?有没有办法让它成为多线程?

Python版本:2.7.6

瓶子版本:0.12.8

CherryPy 版本:3.7.0

OS:在 Ubuntu 14.04 64 位和 Windows 10 64 位

上都试过了

几乎可以肯定是您的浏览器在序列化请求。尝试使用两个不同的,或者更好的是一个真正的客户。它不会使用 curl.

为我重现

我已经在回答 one question 时遇到过这种行为,这让我很困惑。如果您四处搜索相关问题,那么该列表会一直持续下去。

怀疑是服务器端对 Keep-Alive、HTTP 流水线、缓存策略等的一些不正确处理。但实际上与服务器端完全没有关系。由于浏览器缓存实现(Firefox、Chromium),来自同一 URL 的并发请求被序列化。 The best answer 我在直接搜索 bugtrackers 之前发现,说:

Necko's cache can only handle one writer per cache entry. So if you make multiple requests for the same URL, the first one will open the cache entry for writing and the later ones will block on the cache entry open until the first one finishes.

确实,如果您在 Firebug 或 DevTools 中禁用缓存,效果不会持续。

因此,如果您的客户端不是浏览器,例如 API,请忽略该问题。否则,如果您确实需要从一个浏览器向同一个 URL(普通请求或 XHR)发出并发请求,请添加随机查询字符串参数以使请求 URL 唯一,例如http://example.com/concurrent/page?nocache=1433247395.