Magento2 Magento 2针对不同的客户显示不同的价格,导致Fastly出现问题

Magento2 Magento 2针对不同的客户显示不同的价格,导致Fastly出现问题,magento2,fastly,Magento2,Fastly,我只是想为不同的客户展示不同的价格。但我不想让任何块可计算为假。问题是,当客户加载一个类别页面时,它会生成缓存,并为所有客户显示缓存页面。我修正了普通magento FPC的问题。但对于Fastly来说,它不起作用,有什么想法吗?据我所知,你有一个页面(“类别”)其中,您的每个客户的内容都不同,但您发现第一个请求您的“类别”页面的客户导致缓存其内容的变化,因此所有其他客户都看到缓存提供的完全相同的响应 e、 g.您有两个客户:A和B。A客户应看到内容“A”,而B客户应看到内容“B”。目前,您会发

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

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

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

这通常是使用
Vary
响应头的地方,响应头可能带有会话id或cookie头

Fastly有一篇博文,解释了
Vary
标题的作用,以及许多您可能希望如何使用它的示例:

Fastly还有一个
Vary
参考页面,可能会有所帮助:

您可以在Fastly的“配方”页面上找到一个将
Vary
与cookie一起使用的示例(尽管它并不完全符合您的确切要求):

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

因此,我将演示它的一个修改版本:

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

为了子孙后代(以防Fastly配方页面或我自己的示例将来被删除),我将复制粘贴下面的相关代码

注意:如果您需要了解VCL和我在下面提到的各种子程序的帮助,那么您可以在此处阅读:此处为每个子程序提供了更具体的参考指南:

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

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

取数 在下面的代码片段中,在
vcl\u fetch
子例程中,我首先检查请求URL是否与
/anything
匹配,如果匹配,则查看发出请求的客户端是否设置了
用户登录
cookie。如果他们这样做了,那么我操纵来自后端服务器的响应,以包含一个
Vary
头,并将
Cookie
作为其值(或者如果后端的响应上已经有一个
Vary
HTTP头,我会附加Cookie)

vcl\u fetch
子例程在从后端服务器发送内容并且fastly的缓存节点接收到内容后执行,但缓存服务器尚未缓存响应(一旦
vcl\u fetch
子例程完成执行,它将缓存响应)这意味着现在是处理响应并添加
Vary
HTTP头的最佳时机

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";
    }
  }
}
这段代码演示的是:当客户A和B都登录到您的站点,并且他们都有一个相关的会话cookie集时,当他们中的任何一个请求您的类别页面时,他们都(最初)会转到您的后端服务器获取内容(因为还没有缓存任何内容),然后,将使用传入请求的值缓存每个唯一响应

您可以在这里看到一个使用Fastly的“fiddle”工具(用于测试和调试)的完整工作示例:

我希望这在某种程度上有所帮助。否则,我建议伸出手来快速支持。有一个在线社区可以帮助您(屏幕右下角还有一个“语音泡泡”图标,您可以在这里向下搜索以联系支持团队,并通过在线表单向他们发送电子邮件)

更新 我收到了一些关于我上述建议的反馈,并且(正如我预测的那样)不推荐使用
Vary:Cookie

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

但是,如果响应的粒度实际上要小得多,例如,您的变化仅仅是因为一些人可以访问内容,而其他人不能,那么缓存内容并在边缘验证cookie是有意义的(很像:)

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";
    }
  }
}