首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Magento 2显示不同客户的不同价格,导致Fastly出现问题

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

Stack Overflow用户
提问于 2021-01-05 19:00:00
回答 1查看 165关注 0票数 1

我只是想为不同的客户展示不同的价格。但我不想让任何块缓存都是假的。问题是,当客户加载一个类别页面时,它会缓存生成,并为所有客户显示缓存页面。我修复了正常的magento FPC。但是它很快就不工作了,你有什么想法吗?

EN

回答 1

Stack Overflow用户

发布于 2021-01-07 18:45:19

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

例如,您有两个客户: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

备注:我建议联系您的快速支持联系人,因为他们可能会提供比我下面提出的解决方案更好的解决方案。我担心的是,我认为快速缓存中单个对象的唯一变体的数量可能存在限制,例如,如果限制大约是100个变体(我虚构了这个数字,我不知道它会是多少),而你有101个客户,那么这个解决方案就不适用于你。

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

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

vcl_recv

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

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

代码语言:javascript
复制
log "user-login: " + req.http.cookie:user-login;

vcl_fetch

在下面的代码片段中,在URL子例程中,我首先检查请求vcl_fetch是否与/anything匹配,如果匹配,则查看发出请求的客户机是否设置了user-login cookie。如果是这样,那么我将操作来自后端服务器的响应,使其包含一个以Cookie作为其值的Vary头(或者,如果后端的响应中已经存在Vary HTTP头,则附加Cookie )。

HTTP子例程是在内容从后端服务器发送并且fastly的缓存节点收到之后执行的,但是缓存服务器还没有缓存响应(一旦vcl_fetch子例程执行完毕,它就会缓存响应),这意味着现在是操作响应并添加Vary HTTP头的绝佳时机。

代码语言:javascript
复制
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‘工具(对测试和调试很有用):https://fiddle.fastlydemo.net/fiddle/e3aa91a5

我希望这能在某种程度上有所帮助。否则,我会建议伸出援手,快速支持。https://support.fastly.com/hc/en-us有一个可以帮助你的在线社区(屏幕右下角也有一个“发言气泡”图标,你可以在那里深入联系支持团队,并通过在线表格给他们发送电子邮件)。

更新

我对上面的建议有一些反馈,并且(正如我所预测的)不推荐使用Vary: Cookie……

如果您这样做的原因是因为每个用户来自源的响应是不同的,那么在实践中Cache-Control: private更好。这种方式不会尝试缓存它,但浏览器仍然会缓存它。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65577584

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档