Python瓶服务器端缓存

时间:2020-05-03 15:18:58

标签: python caching bottle cache-control

假设我们有一个基于Bottle的应用程序,如下所示:

from bottle import route, run, request, template, response
import time

def long_processing_task(i):
    time.sleep(0.5)      # here some more 
    return int(i)+2      # complicated processing in reality

@route('/')
def index():
    i = request.params.get('id', '', type=str)
    a = long_processing_task(i)
    response.set_header("Cache-Control", "public, max-age=3600")   # does not seem to work
    return template('Hello {{a}}', a=a)     # here in reality it's: template('index.html', a=a, b=b, ...)  based on an external template file

run(port=80)

显然要去http://localhost/?id=1http://localhost/?id=2http://localhost/?id=3等。 首次加载每页至少要花费500 ms。

如何使这些页面的后续加载更快?

更准确地说,有没有办法做到这两者:

  • 客户端缓存:如果用户A访问过http://localhost/?id=1次,则如果用户A第二次访问此页面,则会更快

  • 服务器端缓存:如果用户A访问过http://localhost/?id=1,则如果用户B 稍后访问了此页面(对于用户B来说是第一次! ),它也会更快
    换句话说:如果花费500毫秒来为一个用户生成http://localhost/?id=1,它将被所有将来的用户请求相同的页面。 (有这个名字吗?)

注意:

  • 在我的代码response.set_header("Cache-Control", "public, max-age=3600")中似乎无效。

  • this tutorial中提到了模板缓存:

    模板在编译后缓存在内存中。在您清除模板缓存之前,对模板文件所做的修改将不起作用。调用bottle.TEMPLATES.clear()这样做。在调试模式下禁用了缓存。

但我认为这与准备发送给客户端的最终页面的缓存无关。

1 个答案:

答案 0 :(得分:1)

服务器端

您要避免重复调用长时间运行的任务。一个可以在小范围内使用的幼稚解决方案是记住long_processing_task

from functools import lru_cache

@lru_cache(maxsize=1024)
def long_processing_task(i):
    time.sleep(0.5)      # here some more 
    return int(i)+2      # complicated processing in reality

更复杂的解决方案(更好地扩展)涉及在Web服务器之前设置反向代理(缓存)。

客户端

您将要使用响应标头来控制客户端如何缓存您的响应。 (请参见Cache-ControlExpires标头。)这是一个广泛的话题,许多细微的替代方案在SO答案中均不适用-例如,在要求客户端进行缓存时(它们需要付出一定的代价)在其本地缓存过期之前,不会获得更新的结果。

缓存的另一种方法是使用条件请求:当客户端已经收到最新消息时,使用ETagLast-Modified标头返回HTTP 304响应的版本。

这是个很有帮助的overview of the various header-based caching strategies