目次
Error "} + obj.status + " " + obj.response + {"
Guru Meditation:
ホームページ php教程 php手册 Drupal7配合Varnish使用及整合drupal模块的详细教程

Drupal7配合Varnish使用及整合drupal模块的详细教程

May 26, 2016 am 08:20 AM
request select

Varnish是一款高性能的开源HTTP加速器,使用相对复杂,尤其跟drupal配合使用。现在我们来记录关于Drupal7配合Varnish使用的详细设置教程

准备环境

首先安装一个全新的Drupal,推荐使用drush安装,方便迅速。

先要建一个数据库,记住用户和密码。

###进入mysql
mysql -uroot -p
CREATE DATABASE `mydb` CHARACTER SET utf8 COLLATE utf8_general_ci;
GRANT ALL ON `mydb`.* TO `username`@localhost IDENTIFIED BY 'password';
####退出mysql

Drush安装Drupal7:

drush dl drupal-7.x; #--select 用来选择一个版本
drush site-install standard --account-name=admin --account-pass=admin --db-url=mysql://YourMySQLUser:RandomPassword@localhost/YourMySQLDatabase

默认会安装最新版本的drupal7,如果要选择一个版本,请加参数:–select。

安装成功后,再下载一个varnish模块。

#进入drupal目录
drush dl varnish

安装Varnish

我们默认一个CentOS为例,因为CentOS仓库中的Varnish版本较低,要导入一个新的repo,然后,在升级一下yum软件库。
具体参考这个链接:https://www.varnish-cache.org/installation/redhat

####Varnish 4.0:
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm
yum install varnish
 
####Varnish 3.0:
 
###RHEL 5 or a compatible distribution, use:
 
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-3.0.el5.rpm
yum install varnish
 
###RHEL 6 and compatible distributions, use:
 
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-3.0.el6.rpm
yum install varnish
ログイン後にコピー


#如果安装的版本不对,请update一下。
#yum update

输入如下命令监测是否安装成功:

$ usr/sbin/varnishd -V
varnishd (varnish-3.0.5 revision 1a89b1f)
Copyright (c) 2006 Verdens Gang AS
Copyright (c) 2006-2011 Varnish Software AS

设置Varnish的VCL

复制如下代码到/etc/varnish/default.vcl里面:

backend default {
  .host = "127.0.0.1";
  .port = "80";
}
 
sub vcl_recv {
  if (req.restarts == 0) {
    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;
    }
  }
 
  # Do not cache these paths.
  if (req.url ~ "^/status.php$" ||
    req.url ~ "^/update.php$" ||
    req.url ~ "^/ooyala/ping$" ||
    req.url ~ "^/admin/build/features" ||
    req.url ~ "^/info/.$" ||
    req.url ~ "^/flag/.$" ||
    req.url ~ "^./ajax/.$" ||
    req.url ~ "^./ahah/.$") {
    return (pass);
  }
 
  # Pipe these paths directly to Apache for streaming.
  if (req.url ~ "^/admin/content/backup_migrate/export") {
    return (pipe);
  }
 
  # Allow the backend to serve up stale content if it is responding slowly.
  set req.grace = 6h;
 
  # Use anonymous, cached pages if all backends are down.
  if (!req.backend.healthy) {
    unset req.http.Cookie;
  }
 
  # Always cache the following file types for all users.
  if (req.url ~ "(?i).(png|gif|jpeg|jpg|ico|swf|css|js|html|htm)(?[wd=.-]+)?$") {
    unset req.http.Cookie;
  }
 
  # Remove all cookies that Drupal doesn't need to know about. ANY remaining
  # cookie will cause the request to pass-through to Apache. For the most part
  # we always set the NO_CACHE cookie after any POST request, disabling the
  # Varnish cache temporarily. The session cookie allows all authenticated users
  # to pass through as long as they're logged in.
  if (req.http.Cookie) {
    set req.http.Cookie = ";" +  req.http.Cookie;
    set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
    set req.http.Cookie = regsuball(req.http.Cookie, ";(SESS[a-z0-9]+|NO_CACHE)=", "; 1=");
    set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
    set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");
 
    # Remove the "has_js" cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "has_js=[^;]+(; )?", "");
    # Remove the "Drupal.toolbar.collapsed" cookie
    set req.http.Cookie = regsuball(req.http.Cookie, "Drupal.toolbar.collapsed=[^;]+(; )?", "");
    # Remove AdminToolbar cookie for drupal6
    set req.http.Cookie = regsuball(req.http.Cookie, "DrupalAdminToolbar=[^;]+(; )?", "");
    # Remove any Google Analytics based cookies
    set req.http.Cookie = regsuball(req.http.Cookie, "__utm.=[^;]+(; )?", "");
    # Remove the Quant Capital cookies (added by some plugin, all __qca)
    set req.http.Cookie = regsuball(req.http.Cookie, "__qc.=[^;]+(; )?", "");
 
     if (req.http.Cookie == "") {
      # If there are no remaining cookies, remove the cookie header. If there
      # aren't any cookie headers, Varnish's default behavior will be to cache
      # the page.
      unset req.http.Cookie;
      set req.http.X-Varnish-NoCookie = "TRUE";
    }
    else {
      # If there is any cookies left (a session or NO_CACHE cookie), do not
      # cache the page. Pass it on to Apache directly.
      set req.http.X-Varnish-NoCookie = "FALSE";
      set req.http.X-Varnish-CookieData = req.http.Cookie;
      return (pass);
    }
  }
 
  # Handle compression correctly. Different browsers send different
  # "Accept-Encoding" headers, even though they mostly all support the same
  # compression mechanisms. By consolidating these compression headers into
  # a consistent format, we can reduce the size of the cache and get more hits.
  # @see: http:// varnish.projects.linpro.no/wiki/FAQ/Compression
  if (req.http.Accept-Encoding) {
    if (req.http.Accept-Encoding ~ "gzip") {
      # If the browser supports it, we'll use gzip.
      set req.http.Accept-Encoding = "gzip";
    }
    else if (req.http.Accept-Encoding ~ "deflate") {
      # Next, try deflate if it is supported.
      set req.http.Accept-Encoding = "deflate";
    }
    else {
      # Unknown algorithm. Remove it and send unencoded.
      unset req.http.Accept-Encoding;
    }
  }
 
  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);
  }
  if (req.request != "GET" && req.request != "HEAD") {
      /* We only deal with GET and HEAD by default */
      return (pass);
  }
  ## Unset Authorization header if it has the correct details...
  #if (req.http.Authorization == "Basic <hash>") {
  #  unset req.http.Authorization;
  #}
  if (req.http.Authorization || req.http.Cookie) {
      /* Not cacheable by default */
      return (pass);
  }
 
  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 bereq.http.connection = "close";
    # here.  It is not set by default as it might break some broken web
    # applications, like IIS with NTLM authentication.
}
 
# Routine used to determine the cache key if storing/retrieving a cached page.
sub vcl_hash {
  if (req.http.X-Forwarded-Proto == "https") {
    hash_data(req.http.X-Forwarded-Proto);
  }
}
 
sub vcl_hit {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}
 
sub vcl_miss {
  if (req.request == "PURGE") {
    purge;
    error 200 "Purged.";
  }
}
 
# Code determining what to do when serving items from the Apache servers.
sub vcl_fetch {
  set beresp.http.X-Varnish-CookieData = beresp.http.set-cookie;
  # Don&#39;t allow static files to set cookies.
  if (req.url ~ "(?i).(png|gif|jpeg|jpg|ico|swf|css|js)(?[a-z0-9]+)?$") {
    # beresp == Back-end response from the web server.
    unset beresp.http.set-cookie;
  }
  else if (beresp.http.Cache-Control) {
    unset beresp.http.Expires;
  }
 
  if (beresp.status == 301) {
    set beresp.ttl = 1h;
    return(deliver);
  }
 
  ## Doesn&#39;t seem to work as expected
  #if (beresp.status == 500) {
  #  set beresp.saintmode = 10s;
  #  return(restart);
  #}
 
  # Allow items to be stale if needed.
  set beresp.grace = 1h;
}
 
# Set a header to track a cache HIT/MISS.
sub vcl_deliver {
  if (obj.hits > 0) {
    set resp.http.X-Varnish-Cache = "HIT";
  }
  else {
    set resp.http.X-Varnish-Cache = "MISS";
  }
}
 
# In the event of an error, show friendlier messages.
sub vcl_error {
     set obj.http.Content-Type = "text/html; charset=utf-8";
     set obj.http.Retry-After = "5";
     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 id="Error-nbsp-nbsp-nbsp-obj-status-nbsp-nbsp-nbsp-nbsp-nbsp-obj-response-nbsp-nbsp">Error "} + obj.status + " " + obj.response + {"</h1>
     <p>"} + obj.response + {"</p>
     <h3 id="Guru-nbsp-Meditation">Guru Meditation:</h3>
     <p>XID: "} + req.xid + {"</p>
     <hr>
     <p>Varnish cache server</p>
   </body>
</html>
"};
     return (deliver);
}
ログイン後にコピー


配置完成之后,启动Varnish。

测试效果

打开浏览器,输入druapl7的地址,先看Drupal7是否正常,然后加上端口号。
比如我们的测试地址是:http://drupal7.phprm.com
那么再用浏览器打开varnish的地址,如下:http://drupal7.phprm.com:6081/

测试结果,两边都正常就表示drupal和varnish都工作正常。
让Varnish缓存Drupal页面

用Firebug查看varnish的请求,如果看到http头里面有X-Varnish的标记表示varnish已经起作用,这时候我们要判断varnish是否缓存了页面。
如何判断:X-Varnish后面有一个数字,表示不是缓存,X-Varnish后面有两个数字,表示缓存成功。

到这里,我们会发现所有的varnish都没有缓存命中,那么问题来了。。。(挖掘机不会出现)
如何让varnish缓存起作用:

// Tell Drupal it&#39;s behind a proxy.
$conf[&#39;reverse_proxy&#39;] = TRUE;
 
// Tell Drupal what addresses the proxy server(s) use.
$conf[&#39;reverse_proxy_addresses&#39;] = array(&#39;127.0.0.1&#39;);
 
// Bypass Drupal bootstrap for anonymous users so that Drupal sets max-age < 0.
$conf[&#39;page_cache_invoke_hooks&#39;] = FALSE;
 
// Make sure that page cache is enabled.
$conf[&#39;cache&#39;] = 1;
$conf[&#39;cache_lifetime&#39;] = 0;
$conf[&#39;page_cache_maximum_age&#39;] = 21600;
ログイン後にコピー



给Drupal的settings.php添加如下内容,然后刷新浏览器,即可看到X-Varnish的数字变成了两个(多刷几次)。

至此,Varnish已经完全可以缓存Drupal的页面了。如下图所示:

Drupal X-varnish

那么,Drupal的Varnish模块是做什么用的?

简单来说,Varnish就是通过Drupal的缓存接口,清除varnish的缓存,比如页面过期。
此外,通过Expire模块,可以精确的控制那些页面,过期时间都可以控制,比较方便。

配置Drupal.org的Varnish模块

启用Varnish模块,阅读一下varnish模块的官方说明: https://www.drupal.org/project/varnish
主要是给Drupal的settings.php添加如下两行:

// Add Varnish as the page cache handler.
$conf['cache_backends'] = array('sites/all/modules/varnish/varnish.cache.inc');
$conf['cache_class_cache_page'] = 'VarnishCache';

然后到Drupal设置页面,路径如下: admin/config/development/varnish

例如:
Varnish Control Terminal: 127.0.0.1:6082
Varnish Control Key: 86b2d660-9768-4a13-ab90-4b0736d6a4d1
点击保存,status就会变为绿色。
(注意:Control Key的值在/etc/varnish/secret 文件里面,复制内容即可)

设置完成,那么清空一下Drupal的缓存,就会发现Varnish里面的缓存值就会刷新,实现了即时清空缓存的目的。

+++++到此完成++++++++(更多问题到drupal大学:http://drupal001.net提问哦!)+++++

哦哦,还有一种情况,就是Varnish安装再另外一台服务器上,因为Varnish控制后台默认监听的是本机,因此,如果要刷新另一台反向代理服务器的缓存,就必须修改配置。可选的方法有两个,

其一,让Varnish的管理后台地址使用内网的IP(比如192.168.1.x),一般这种架构都是内网集群,因此监听内网也是比较合理的。
其二,本机使用autossh,把本机的端口6082映射到内网机器上面。

$ autossh -fN  -L 6082:localhost:6082

完成

至此,Drupal7 + Varnish的配置已经完成,Drupal和varnish也完全集成。Varnish的缓存总得来说速度大于其他缓存,所以可以代替Boost缓存。
如果要使用Varnish缓存动态内容,还有更多的内容要做,本文就不再增加大家的阅读量了(^_^)。

+++++++++++++++++++++++

最后,顺便多嘴,说一下Apache的RPAF Module。

Varnish默认使用 X-Forwarded-For作为远程IP的地址信息,但是这个不是一个标准的协议,有时候我们还是用PHP里面的 $_SERVER['REMOTE_ADDR']来获得IP。
Apache有一个模块,RPAF的配置文件 rpaf.conf如下,即可获设置正确的IP地址。(具体安装就不多说)

RPAFenable On
RPAFsethostname  On
RPAFproxy_ips    127.0.0.1 192.168. 10.0.0.
RPAFheader       X-Forwarded-For


このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PHPリクエストとはどういう意味ですか? PHPリクエストとはどういう意味ですか? Jul 07, 2021 pm 01:49 PM

request の中国語の意味は「要求」で、PHP のグローバル変数であり、「$_POST」、「$_GET」、「$_COOKIE」を含む配列です。 「$_REQUEST」変数は、POSTまたはGETで送信されたデータやCOOKIE情報を取得できます。

PHP の Request オブジェクトとは何ですか? PHP の Request オブジェクトとは何ですか? Feb 27, 2024 pm 09:06 PM

PHP の Request オブジェクトは、クライアントからサーバーに送信される HTTP リクエストを処理するために使用されるオブジェクトです。 Request オブジェクトを通じて、リクエストを処理して応答するために、リクエスト メソッド、リクエスト ヘッダー情報、リクエスト パラメータなどのクライアントのリクエスト情報を取得できます。 PHP では、$_REQUEST、$_GET、$_POST などのグローバル変数を使用して、要求された情報を取得できますが、これらの変数はオブジェクトではなく配列です。リクエスト情報をより柔軟かつ便利に処理するために、次のことができます。

Select Channels Goの非同期処理方法 golangを使った並行プログラミング Select Channels Goの非同期処理方法 golangを使った並行プログラミング Sep 28, 2023 pm 05:27 PM

golang を使用した SelectChannelsGo 同時プログラミングの非同期処理方法 はじめに: 同時プログラミングは、アプリケーションのパフォーマンスと応答性を効果的に向上させることができる、現代のソフトウェア開発における重要な領域です。 Go 言語では、Channel と Select ステートメントを使用して同時プログラミングを簡単かつ効率的に実装できます。この記事では、SelectChannelsGo 同時プログラミングの非同期処理メソッドに golang を使用する方法を紹介し、具体的な方法を提供します。

urllib.request.urlopen() 関数を使用して Python 3.x で GET リクエストを送信する方法 urllib.request.urlopen() 関数を使用して Python 3.x で GET リクエストを送信する方法 Jul 30, 2023 am 11:28 AM

Python3.x で urllib.request.urlopen() 関数を使用して GET リクエストを送信する方法 ネットワーク プログラミングでは、HTTP リクエストを送信してリモート サーバーからデータを取得する必要があることがよくあります。 Python では、urllib モジュールの urllib.request.urlopen() 関数を使用して、HTTP リクエストを送信し、サーバーから返される応答を取得できます。この記事では使い方を紹介します

jqueryでselect要素を非表示にする方法 jqueryでselect要素を非表示にする方法 Aug 15, 2023 pm 01:56 PM

jquery で select 要素を非表示にする方法: 1. hide() メソッド。jQuery ライブラリを HTML ページに導入します。さまざまなセレクターを使用して select 要素を非表示にできます。ID セレクターは、selectId を選択した select 要素の ID に置き換えます。実際に使用する; 2. css() メソッド、ID セレクターを使用して非表示にする必要がある select 要素を選択し、css() メソッドを使用して表示属性を none に設定し、selectId を select 要素の ID に置き換えます。

PHPにおけるリクエストの役割と重要性 PHPにおけるリクエストの役割と重要性 Feb 27, 2024 pm 12:54 PM

PHP におけるリクエストの役割と重要性 PHP プログラミングにおけるリクエストは、Web サーバーにリクエストを送信するためのメカニズムであり、Web 開発において重要な役割を果たします。リクエストは主に、フォームの送信、GET または POST リクエストなど、クライアントから送信されたデータを取得するために使用されます。リクエストを通じて、ユーザーが入力したデータを取得し、データを処理して応答することができます。この記事では、PHPにおけるリクエストの役割と重要性を紹介し、具体的なコード例を示します。

jQueryで選択要素の変更イベントバインディングを実装する方法 jQueryで選択要素の変更イベントバインディングを実装する方法 Feb 23, 2024 pm 01:12 PM

jQuery は、DOM 操作、イベント処理、アニメーション効果などを簡素化するために使用できる人気のある JavaScript ライブラリです。 Web 開発では、選択した要素のイベント バインディングを変更する必要がある状況によく遭遇します。この記事では、jQuery を使用して選択要素変更イベントをバインドする方法を紹介し、具体的なコード例を示します。まず、ラベルを使用してオプションを含むドロップダウン メニューを作成する必要があります。

Vue3 Axios インターセプターをリクエスト ファイルにカプセル化する方法 Vue3 Axios インターセプターをリクエスト ファイルにカプセル化する方法 May 19, 2023 am 11:49 AM

1. request.js という名前の新しいファイルを作成し、Axios をインポートします: importaxiosfrom'axios'; 2. request という名前の関数を作成してエクスポートします: これにより、request という名前の関数が作成され、それがエクスポートされます ベース URL を使用して新しい Axios インスタンスを設定します。ラップされた Axios インスタンスにタイムアウト設定を追加するには、Axios インスタンスの作成時にタイムアウト オプションを渡すことができます。 exportconstrequest=axios.create({baseURL:'https://example.

See all articles