清漆,提前退出的自定义子例程

Varnish, custom subroutine with early exit

我是清漆新手。在编辑我们的后端选择器子例程时,我发现自己在 Varnish 配置文件中寻找早期的 return 模式。

sub select_backend {
  if (req.http.host ~ "tracking\..*") {
    set req.backend = tracking;
  }

  if (req.http.host ~ "myapp1.domain.com") {
    if (req.url ~ "^/insecure/path") {
      error 403 "Forbidden";
    }
    set req.backend = app1;
  }

  if (req.http.host ~ "myapp2.domain.com") {
    set req.backend = app2;
  }
}

sub vcl_recv {
  // other stuffs
  call select_backend;
}

如果没有正确的 return/exit 语句,则存在更改后端两次的风险(随着文件变得越来越复杂)。 是否可以使用早期的 return 模式来避免这种情况?如果不是,我如何在不浪费性能的情况下避免 if/elseif 模式?

目前没有很好的方法来做到这一点,正如Syntax part of VCL Basics解释的那样:

The "return" statement of VCL returns control from the VCL state engine to Varnish. If you define your own function and call it from one of the default functions, typing "return(foo)" will not return execution from your custom function to the default function, but return execution from VCL to Varnish. That is why we say that VCL has terminating statements, not traditional return values.

Some other people 有过类似需求,推荐如下:

  if (req.http.host ~ "tracking\..*") {
    set req.backend = tracking;
  } elsif (req.http.host ~ "myapp1.domain.com") {
    if (req.url ~ "^/insecure/path") {
      error 403 "Forbidden";
    }
    set req.backend = app1;
  } elsif (req.http.host ~ "myapp2.domain.com") {
    set req.backend = app2;
  }

如果你保持模式 if .. elsif 应该没有机会设置两次支持。如果你保持单独的 if { } 块,你可以让这种情况发生。