如果 Varnish 从主服务器收到 404 错误,是否可以将其配置为尝试使用第二个服务器获取某些资源?

发布于 2024-10-05 02:25:43 字数 346 浏览 0 评论 0原文

这对我来说是一个完美的解决方案,因为我需要向网络浏览器提供一些生成的内容。 我的计划是按需生成内容并存储以供下次使用。我不希望浏览器每次都调用我的服务(生成内容)。我希望他们直接访问“缓存”资源(如果可用),并且仅在不可用时调用该服务。 因此,我将 Varinsh 放在运行服务的服务器 A 和存储先前生成的内容版本的服务器 B 之前。如果它收到对尚未缓存的资源的请求,它将尝试服务器 B。收到 404 响应后,它将向服务器 A 请求相同的资源。

可以使用 VCL 以这种方式配置 Varnish 吗?如果没有,是否有您知道的类似解决方案?

PS 我不想将 302 重定向发送到浏览器,而且我无法控制服务器 B 使其发送此类重定向而不是 404

This would be a perfect solution for me as I need to serve some generated content to web browsers.
My plan is to generate the content on demand and store it for next time. I don't want the browsers to call my service (which generates the content) every time. I want them to go directly to the "cached" resource if it's available and only call the service if it's not.
So I'd put Varinsh in front of server A which runs the service and server B which stores the previously generated content versions. If it gets a request for a resource it hasn't got cached it'll try server B. Upon getting a 404 response it'll request the same resource from server A.

Can Varnish be configured in such a way with VCL? If not is there a solution like that you know about?

P.S. I don't want to send 302 redirects to the browser plus I don't have control over server B to make it send such redirects instead of 404's

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

a√萤火虫的光℡ 2024-10-12 02:25:43

这在 Varnish 中是完全可能的。确保在 vcl_fetch 中(也可能在 vcl_error 中)检查返回状态代码(例如,检查 status > 400),如果失败则重新启动,如果 req.restarts > 则在 vcl_recv 中选择另一个后端。 0. 例如:

backend serverA {
   .host="192.168.0.1";
   .port = "80";
}

backend serverB {
   .host = "192.168.0.2";
   .port = "80";
}

sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverB;
   } else {
       set req.backend = serverA;
   }
}

sub vcl_fetch {
    if (obj.status >= 400 && req.restarts == 0) {
        restart;
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       restart;
   }
}

但是话虽如此,听起来您正在重新发明缓存服务器的概念。 Varnish 是很棒的缓存服务器。为什么不拥有一台后端服务器(serverA)并让 Varnish 缓存您生成的实体?您可以设置复杂的规则,并且免费获得(缓存)过期、清除管理和性能! :)

This is perfectly possible in Varnish. Make sure that in vcl_fetch (and possibly in vcl_error) you check the return status code (e.g. check for status > 400), do a restart if it failed, and in vcl_recv select the other backend if req.restarts > 0. For example:

backend serverA {
   .host="192.168.0.1";
   .port = "80";
}

backend serverB {
   .host = "192.168.0.2";
   .port = "80";
}

sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverB;
   } else {
       set req.backend = serverA;
   }
}

sub vcl_fetch {
    if (obj.status >= 400 && req.restarts == 0) {
        restart;
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       restart;
   }
}

But this being said, it sounds like you're reinventing the concept of a cache server. And Varnish is great cache server. Why not have one back-end server (serverA) and have Varnish cache your generated entities? You can setup complex rules and you'll get expiration (of the cache), purge management and performance for free! :)

只等公子 2024-10-12 02:25:43

在这个例子中,varnish尝试在6台服务器中查找,如果没有找到,则显示最后一条消息。

# cat /etc/varnish/default.vcl 
backend serverA {
   .host="10.42.4.104";
   .port = "80";
}

backend serverB {
   .host = "10.42.4.102";
   .port = "80";
}

backend serverC {
   .host = "10.42.4.103";
   .port = "80";
}

backend serverD {
   .host = "10.42.4.101";
   .port = "80";
}

backend serverE {
   .host = "10.42.4.105";
   .port = "80";
}

backend serverF {
   .host = "10.42.4.106";
   .port = "80";
}




sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverA;
   } elseif (req.restarts == 1){
       set req.backend = serverB;
   } elseif (req.restarts == 2){
       set req.backend = serverC;
   } elseif (req.restarts == 3){
       set req.backend = serverD;
   } elseif (req.restarts == 4){
       set req.backend = serverE;
   } else {
       set req.backend = serverF;
   }
}


sub vcl_fetch {
    if (beresp.status >= 400 && req.restarts == 0) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 1) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 2) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 3) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 4) {
        return(restart);
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       return(restart);
   }
   if (req.restarts == 1) {
       return(restart);
   }
   if (req.restarts == 2) {
       return(restart);
   }
   if (req.restarts == 3) {
       return(restart);
   }
   if (req.restarts == 4) {
       return(restart);
   }

}

In this example, varnish try find in 6 servers, if not found, show the last msg.

# cat /etc/varnish/default.vcl 
backend serverA {
   .host="10.42.4.104";
   .port = "80";
}

backend serverB {
   .host = "10.42.4.102";
   .port = "80";
}

backend serverC {
   .host = "10.42.4.103";
   .port = "80";
}

backend serverD {
   .host = "10.42.4.101";
   .port = "80";
}

backend serverE {
   .host = "10.42.4.105";
   .port = "80";
}

backend serverF {
   .host = "10.42.4.106";
   .port = "80";
}




sub vcl_recv {
   if (req.restarts == 0) {
       set req.backend = serverA;
   } elseif (req.restarts == 1){
       set req.backend = serverB;
   } elseif (req.restarts == 2){
       set req.backend = serverC;
   } elseif (req.restarts == 3){
       set req.backend = serverD;
   } elseif (req.restarts == 4){
       set req.backend = serverE;
   } else {
       set req.backend = serverF;
   }
}


sub vcl_fetch {
    if (beresp.status >= 400 && req.restarts == 0) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 1) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 2) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 3) {
        return(restart);
    }
    if (beresp.status >= 400 && req.restarts == 4) {
        return(restart);
    }
}

sub vcl_error {
   if (req.restarts == 0) {
       return(restart);
   }
   if (req.restarts == 1) {
       return(restart);
   }
   if (req.restarts == 2) {
       return(restart);
   }
   if (req.restarts == 3) {
       return(restart);
   }
   if (req.restarts == 4) {
       return(restart);
   }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文