更新
好的,所以重新阅读原始发布者的问题,我意识到首先我误解了他们的要求,但后来我也注意到他们对 Kailan 回答的评论也略微调整了要求。
所以我的理解是现在的要求是......
- 根据传入的请求路径修改后端。
- 在不影响缓存的情况下修改传入请求路径(例如,原始请求路径将是缓存查找中使用的路径)。
例如,如果我们的默认后端是httpbin.org
并且传入的请求是,/services/users
那么我们希望后端更改为另一个后端(我们会说bbc.co.uk
)。
但是我们也希望路径从/services/user/
变为/
,而bbc.co.uk
后端的响应缓存在原始请求路径/services/users
/ 下。
这是一个证明这一点的小提琴:
https ://fiddle.fastlydemo.net/fiddle/e337b8f5
注意:您不能将字符串设置为的原因req.backend
是因为它需要被分配一个特定的BACKEND
类型。
如果小提琴链接停止工作,代码如下......
vcl_recv
if (req.url.path ~ "^/services/user/" ) {
// pretend www.bbc.co.uk is the correct backend for handling a 'user' request
set req.backend = F_origin_1;
}
注意:后端分配给递增变量F_origin_0
等F_origin_1
。所以在我的小提琴示例F_origin_0
中是 httpbin.orgF_origin_1
而是 bbc.co.uk
vcl_miss
if (req.url.path ~ "^/services/.*") {
set bereq.url = "/";
}
我的原始答案
Kailan 的答案是正确的,应该这样标记,但为了完整起见,我将更加充实它,以便原始海报对正在发生的事情有更清晰的概念理解......
对 Varnish 的传入请求被转换为req
通过各种状态/子例程传递的对象(例如vcl_recv
== 收到请求,vcl_deliver
== 请求已被处理,并且准备好将响应发送回客户端等)。
您的条件逻辑应该添加到子例程中,因为这是传入请求的第一个“状态”,也是您可以修改vcl_recv
请求的最早点。
可以使用return(<state>)
指令控制通过 Varnish 的请求对象的流程,该指令指示下一步要移动到什么状态。Varnish 具有默认行为,这意味着您不需要在每个可用子例程结束时显式调用return
(将为您调用一个将您的请求移动到下一个逻辑状态/子例程的决定),因此您决定显式更改默认值请求流的使用return
将取决于您要执行的操作(在您的情况下,您无需担心这一点)。
一个典型/默认的请求流程会让请求对象从vcl_recv
到移动,vcl_hash
因此 Varnish 可以生成一个“查找”键(用于查找先前缓存的请求版本),然后取决于是否找到了请求的缓存版本请求将移动到vcl_miss
(未找到缓存版本)或vcl_hit
(找到缓存版本)。
如果没有缓存内容,那么在vcl_miss
向您的后端/源服务器发出请求之后,来自后端的响应将vcl_fetch
作为beresp
对象提供给。最后,响应被传递到vcl_deliver
您可以修改响应的位置,然后再将其发送回客户端。
request ( req
) 对象通过所有这些状态/子例程传递,这意味着您可以在整个请求流程中的任何时候访问它。
如果您需要有关各种 VCL 子例程的更多指导(它们为什么存在,以及您可以在每个子例程中修改什么),那么请快速将它们全部记录在这里(以及一个漂亮的“请求流”图):https://developer .fastly.com/learning/vcl/using/