Ruby on Railsアプリケーションの前に、varnish + nginxがあります。ログインしているユーザーでない限り、ほとんどのサイトのコンテンツは静的なので、ユーザーがログアウトしているときはニスでサイトを大量にキャッシュしますが、ログインしているときは静的アセットのみをキャッシュします。
ユーザーがログインすると、Cookie:ヘッダーに「user_credentials」というCookieが含まれます。さらに、ユーザーが最初に「user_credentials」Cookieを取得できるようにするには、/ loginと/ sessionsのキャッシュをスキップする必要があります。 。
RailsはデフォルトでキャッシュフレンドリーなCache-controlヘッダーを設定しませんが、ユーザーがログインしていない場合、アプリケーションは「public、s-max-age = 60」ヘッダーを設定します。Nginxは「farfuture」の期限切れヘッダーを返すように設定されていますすべての静的アセットに対して。
私が現在持っている構成は、静的アセットを含め、ログイン時にすべてのキャッシュを完全にバイパスし、ログアウトするとすべてのキャッシュMISSを返します。私は何時間も輪になって回っていました、そしてこれが私の現在のdefault.vclです
director Rails_director round-robin {
{
.backend = {
.Host = "xxx.xxx.xxx.xxx";
.port = "http";
.probe = {
.url = "/lbcheck/lbuptest";
.timeout = 0.3 s;
.window = 8;
.threshold = 3;
}
}
}
}
sub vcl_recv {
if (req.url ~ "^/login") {
pipe;
}
if (req.url ~ "^/sessions") {
pipe;
}
# The regex used here matches the standard Rails cache buster urls
# e.g. /images/an-image.png?1234567
if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
unset req.http.cookie;
lookup;
} else {
if (req.http.cookie ~ "user_credentials") {
pipe;
}
}
# Only cache GET and HEAD requests
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
}
sub vcl_fetch {
if (req.url ~ "^/login") {
pass;
}
if (req.url ~ "^/sessions") {
pass;
}
if (req.http.cookie ~ "user_credentials") {
pass;
} else {
unset req.http.Set-Cookie;
}
# cache CSS and JS files
if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
unset req.http.Set-Cookie;
}
if (obj.status >=400 && obj.status <500) {
error 404 "File not found";
}
if (obj.status >=500 && obj.status <600) {
error 503 "File is Temporarily Unavailable";
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
さて、最終的に私は次のvclファイルを使用してこれを解決することができました。バックエンドが停止したときにキャッシュの有効期限を確保できるように、いくつかのビットを追加したことに注意してください。
私の主な失敗は、unset req.http.Set-Cookie;
セクションでunset obj.http.Set-Cookie;
を使用する必要があったときにvcl_fetch
を使用したことだったようです。 (vcl_fetchのobj
およびvcl_recvセクションのreq
)。
director Rails_director round-robin {
{
.backend = {
.Host = "xxx.xxx.xxx.xxx";
.port = "http";
.probe = {
.url = "/lbcheck/lbuptest";
.timeout = 0.3 s;
.window = 8;
.threshold = 3;
}
}
}
}
sub vcl_recv {
if (req.backend.healthy) {
set req.grace = 30s;
} else {
set req.grace = 1h;
}
if (req.url ~ "^/login") {
pipe;
}
if (req.url ~ "^/sessions") {
pipe;
}
if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
unset req.http.cookie;
lookup;
} else {
if (req.http.cookie ~ "user_credentials") {
pipe;
} else {
unset req.http.cookie;
}
}
# Only cache GET and HEAD requests
if (req.request != "GET" && req.request != "HEAD") {
pipe;
}
}
sub vcl_fetch {
set obj.grace = 1h;
if (req.url ~ "^/login") {
pass;
}
if (req.url ~ "^/sessions") {
pass;
}
if (req.http.cookie ~ "user_credentials") {
pass;
} else {
unset obj.http.Set-Cookie;
}
# cache CSS and JS files
if (req.url ~ "\.(css|js|jpg|jpeg|gif|ico|png)\??\d*$") {
unset obj.http.Set-Cookie;
}
if (obj.status >=400 && obj.status <500) {
error 404 "File not found";
}
if (obj.status >=500 && obj.status <600) {
error 503 "File is Temporarily Unavailable";
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
}
コメントできないので、回答として投稿します。
重要:2.1.0以降、obj。*はvcl_fetchでberesp。*と呼ばれ、obj。*は読み取り専用になりました。
これらは、vcl_fetchではなくvcl_recvに配置する方が適切なようです。
if (req.url ~ "^/login") {
pipe;
}
if (req.url ~ "^/sessions") {
pipe;
}
最後に、バックエンドの定義に追加します
.max_connections = 32;
Nginx/Apacheに作成を許可したパッセンジャーバックエンドの数に調整します。この制限を設定しない場合は、乗客のグローバルキューを監視する必要があります(乗客を使用していると仮定します)。