如何在负载均衡器后使用django-compressor?

11 投票
3 回答
2598 浏览
提问于 2025-04-17 00:44

我有两台服务器,它们在一个负载均衡器后面。每台服务器上都运行着一个memcached服务器,并且它们的设置文件是一样的(简单来说,就是共享缓存)。

我希望生成的文件路径在这两台服务器上是相同的,这样客户端就不需要下载多次。

为了实现这一点,我需要了解django compressor是怎么工作的。

  • django compressor中的缓存到底是用来干嘛的?
  • 文件内容是存储在缓存中还是文件系统中?
    • 如果是的话,哪个先发生?
  • 我希望我问的问题是对的。如果你觉得有其他问题可以补充,请随意添加。

比起这个,如果能有更详细、更清晰的步骤说明就太好了。

编辑

  • 因为这两台服务器共享一个memcached服务器,我应该设置 COMPRESS_CACHE_KEY_FUNCTION = 'compressor.cache.socket_cachekey' 吗?(见开发分支)还是说使用相同的缓存键会影响我想要的相同文件名的目标?
  • 我理解的是,mtime是从源js/css文件中收集的,用来判断它们是否有变化,从而决定是否需要生成新的文件。对吗?
    • 这可能不是每次加载都会发生。那么它是什么时候发生的呢?

3 个回答

0

你应该把所有的压缩文件放在一个独立的存储空间,这个存储空间要在你的计算实例之外,也就是在负载均衡器后面。比如,你可以使用亚马逊的S3来存储所有文件,放在一个和你应用程序其他部分不同的子域名上。

这样,http://myapp.com 就指向你的负载均衡器,而 http://s3.myapp.com 则指向你的存储空间,比如亚马逊S3。这样你就不用担心在不同的实例上存储多个不同版本的文件了。

在这里你可以找到一个 关于如何设置亚马逊S3、Gzip压缩和django-compressor的完整指南,适用于Django框架。

12

在开发分支中,有一个新的选项可以更改 CSS 的哈希方法。你可以在这里查看:https://github.com/jezdez/django_compressor

具体可以查看 filters/css_default.py 文件的第61行

我使用的设置:

COMPRESS_ENABLED = True
COMPRESS_OFFLINE = False
COMPRESS_STORAGE = 'compressor.storage.GzipCompressorFileStorage'
COMPRESS_CSS_HASHING_METHOD = 'hash' # not using mtime since it differs between servers.

对于 JavaScript 文件来说,没有类似的选项,因为它们的哈希键本来就不会通过修改时间来生成。

在我的负载均衡器后面,这个方法运行得非常好。

写这段话时,开发分支中的最新提交是:https://github.com/jezdez/django_compressor/commit/d48bc5f45d5a55b0f826eb605ccf09a6bf33fcb9

4

如果你想要在两个服务器上有相同的缓存文件,你必须确保这两个服务器上的输入是完全一样的。

你需要检查:

  • {% compress %}...{% endcompress %} 之间的代码在两个服务器上是否完全相同(如果你同时部署到两个服务器,这应该是一样的)
  • 所有的 .css 和 .js 文件在两个服务器上是否完全相同(如果你同时部署到两个服务器,这应该是一样的)
  • 你的 .css 和 .js 文件的修改时间(mtime)在两个服务器上是否相同(你的部署脚本可能会影响这些文件的时间,设置为当前日期)

如果这些要求都满足,生成的文件应该是完全相同的(内容和名称)。

你可以使用 "stat" 这个 Unix 命令来检查修改时间。

关于你问题的回答:

  • django-compressor 中缓存的目的是减少对文件系统的读取。
  • 合并代码生成的文件只存储在文件系统中。

补充:

我在我的一个网站上检查过,它在负载均衡器后面。我有不同的 .css 文件名,但 .js 文件是相同的。

对于 .css 文件,我使用了预处理器(http://lesscss.org/),所以这会影响修改时间。

补充(话题发展后):

缓存中有什么?

根据 文档,django-compressor 在缓存中存储了两样东西:

  • 缓存文件的修改时间(每隔 COMPRESS_MTIME_DELAY 秒重新检查一次)
  • 完整生成的代码,例如:

    <link rel="stylesheet" href="http://cdn.inprl.pl/CACHE/css/117f97d818b8.css" type="text/css">

由于这种缓存的使用,django-compressor 将对文件系统的读取次数减少到 0。这对页面加载速度非常重要,因为从内存读取的速度比从文件系统读取快几百倍。而且,文件系统往往是性能瓶颈。

它是如何存储在缓存中的?

django-compressor 使用生成的键将代码存储在缓存中。这个键是根据以下内容生成的:

  • {% compress %}...{% endcompress %} 中的代码
  • {% compress %}...{% endcompress %} 中提到的文件的修改时间

所以如果你想要在所有服务器上得到一致的响应,这些内容必须是相同的。

附言:

请检查你服务器上的限制(比如修改时间),并在这里发布信息以确认它们是否匹配。

我可能下周会在我的网站上修复同样的问题,到时候会发布更多细节。

撰写回答