Magento 2 为不同的客户显示不同的价格,导致 Fastly

问题描述

我只想为不同的客户显示不同的价格。但我不想让任何块缓存为假。问题是当客户加载类别页面时,它会缓存生成并为所有客户显示缓存页面。我为普通的 magento FPC 修复了这个问题。但是对于 Fastly 它不起作用,有什么想法吗??

解决方法

据我所知,您有一个页面(“类别”),其中每个客户的内容都不同,但您发现第一个请求您的“类别”页面的客户正在导致他们 要缓存的内容的变化,因此所有其他客户都会看到从缓存中提供的完全相同的响应。

例如您有两个客户:A 和 B。A 客户应该看到内容“A”,而 B 客户应该看到内容“B”。目前您会发现,当客户 A 首先请求页面,然后客户 B 请求同一页面时,客户 B 现在看到的是内容“A”(因为该版本的响应首先被缓存)。

这通常是您将 Vary 响应标头与会话 ID 或 cookie 标头一起使用的地方。

Fastly 有一篇博文解释了 Vary 标头的作用,以及许多您可能希望如何使用它的示例:
https://www.fastly.com/blog/getting-most-out-vary-fastly

Fastly 还有一个 Vary 参考页面可能会有所帮助:
https://developer.fastly.com/reference/http-headers/Vary/

您实际上可以在 Fastly 的“食谱”页面上找到将 Vary 与 cookie 一起使用的示例(尽管它完全不符合您的确切要求):
https://developer.fastly.com/solutions/recipes/vary-based-on-a-cookie

这个例子不太正确的原因是他们使用一个名为 logged-in 的自定义标头作为请求标头来改变内容响应。您需要一个始终由客户端发送并包含唯一值(例如 cookie)的请求标头。

所以我将演示它的修改版本:
https://fiddle.fastlydemo.net/fiddle/e3aa91a5

注意:我建议与您的 Fastly 支持联系人联系,因为他们可能会就比我在下面建议的解决方案更好的解决方案提出建议。我担心的是,我认为 Fastly 缓存中单个对象的唯一变体的数量可能存在限制,例如,如果限制是 100 个变体(我编造了这个数字,我不知道)它会是什么)并且您有 101 个客户,那么此解决方案对您不起作用。

为了后代(以防将来删除快速食谱页面或我自己的示例)我将复制粘贴下面的相关代码...

注意:如果您在理解 VCL 和我在下面提到的各种子例程方面需要帮助,那么您可以在这里阅读:https://developer.fastly.com/learning/vcl/using 以及每个子例程的更具体的参考指南此处:https://developer.fastly.com/reference/vcl/subroutines/

vcl_recv

在以下代码片段的 vcl_recv 子例程中,我记录了传入客户端请求设置的 Cookie。我这样做只是为了让您可以直观地看到哪个客户端发出了请求。

vcl_recv 子例程是 Fastly 服务器执行的第一个子例程,这意味着您可以检查和操作来自客户端的传入请求之前它要么在缓存中查找,要么在查找​​之前向您的后端服务器发出请求(如果缓存中尚不存在,则获取请求的内容)。

log "user-login: " + req.http.cookie:user-login;

vcl_fetch

在以下代码片段中,在 vcl_fetch 子例程中,我首先检查请求 URL 是否与 /anything 匹配,如果匹配,则查看发出请求的客户端是否具有 {{1 }} cookie 集。如果他们这样做,那么我操纵来自后端服务器的响应以包含一个 user-login 标头,其中 Vary 作为其值(或者如果已经有 Cookie HTTP 标头在后端的响应)。

Vary 子例程在您的后端服务器发送内容并且 fastly 的缓存节点收到它后执行,但缓存服务器尚未缓存响应(一旦 vcl_fetch 将缓存响应{1}} 子例程已完成执行)意味着现在是操作响应并添加 vcl_fetch HTTP 标头的最佳时机。

Vary

这段代码演示的是:当客户 A 和 B 都登录到您的网站并且他们都设置了相关的会话 cookie 时,当他们中的任何一个请求您的类别页面时,他们都会(最初)转到您的后端内容的服务器(因为尚未缓存任何内容),然后将使用传入请求中的值缓存每个唯一响应。

您可以在此处查看使用 Fastly 的“fiddle”工具(用于测试和调试)的完整示例: https://fiddle.fastlydemo.net/fiddle/e3aa91a5

我希望这在某种程度上有所帮助。否则,我建议联系 Fastly 支持。 https://support.fastly.com/hc/en-us 有一个可以为您提供帮助的在线社区(屏幕右下方还有一个“语音气泡”图标,您可以在其中深入联系支持团队,并通过在线表格向他们发送电子邮件).

更新

我收到了一些关于上述建议的反馈,并且(正如我预测的那样)不推荐使用 if (req.url ~ "^/anything") { if (req.http.cookie:user-login) { if (beresp.http.vary) { set beresp.http.vary = beresp.http.vary ",Cookie"; } else { set beresp.http.vary = "Cookie"; } } } ...

如果您这样做的原因是每个用户的源响应不同,那么实际上 Vary: Cookie 更好。这样 Fastly 就不会尝试缓存它,但浏览器仍然会缓存它。

但是,如果响应的粒度实际上要小得多,例如您之所以不同,仅仅是因为有些人可以访问内容,而其他人则不能,那么缓存内容并在边缘验证 cookie 是有意义的(很像:https://developer.fastly.com/solutions/recipes/vary-based-on-a-cookie

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...