Skip to main content
 首页 » 编程设计

python之一台服务器,2个站点,1个用 Varnish 缓存,另一个不能删除 session

2025年05月04日11开发

场景如下: 1x EC2 微型实例,托管 2 个站点,1 个 wordpress 博客和 1 个 flask-powered 站点,例如:wpsite.com 和 flasksite.com。 两者都由监听 8080 的 nginx 提供,然后监听 80 的 varnish 充当 nginx 的代理。 我只需要缓存 wpsite.com 并且我想跳过 flasksite.com 的缓存引擎。

这是 VCL:

backend default { 
    .host = "127.0.0.1"; 
    .port = "8080"; 
} 
 
acl purge { 
    "127.0.0.1"; 
} 
 
sub vcl_recv { 
   if (!req.http.host ~ "^(www\.)?wpsite\.com$") { 
        return(pass); 
   } 
 
   remove req.http.X-Forwarded-For; 
   set req.http.X-Forwarded-For = client.ip; 
 
   if (req.request == "PURGE") { 
     if (!client.ip ~ purge) { 
       error 405 "Not allowed."; 
     } 
     return(lookup); 
   } 
  if (req.http.Accept-Encoding) { 
    #revisit this list 
    if (req.url ~ "\.(gif|jpg|jpeg|swf|flv|mp3|mp4|pdf|ico|png|gz|tgz|bz2)(\?.*|)$") { 
      remove req.http.Accept-Encoding; 
    } elsif (req.http.Accept-Encoding ~ "gzip") { 
      set req.http.Accept-Encoding = "gzip"; 
    } elsif (req.http.Accept-Encoding ~ "deflate") { 
      set req.http.Accept-Encoding = "deflate"; 
    } else { 
      remove req.http.Accept-Encoding; 
    } 
  } 
  if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") { 
    unset req.http.cookie; 
    set req.url = regsub(req.url, "\?.*$", ""); 
  } 
  if (req.url ~ "\?(utm_(campaign|medium|source|term)|adParams|client|cx|eid|fbid|feed|ref(id|src)?|v(er|iew))=") { 
    set req.url = regsub(req.url, "\?.*$", ""); 
  } 
  if (req.http.cookie) { 
    if (req.http.cookie ~ "(wordpress_|wp-settings-)") { 
      return(pass); 
    } else { 
      unset req.http.cookie; 
    } 
  } 
} 
 
sub vcl_fetch { 
  if (req.url ~ "manager" || req.url ~ "wp-(login|admin)" || req.url ~ "preview=true" || req.url ~ "xmlrpc.php") { 
    return (hit_for_pass); 
  } 
  if ( (!(req.url ~ "manager" ||  req.url ~ "(wp-(login|admin)|login)")) || (req.request == "GET") ) { 
    unset beresp.http.set-cookie; 
   set beresp.ttl = 1h; 
  } 
  if (req.url ~ "\.(gif|jpg|jpeg|swf|css|js|flv|mp3|mp4|pdf|ico|png)(\?.*|)$") { 
    set beresp.ttl = 365d; 
  } 
} 
 
sub vcl_deliver { 
   if (obj.hits > 0) { 
     set resp.http.X-Cache = "HIT"; 
   } else { 
     set resp.http.X-Cache = "MISS"; 
   } 
} 
sub vcl_hit { 
  if (req.request == "PURGE") { 
    set obj.ttl = 0s; 
    error 200 "OK"; 
  } 
} 
 
sub vcl_miss { 
  if (req.request == "PURGE") { 
    error 404 "Not cached"; 
  } 
} 

问题: 一切似乎都很好但是: 我在 flasksite.com 中有一个依赖于 cookie-session 的登录系统:如果我登录,系统会工作,但如果我想注销,cookie 会保留在那里。

这些是 flasksite.com 的登录/注销 View :

@bp.route('/logout', methods=['POST']) 
def logout(): 
    if 'username' in session: 
        del session['username'] 
    return redirect(url_for('.start')) 
 
@bp.route('/login', methods=['POST']) 
def login(): 
    if 'username' not in session: 
        db_user = database.get_user(request.form['username']) 
        if db_user: 
            if check_password(db_user['password'], request.form['password']): 
                session['username'] = request.form['username'] 
                if 'remember_flag' in request.form: 
                    session.permanent = True 
                else: 
                    session.permanent = False 
            else: 
                pass # wrong password 
        else: 
            pass # user not in db 
    return redirect(url_for('.start')) 

如果我在 nginx 和客户端之间放置 varnish,一切都会像魅力一样。 感谢您的任何提示 :)

请您参考如下方法:

好的,我已经解决了在 vcl_fetch 中添加以下内容:

  if (!req.http.host ~ "^(www\.)?wpsite\.com$") { 
     return (hit_for_pass); 
  }