我想为 Rubygems 设置一个缓存服务器,因为我目前在越南,国际互联网连接速度很慢。我一直试图通过 Varnish 完成此操作,但经过几个小时的谷歌搜索和尝试各种方法后,我仍然卡住并且无法使其正常工作。
我的目标
这是我安装 gem 时的示例请求组:
GET http://api.rubygems.org/latest_specs.4.8.gz
302 Moved Temporarily
GET http://s3.amazonaws.com/production.s3.rubygems.org/latest_specs.4.8.gz
200 OK
我想设置一个反向代理缓存服务器(例如 rubygems.mydomain.com),在其中我可以执行以下请求,并且缓存服务器将在内部遵循任何重定向。
rubygems.mydomain.com/latest_specs.4.8.gz
重定向位置将链接到各种域(一些 rubygems 子域、Amazon S3、rubygems 镜像)。
当前状态
在摆弄了 nginx 之后,我发现这篇博文这非常接近我想要实现的目标。但是,我对 Varnish 的工作原理了解甚少,无法让它正常工作。
这是我现在的配置文件
import std;
backend rubygems {
.host = "rubygems.org";
.port = "80";
}
sub vcl_recv {
std.syslog(180, "RECV: " + req.http.host + req.url);
if (!req.url ~ "^http") {
std.syslog(180, "FETCH");
set req.backend = rubygems;
return (lookup);
}
}
sub vcl_fetch {
if (beresp.status == 302) {
set beresp.http.X-Magic-Redirect = "1";
return(deliver);
}
}
sub vcl_hit {
if (obj.http.X-Magic-Redirect == "1") {
set req.url = obj.http.Location;
return (restart);
}
}
sub vcl_deliver {
if (resp.http.X-Magic-Redirect == "1") {
unset resp.http.X-Magic-Redirect;
return(restart);
}
return(deliver);
}
我可以执行请求,但它响应错误:
curl -is http://localhost:8080/latest_specs.4.8.gz
HTTP/1.1 302 Found
Server: Varnish
Content-Type: text/html; charset=utf-8
Retry-After: 5
Content-Length: 376
Accept-Ranges: bytes
Date: Sat, 01 Feb 2014 02:33:47 GMT
X-Varnish: 933109322
Age: 1
Via: 1.1 varnish
Connection: close
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>302 Found</title>
</head>
<body>
<h1>Error 302 Found</h1>
<p>Found</p>
<h3>Guru Meditation:</h3>
<p>XID: 933109322</p>
<hr>
<p>Varnish cache server</p>
</body>
</html>
这是该请求对应的系统日志输出:
Jan 31 18:33:46 precise64 varnishd[2387]: RECV: localhost:8080/latest_specs.4.8.gz
Jan 31 18:33:46 precise64 varnishd[2387]: FETCH
Jan 31 18:33:47 precise64 varnishd[2387]: RECV: localhost:8080/latest_specs.4.8.gz
Jan 31 18:33:47 precise64 varnishd[2387]: FETCH
Jan 31 18:33:47 precise64 varnishd[2387]: RECV: localhost:8080http://production.s3.rubygems.org/latest_specs.4.8.gz
因此,对 Rubygems 的请求工作正常,但重定向无法按预期工作。如果有人能给我指明正确的方向,我会很高兴。
答案1
此时,当你从 rubygems 后端收到 302 状态时,你必须在 HTTP 标头指定的新位置再次发出请求地点在回应中。
你最终应该得到类似这样的结果:
vcl_fetch {
if (beresp.status == 302) { /* The content is on another location */
/* First change the host of the request*/
set req.http.host = regsub(regsub(beresp.http.Location, "^http://", ""), "^([^/]+)/.*$", "\1");
/* Then change the url of the request */
set req.url = regsub(beresp.http.Location, "^http://[^/]+/(.*)$", "/\1");
return (restart);
}
}
答案2
当我联系作者时愤怒的缓存代理,她回答道:
不幸的是,你的担心是正确的。两年前我离开了我为之写这篇文章的公司——这意味着我对维护它的兴趣相当低。而且似乎没有其他人在那里捡到它……
答案3
答案4
另一种方法是https://www.npmjs.org/package/angry-caching-proxy它提供了一个代理,可以在途中缓存宝石。