Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
571 views
in Technique[技术] by (71.8m points)

magento2 - Magento 2 Show differnt price for different customers causing issue with Fastly

I just want to show different price for different customers. But I don't want to make any block cachable false. The Issue is when a customer loads a category page then it cache generates and for all customers that cached pages shows. I fix that for normal magento FPC. But for the Fastly it is not working, Any Idea??


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

From what I understand you have a page ('category') where the content is different for each of your customers but you're finding that the first customer that requests your 'category' page is causing their variation of the content to be cached and so all other customers are seeing the exact same response served from the cache.

e.g. you have two customers: A and B. The A customer should see the content "A" while the B customer should see the content "B". Currently you'll finding that when customer A requests the page first followed by customer B requesting the same page, customer B is now seeing content "A" (as that version of the response was cached first).

This is typically where you would utilize the Vary response header with maybe a session id or cookie header.

Fastly has a blog post which explains what the Vary header does, along with lots of examples of how you might want to use it:
https://www.fastly.com/blog/getting-most-out-vary-fastly

Fastly also has a Vary reference page that might help:
https://developer.fastly.com/reference/http-headers/Vary/

You can actually find an example of using Vary with a cookie on Fastly's "Recipe" page (although it doesn't quite fit your exact requirements):
https://developer.fastly.com/solutions/recipes/vary-based-on-a-cookie

The reason this example isn't quite correct is because they use a custom header called logged-in as the request header to vary content responses on. You want a request header that would always be sent by the client and which contains a unique value (such as a cookie).

So I'm going to demonstrate a modified version of it:
https://fiddle.fastlydemo.net/fiddle/e3aa91a5

Note: I would recommend reaching out to your Fastly support contact because they might be able to advise on a better solution than the one I propose below. The concern I have is that I believe there might be limitations on the number of unique variants of a single object in the Fastly cache and so for example if the limit was something like 100 variants (I made up that number, I've no idea what it would be) and you had 101 customers then this solution wouldn't work for you.

For posterity (in case the Fastly recipe page or my own example is removed in the future) I'll copy paste the relevant code below...

Note: if you need help with understanding VCL and the various subroutines I mention below, then you can read up on it here: https://developer.fastly.com/learning/vcl/using with a more specific reference guide for each subroutine here: https://developer.fastly.com/reference/vcl/subroutines/

vcl_recv

In the following code snippet, in the vcl_recv subroutine, I log the Cookie set by the incoming client request. I do this just so you can visually see which client has made a request.

The vcl_recv subroutine is the first subroutine executed by a Fastly server, meaning you can inspect and manipulate the incoming request from a client before it is either looked up in the cache or before a request is made to your backend server (to acquire the requested content if it doesn't exist in the cache yet).

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

vcl_fetch

In the following code snippet, in the vcl_fetch subroutine, I first check the request URL matches /anything and if it does I then look to see if the client making the request has a user-login cookie set. If they do, then I manipulate the response from the backend server to include a Vary header with Cookie as its value (or I append Cookie if there was already a Vary HTTP header on the backend's response).

The vcl_fetch subroutine is executed after content has been sent from your backend server and fastly's cache node has received it, but the cache server hasn't yet cached the response (it'll cache the response once the vcl_fetch subroutine has finished executing) meaning it's a perfect time to manipulate the response and add a Vary HTTP header.

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

What this code demonstrates is: when both customer A and B are logged into your site and they both have a relevant session cookie set, then when either of them request your category page they'll both (initially) go to your backend server for the content (because nothing will be cached yet), and then each unique response will be cached using the value from the incoming request.

You can see a fully working example here using Fastly's 'fiddle' tool (useful for testing and debugging): https://fiddle.fastlydemo.net/fiddle/e3aa91a5

I hope this helps in some way. Otherwise I'd suggest reaching out to Fastly support. https://support.fastly.com/hc/en-us has an online community which can help you (also there is a 'speech bubble' icon at the bottom right of the screen where you can drill down to contact the support team, and send them an email via an online form).

UPDATE

I had some feedback regarding my above suggestion and (as I predicted) using Vary: Cookie isn't recommended...

If the reason you're doing this is because the response from the origin is different for each user, then in practice Cache-Control: private is better. That way Fastly will not attempt to cache it, but the browser will still cache it.

However, if the granularity of the response is actually much less, e.g. you're varying simply because some people have access to the content, and others don't, then it makes sense to cache the content, and to validate the cookie at the edge (much like: https://developer.fastly.com/solutions/recipes/vary-based-on-a-cookie)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...