17

首先请原谅我对 Varnish 完全缺乏了解。这是我第一次尝试用 Varnish 做任何事情。

我在以下示例:http ://www.kalenyuk.com.ua/magento-performance-optimization-with-varnish-cache-47.html

但是,当我安装并运行它时,Varnish 似乎没有缓存。我确实得到了带有单个数字的 X-Varnish 标头和一个值为 1.1 varnish 的 Via 标头

我被告知(我的 ISP)这是因为 Magento 设置了以下 cookie:

Set-Cookie: frontend=6t2d2q73rv9s1kddu8ehh8hvl6; expires=Thu, 17-Feb-2011 14:29:19 GMT; path=/; domain=XX.X.XX.XX; httponly

他们说我要么必须更改 Magento 来处理这个问题,要么配置 Varnish 来处理这个问题。由于更改 Magento 是不可能的,我想知道是否有人可以给我一个线索,告诉我如何配置 Varnish 来处理这个 cookie?

4

7 回答 7

9

http://moprea.ro/2011/may/6/magento-performance-optimization-varnish-cache-3/描述了使用 varnish 启用全页缓存的 Magento 扩展。这个扩展依赖于在 github 上发布的 Varnish 配置。

这些是已经实现的功能:

  1. 可用的清漆配置
  2. 使用 Varnish 启用整页缓存,这是一种超快速缓存 HTTP 反向代理。
  3. Varnish 服务器可在 Admin 中配置,位于 System / Configuration / General - Varnish Options
  4. 保存产品、类别和 CMS 页面时自动清除(仅)缓存页面。
  5. 在系统/缓存管理下的 Magento Admin 中添加新的缓存类型,并提供停用缓存和刷新缓存的可能性。
  6. 当保存类别导航并且需要刷新清漆缓存时通知管理员用户,以便为所有页面更新菜单。
  7. 为购物车中有产品或已登录的用户自动关闭清漆缓存等)
  8. 提供默认清漆配置,以便模块可用。屏幕截图:https ://github.com/madalinoprea/magneto-varnish/wiki
于 2011-05-25T08:00:02.167 回答
7

如何在 Varnish 中缓存 Magento(理论) - 这有 2 个组件

1) 静态资产(例如图像、CSS、JS)——这是一种简单的常见模式,涉及检测属于该类别的请求并设置缓存时间(或依赖于源服务器发送的缓存时间) 示例这是要点形式

2) HTML 文档——这是一个好的 Magento 解决方案中复杂得多的部分。在 Varnish 中缓存 HTML 文档以提高 Magento 性能至关重要。HTML 文档生成是 Magento 服务器将做的最昂贵(耗时)的事情。

缓存 HTML 文档的挑战来自个性化内容。

个性化内容和 HTML 文档

Magento 和所有其他电子商务网站通过会话管理特定用户的状态。会话是该特定用户在您网站上的状态的记录。这包括以下内容: “Hello Bob” - 位于页面顶部 “4 Things in Your Cart” - 您的购物车在每个页面上的状态

这些是不能在用户之间共享的项目,如果发生这种情况会导致重大问题(我们称之为“会话泄漏”)。

如果 HTML 页面包含有关人员是谁以及他们的购物车中有什么的个性化信息,我们如何缓存 HTML 页面?

实现这一点的主要方法有两种: 在页面加载后通过附加请求加载页面的个性化元素 这里一种常见的实现方法是使用 AJAX 请求个性化的页面元素 利用一种技术将 HTML 文档的组件标记为可缓存和其他不可缓存(或在用户之间不可共享)。Varnish 支持一种称为 ESI(Edge Side Includes)的技术,该技术允许以不同方式缓存 HTML 文档的不同部分。

您的 Varnish 实施策略必须考虑用户个性化。

Varnish 的实现选项

Magento 1.X - 在 Magento 版本 1 中缓存 HTML 文档的最广泛使用的方法是名为 Magento Turpentine 的开源产品(由 Nexus 提供)。这是一个已安装的插件(通过 Magento Connect),它会自动将 ESI 标签添加到您的 HTML 文档中,以便 Varnish 可以缓存这些资源。Magento 松节油安装/指南

Magento 2.X - Magento 的最新版本(目前处于测试阶段)支持 Varnish 作为其在生产中用于 HTML 缓存的推荐解决方案。这是个好消息,Varnish 是 Magento 推荐的选项,它可以开箱即用,以提高您的网站速度。

如何让 Varnish 和 Magento 运行良好

部署是一回事,一旦您实施了 Varnish Magento 解决方案并开始工作,接下来的步骤就是了解它的性能如何。获取有关缓存命中率的指标和基于请求的详细日志可能是一个挑战,因为它涉及部署一系列额外的基础设施(或被卡在一次性手动日志收集)。

我们最近构建了这个基础架构,以在云中将 Varnish 作为服务运行(具有完整的日志/指标) - www.section.io - 将其放在一边,这可能是您在 Varnish 和 Magento 项目中取得实际成功的最重要因素,因为您需要不断调整您的实现以管理诸如 url 中不同的查询字符串之类的事情(您好 google 分析“gclid”!),这可以显着降低缓存命中率

于 2015-08-07T06:08:10.067 回答
4

如果您使用 Varnish 3.0,您可能需要更改您的 .vcl 配置。这是我在 magento 和 varnish 3 中使用的内容:

    # This is a basic VCL configuration file for varnish.  See the vcl(7)
# man page for details on VCL syntax and semantics.
# 
# Default backend definition.  Set this to point to your content
# server.
# 
 backend default {
    .host = "127.0.0.1";
    .port = "8080";
 }

acl trusted {
    "127.0.0.1";
    "127.0.1.1";
    # Add other ips that are allowed to purge cache
}

# 
# http://www.varnish-cache.org/docs/2.1/tutorial/vcl.html#vcl-recv
# @param req    Request object
sub vcl_recv {
    if (req.http.x-forwarded-for) {
        set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
    }
    else {
        set req.http.X-Forwarded-For = client.ip;
    }

    if (req.request == "PURGE") {
        # Allow requests from trusted IPs to purge the cache
        if (!client.ip ~ trusted) {
           error 405 "Not allowed.";
        }
        ban("req.url ~ " + req.url);
        error 200 "Ok"; #We don't go to backend 
        #return(lookup); # @see vcl_hit
    }

    if (req.request != "GET" &&
       req.request != "HEAD" &&
       req.request != "PUT" &&
       req.request != "POST" &&
       req.request != "TRACE" &&
       req.request != "OPTIONS" &&
       req.request != "DELETE") {
         /* Non-RFC2616 or CONNECT which is weird. */
         return (pipe);
    }

     # Cache only GET or HEAD requests
     if (req.request != "GET" && req.request != "HEAD") {
         /* We only deal with GET and HEAD by default */
         return (pass);
     }

    # parse accept encoding rulesets to normalize
    if (req.http.Accept-Encoding) {
        if (req.http.Accept-Encoding ~ "gzip") {
            set req.http.Accept-Encoding = "gzip";
        } elsif (req.http.Accept-Encoding ~ "deflate") {
            set req.http.Accept-Encoding = "deflate";
        } else {
            # unkown algorithm
            remove req.http.Accept-Encoding;
        }
    }

     # Rules for static files
     if (req.url ~ "\.(jpeg|jpg|png|gif|ico|swf|js|css|gz|rar|txt|bzip|pdf)(\?.*|)$") {
        set req.http.staticmarker = "1";
        unset req.http.Cookie;

        return (lookup);
    }

    # Don't cache pages for Magento Admin
    # FIXME: change this rule if you use custom url in admin
    if (req.url ~ "^/(index.php/)?admin") {
        return(pass);
    }

    # Don't cache checkout/customer pages, product compare
  #  if (req.url ~ "^/(index.php/)?(checkout|customer|catalog/product_compare|wishlist)") {
  #      return(pass);
  #  }
    # Don't cache checkout/customer pages, product compare
    if (req.url ~ "/(checkout|customer|catalog/product_compare|wishlist)/") {
        return(pass);
    }


    # Don't cache till session end
    if (req.http.cookie ~ "nocache_stable") {
        return(pass);
    }

    # Unique identifier witch tell Varnish use cache or not
    if (req.http.cookie ~ "nocache") {
        return(pass);
    }

    # Remove cookie 
    unset req.http.Cookie;
    set req.http.magicmarker = "1"; #Instruct varnish to remove cache headers received from backend
    return(lookup);
 }


sub vcl_pipe {
#     # Note that only the first request to the backend will have
#     # X-Forwarded-For set.  If you use X-Forwarded-For and want to
#     # have it set for all requests, make sure to have:
#     # set req.http.connection = "close";
#     # here.  It is not set by default as it might break some broken web
#     # applications, like IIS with NTLM authentication.
     return (pipe);
}

#sub vcl_pass {
#     return (pass);
#}

#sub vcl_hash {
#     set req.hash += req.url;
#     if (req.http.host) {
#         set req.hash += req.http.host;
#     } else {
#         set req.hash += server.ip;
#     }
#     return (hash);
# }


# Called after a cache lookup if the req. document was found in the cache.
sub vcl_hit {
    if (req.request == "PURGE") {
        ban_url(req.url);
        error 200 "Purged";
    }

    #
    # ATTENTION!! I had to comment this to make it work on vernish 3.0!!!!
    # error message:
    # Symbol not found: 'obj.cacheable' (expected type BOOL):
    #
    # I'm not sure about it, please check!!!
    #
    #if (!obj.cacheable) {
    #    return (pass);
    #}


    return (deliver);
}

# Called after a cache lookup and odc was not found in cache.
sub vcl_miss {
    if (req.request == "PURGE"){
        error 200 "Not in cache";
    }
    return (fetch);
}

# Called after document was retreived from backend
# @var req      Request object.
# @var beresp   Backend response (contains HTTP headers from backend)
sub vcl_fetch {
    set req.grace = 30s;

    # Current response should not be cached
    if(beresp.http.Set-Cookie ~ "nocache=1") {
        return (deliver);
    }

    # Flag set when we want to delete cache headers received from backend
    if (req.http.magicmarker){
        unset beresp.http.magicmarker;
        unset beresp.http.Cache-Control;
        unset beresp.http.Expires;
        unset beresp.http.Pragma;
        unset beresp.http.Cache;
        unset beresp.http.Server;
        unset beresp.http.Set-Cookie;
        unset beresp.http.Age;

        # default ttl for pages
        set beresp.ttl = 1d;
    }
    if (req.http.staticmarker) {
        set beresp.ttl = 30d; # static file cache expires in 30 days
        unset beresp.http.staticmarker;
        unset beresp.http.ETag; # Removes Etag in case we have multiple frontends
    }

    return (deliver);
}

# Called after a cached document is delivered to the client.
sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT ("+obj.hits+")";
    } else {
        set resp.http.X-Cache = "MISS";
        #    set resp.http.X-Cache-Hash = obj.http.hash;
    }
    return (deliver);
}
# 
# sub vcl_error {
#     set obj.http.Content-Type = "text/html; charset=utf-8";
#     synthetic {"
# <?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>"} obj.status " " obj.response {"</title>
#   </head>
#   <body>
#     <h1>Error "} obj.status " " obj.response {"</h1>
#     <p>"} obj.response {"</p>
#     <h3>Guru Meditation:</h3>
#     <p>XID: "} req.xid {"</p>
#     <hr>
#     <address>
#        <a href="http://www.varnish-cache.org/">Varnish cache server</a>
#     </address>
#   </body>
# </html>
# "};
#     return (deliver);
# }
于 2013-01-10T23:37:41.160 回答
3

我假设这是 Magento 发送给所有用户的会话 cookie - 我在 Varnish + Redmine 上遇到了类似的问题。

Varnish 不缓存你的页面的原因是因为默认情况下它只缓存它确定是安全的 - 使用 cookie 的用户通常会看到给定页面加载的不同内容,例如,如果他们已登录,那么他们的用户名可能是每个页面的顶部,因此该页面无法被缓存†。

然而,许多框架也将会话 cookie 提供给未登录的用户。恐怕我根本不了解 Magento,所以我无法预测忽略此 cookie 的后果 - 在 Redmine 上,忽略 cookie 意味着用户无法登录,并且所有表单都停止工作(因为他们不再拥有 CSRF令牌)。

如果可以的话,从 Magento 方面解决这个问题可能会更好 - Varnish 将监听上游的标头以确定可以缓存的内容等。

如果你不能,那么你也许可以从 Varnish 的配置中减轻它。您需要确保 Set-Cookie 标头不是从任何缓存命中发送的,并且您还需要在请求该 cookie 无效的页面时删除客户端的 cookie 。这意味着您将需要例外情况,例如登录屏幕或任何需要您登录的页面(除非 Magento 在您登录后设置单独的 cookie,这会使事情变得容易得多)。

Varnish 文档(我强烈推荐作为资源)有几页关于提高命中率的内容,包括一个专门用于在某些页面而不是其他页面上放置 cookie 的页面

† 有一个例外,即如果您使用edge side includes

于 2011-05-20T08:25:02.087 回答
0

我认为这解释了我们如何避免在 magento 中使用清漆

如果您使用 aoe_static 模块和我为 varnish 3 定制的 vcl,它会清除缓存页面响应中的 cookie。它应该在 vcl fetch 中执行此操作。然后可以从加载动态内容的较小的 ajax 响应中设置 cookie。这会维护您的会话、购物车等。此 ajax 响应可以在 vcl 恢复中“管道”化。

我没有遇到任何问题,但没有在生产站点上尝试过。

动态块必须通过布局 xml 替换为占位符。如果您喜欢这些替代品,则可能是清漆边缘包含或自定义 ajax 实现。

当从 aoe_static 加载动态内容(或者你喜欢的任何类型的 ajax 方法)时,记住你仍然可以使用 magentos 布局系统是很好的,例如,为你的 ajax 调用创建一个句柄,其中包含要渲染的嵌套块。

如果您使用 aoe_static 模块,您会注意到调用了 loadLayout,但请记住传递给该 loadLayout 的句柄。它与您所在页面的布局请求不同,但它确实为您提供了默认句柄。

另一个问题是库存水平。当产品不再有足够的库存添加到购物车时,它仍会出现在产品列表中,并作为可配置和分组产品的选项。

可能您可以使用观察者 - cataloginventory_stock_item_save_after - 检查库存水平(我没有检查过这个)。然后可以根据产品的 url 清除缓存。获取产品将出现的类别 URL 并同时清除这些 URL 非常容易。

如果您想从观察者那里看到一个简单的实现,phoenix 模块有方法可以执行这些清除操作。

但是如何处理分层的导航 url 更加棘手。您需要预先存储应用程序使用基本类别列表 url 作为键提供的查询字符串参数,然后在观察者中读取并清除这些 url。这种查询字符串参数的存储在发送之前使用响应非常容易,使用正则表达式检查请求对象并使用逗号分隔记录查询字符串。

我认为当前的模块都没有处理分层导航的库存水平是错误的?

我认为开源社区需要一个好的完成的清漆模块,因为所有其他模块都缺乏。就我个人而言,我计划仅将付费整页缓存与负载平衡服务器一起使用,并且可能使用清漆来捕获图像和 css 请求。除非有人想联合起来进行适当的 varnish 实施,或者如果可以将工作添加到更好地处理所有这些问题的开源实施中,我很乐意为您的网站提供帮助。

结帐此问题以获取有关您将面临此问题的问题的更多详细信息-magento 开源整页缓存

于 2012-10-28T09:40:57.843 回答
0

我们开发了一个名为 PageCache 的模块,由 Varnish 提供支持,通过提供经过良好测试的 Varnish 配置文件 (VCL) 和一个紧密集成的 Magento 模块,该模块具有大量选项来控制来自 Magento 后端的 Varnish rigth,从而使 Magento 和 Varnish 能够顺畅地一起运行。在 Magento Connect 上查看:

http://www.magentocommerce.com/magento-connect/Phoenix/extension/6322/varnish_cache

于 2011-05-13T21:42:54.417 回答
-1

http://moprea.ro/2011/feb/16/magento-performance-optimization-varnish-cache-2/

不确定它是否有帮助,但我偶然发现了这一点。

实际上,我以前曾尝试过让清漆起作用,但失败了。我建议您在尝试 varnish 之前获得 APC + Memcached + tmpfs 会话/缓存。

于 2011-02-20T12:45:40.990 回答