Varnish在企業中的應用

在前一篇博文中,我們主要介紹了Varnish的原理,本篇博文主要介紹Varnish的配置及管理...

一、Varnish的安裝、命令使用及配置文件介紹

二、以案例方式介紹如何配置Varnish

三、服務驗證


一、Varnish的安裝、命令使用及配置文件介紹

1、配置YUM源,使用yum安裝Varnish

# rpm --nosignature -i http://repo.varnish-cache.org/redhat/varnish-3.0/el5/noarch/varnish-release-3.0-1.el5.centos.noarch.rpm
# yum -y install varnish

2、查看Varnish生成的文件

# rpm -ql varnish
/etc/rc.d/init.d/varnish        #Varnish服務啓動腳本
/etc/rc.d/init.d/varnishlog     #Varnish日誌服務啓動腳本
/etc/rc.d/init.d/varnishncsa    #Varnish日誌服務啓動腳本
/etc/sysconfig/varnish          #Varnish啓動服務的主配置文件
/etc/varnish                    #配置文件目錄
/etc/varnish/default.vcl        #默認VCL文件
/usr/bin/varnish_reload_vcl     #Varnish的VCL管理工具
/usr/bin/varnishadm             #Varnish管理工具
/usr/bin/varnishhist
/usr/bin/varnishlog             #Varnish日誌管理工具
/usr/bin/varnishncsa            #Varnish日誌管理工具
/usr/bin/varnishreplay
/usr/bin/varnishsizes
/usr/bin/varnishstat            #Varnish狀態查看工具
/usr/bin/varnishtest
/usr/bin/varnishtop

3、Varnish服務配置文件介紹

NFILES=131072             
MEMLOCK=82000
NPROCS="unlimited"
# DAEMON_COREFILE_LIMIT="unlimited"        #內核最大打開的文件數
RELOAD_VCL=1                               #是否自動加載VCL
VARNISH_VCL_CONF=/etc/varnish/default.vcl  #默認加載的VCL文件
VARNISH_LISTEN_PORT=80                     #監聽端口,默認爲6081
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1     #管理的IP地址
VARNISH_ADMIN_LISTEN_PORT=6082             #管理端口
VARNISH_SECRET_FILE=/etc/varnish/secret    #密鑰文件
VARNISH_MIN_THREADS=50                     #最小線程數量
VARNISH_MAX_THREADS=1000                   #最大線程數量
VARNISH_THREAD_TIMEOUT=120                 #線程超時時間
VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin #緩存文件位置 
VARNISH_STORAGE_SIZE=1G                    #設置文件緩存大小變量
VARNISH_MEMORY_SIZE=64M                    #設置內存緩存大小變量
#VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" #默認存儲到文件中,這裏可以修改存儲位置
VARNISH_STORAGE="malloc,${VARNISH_MEMORY_SIZE}" #設置緩存位置爲內存
VARNISH_TTL=120                 
DAEMON_OPTS="-a ${VARNISH_LISTEN_ADDRESS}:${VARNISH_LISTEN_PORT} \
             -f ${VARNISH_VCL_CONF} \
             -T ${VARNISH_ADMIN_LISTEN_ADDRESS}:${VARNISH_ADMIN_LISTEN_PORT} \
             -t ${VARNISH_TTL} \
             -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \
             -u varnish -g varnish \
             -S ${VARNISH_SECRET_FILE} \
             -s ${VARNISH_STORAGE}"    #所有啓動加載選項

4、啓動Varnish

[root@varnish ~]# service varnish start
[root@varnish ~]# netstat -anput|grep varnish
tcp        0      0 0.0.0.0:80                  0.0.0.0:*                   LISTEN      20303/varnishd
tcp        0      0 127.0.0.1:6082              0.0.0.0:*                   LISTEN      20301/varnishd
tcp        0      0 :::80                       :::*                        LISTEN      20303/varnishd

5、Varnishd命令介紹

# varnishd -h
-a address:port        #表示varnish對httpd的監聽地址及其端口
-b address:port        #表示後端服務器地址及其端口
-d                     #表示使用debug調試模式
-f file                #指定varnish服務器的配置文件
-p param=value         #指定服務器參數,用來優化varnish性能
-P file                #Varnish進程PID文件存放路徑
-n dir                 #指定varnish的工作目錄
-s kind[,storageoptions] #指定varnish緩存內容的存放方式,常用的方式有:“-s file,<dir_or_file>,<size>”;其中“<dir_or_file>”指定緩存文件的存放路徑,“<size>”指定緩存文件的大小
-t                     #指定默認的TTL值
-T address:port        #設定varnish的telnet管理地址及其端口
-V                     #顯示varnish版本號和版權信息
-w int[,int[,int]]     #設定varnish的工作線程數,常用的方式有:  -w min,max
 -w min,max,timeout
如:-w3,25600,50       #這裏最小啓動的線程數不能設定過大,設置過大,會導致varnish運行異常緩慢

6、Varnishadm命令使用介紹

# varnishadm -h
varnishadm: invalid option -- 'h'
usage: varnishadm [-n ident] [-t timeout] [-S secretfile] -T [address]:port command [...]
    -n is mutually exlusive with -S and -T
註釋:常用選項 -S:指定密鑰文件 -T:指定服務器地址與端口;如管理一個Varnish服務器,連接到Varnish服務器:
# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
varnish> help
help [command]
ping [timestamp]
auth response
quit      #退出
banner
status    #查看狀態
start     #啓動Varnish
stop      #關閉Varnish
vcl.load <configname> <filename>            #加載一個VCL文件
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname>                        #使用VCL文件
vcl.discard <configname>
vcl.list                                    #查看VCL文件列表
vcl.show <configname>                       #查看VCL文件配置
param.show [-l] [<param>]
param.set <param> <value>
panic.show
panic.clear
storage.list
backend.list
backend.set_health matcher state
ban.url <regexp>
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


二、以案例方式介紹如何配置Varnish

A、環境介紹

175919171.gif

架構簡單描述:安裝一個論壇程序,在Varnish服務器上做動靜分離,將動態頁面的請求都轉發到"lamp"服務器組,"lamp"服務器組的數據庫安裝在"lamp1"服務器上面;將靜態頁面轉發到"web"服務器組,對請求的靜態內容做緩存

------------------------------------------------------------------------------------------------

B、安裝lamp服務器並架設好論壇 更多詳細安裝請看前面博客...

1、在lamp1與lamp2服務器上安裝服務並測試

######在Lamp1服務器上安裝Httpd、Php、Mysql,啓動服務
[root@lamp1 ~]# yum -y install httpd php mysql-server php-mysql
[root@lamp1 ~]# service httpd start
[root@lamp1 ~]# service mysqld start
------------------------------------------------------------------------
######在Lamp2服務器上安裝Httpd、Php,啓動服務
[root@lamp2 ~]# yum -y install httpd php php-mysql
[root@lamp2 ~]# service httpd start

2、在Lamp1與Lamp2服務器創建php測試頁面並訪問驗證,做法相同,這裏只介紹一次

[root@lamp1 ~]# echo "<?php phpinfo();" > /var/www/html/index.php

181642963.gif

3、安裝論壇程序 點此下載

[root@lamp1 ~]# mysql
mysql> create database bbs;
mysql> grant all on bbs.* to 'bbsuser'@'172.16.%.%' identified by 'bbspass';
mysql> flush privileges;
註釋:爲論壇創建一個數據庫並授權用戶訪問
------------------------------------------------------------------------
######安裝論壇程序
[root@lamp1 ~]# unzip Discuz_X3.0_SC_UTF8.zip
[root@lamp1 ~]# cp -rf upload/* /var/www/html/
[root@lamp1 ~]# chmod -R +w /var/www/html/{config,data,uc_server,uc_client}    #添加可寫權限
[root@lamp1 ~]# chown -R apache /var/www/html/*      #修改屬主權限

4、訪問"lamp1"服務器地址安裝論壇

183804237.gif

5、點擊我同意-->下一步-->(全新安裝 Discuz! X)下一步-->安裝數據庫界面

184031143.gif

6、下一步-->安裝完成-->訪問主頁並登錄測試

184318367.gif

7、將論壇程序拷貝到lamp2服務器上一份並訪問測試

[root@lamp1 ~]# scp -rp /var/www/html/* 172.16.14.3:/var/www/html/
[root@lamp2 ~]# service httpd restart    #重啓lamp2服務器的WEB服務

184654360.gif

------------------------------------------------------------------------------------------------

C、安裝web服務器並創建測試頁訪問

[root@web ~]# yum -y install httpd
[root@web ~]# service httpd start
[root@web ~]# echo "<h1>WEB</h1>" > /var/www/html/index.html #創建測試頁

195408619.gif

將Lamp1服務器上的論壇程序拷貝到WEB服務器一份,因爲需要論壇中的一些靜態文件如:(.jpg|.html)結尾的文件等

[root@lamp1 ~]# scp -rp /var/www/html/* 172.16.14.3:/var/www/html/


D、Varnish安裝及配置,這裏不再介紹如何安裝,在第一部分已經介紹瞭如何安裝

1、在第一部分中我們已經修改過默認監聽端口爲"80",接下來爲Varnish提供一個VCL配置文件,建議基於默認的配置文件基礎上修改,修改前備份一下文件

[root@varnish ~]# cd /etc/varnish/
[root@varnish varnish]# cp default.vcl default.vcl.bak
[root@varnish varnish]# vim default.vcl
######定義ACL
acl purgers {                    #定義acl,實現IP地址過濾
    "127.0.0.1";
    "172.16.0.0"/16;
}
######定義健康狀態檢測
probe dynamic {                  #設置動態網站服務器健康狀態檢測
    .url = "/index.html";
    .interval = 5s;
    .timeout = 1s;
    .expected_response = 200;
}            #這裏設置了兩個健康狀態檢測主要是爲了區分動、靜網站
probe static {                   #設置動態網站服務器健康狀態檢測
    .url = "/index.html";        #定義檢測的頁面
    .interval = 5s;              #探測請求的發送週期,默認爲5秒
    .timeout = 1s;               #每次探測請求的過期時間
    .expected_response = 200;
}
######定義後端服務器
backend app1 {                  #定義一個後端服務器
    .host = "172.16.14.2";      #服務器地址
    .port = "80";               #服務器監聽端口
    .probe = dynamic;           #健康狀態檢測
}
backend app2 {
    .host = "172.16.14.3";
    .port = "80";
    .probe = dynamic;
}
backend web {           
    .host = "172.16.14.4";
    .port = "80";
    .probe = static;
}
######定義後端服務器組,實現負載均衡效果
director apps random {          #定義一個後端服務器組,實現負載均衡效果
    {
         .backend = app1;       #調用前面已定義過的後端主機
     .weight = 2;           #設置權重
    }
    {
     .backend = app2;
     .weight = 2;
    }
}
######定義vcl_recv函數,實現請求到達併成功接收後調用此函數中定義的規則
sub vcl_recv {
######定義動、靜分離,以".php"或".php?後面跟所有文件"結尾的請求都發送到動態服務器,其他請求都發送到靜態服務器
    if (req.url ~ "\.php(\?\.*|$)") {
    set req.backend = apps;
    } else {
    set req.backend = web;
    }
    return(lookup);
######定義允許清除緩存的IP地址,調用的是前面定義的ACL
    if (req.request == "PURGE") {
        if (!client.ip ~ purgers) {
        error 405 "Method not allowed";
    }
        return(lookup);
    }
######重新定義http請求首部,讓後端服務器可以記錄請求客戶端的真實IP地址
        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;
            }
         }
######除了定義的請求方法外,其他請求都到後端服務器
    if (req.request != "GET" &&
        req.request != "HEAD" &&
        req.request != "PUT" &&
        req.request != "POST" &&
        req.request != "TRACE" &&
        req.request != "OPTIONS" &&
        req.request != "DELETE") {
        return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        return (pass);
    }
######定義不緩存認證與Cookie信息
    if (req.http.Authorization || req.http.Cookie) {
        return (pass);
    }
######定義壓縮功能
    if (req.http.Accept-Enconding) {
       if (req.url ~ "\.(jpg|jpeg|gif|bmp|png|flv|gz|tgz|tbz|mp3)$") {
           remove req.http.Accept-Encoding;
       remove req.http.Cookie;
       } else if (req.http.Accept-Encoding ~ "gzip") {
       set req.http.Accept-Encoding = "gzip";
       } else if (req.http.Accept-Encoding ~ "deflate") {
       set req.http.Accept-Encoding = "deflate";
       } else { remove req.http.Accept-Encoding;
       }
    }
######定義指定格式結尾的文件去除Cookie信息
    if (req.request == "GET" && req.url ~ "\.(jpeg|jpg|gif|png|bmp|swf)$") {
    unset req.http.cookie;
    }
######定義防盜鏈設置
    if (req.http.referer ~ "http://.*") {
        if (!(req.http.referer ~ "http://.*\.baidu\.com" || req.http.referer ~ "http://.*\.google\.com.*")) {
              set req.http.host = "www.allen.com";
          set req.url = "http://172.16.14.4/error.html";
    }
    }
}
######定義vcl_hash函數
sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return(hash);
}
######定義vcl_hit函數
sub vcl_hit {
    if (req.request == "PURGE") { #語法方法爲"PURGE"
       purge;                     #清除緩存
       error 200 "Purged.";       #返回錯誤狀態碼爲"200"
    }
    return(deliver);
}
######定義vcl_miss函數
sub vcl_miss {
    if (req.request == "PURGE") {
    purge;
    error 404 "Not In Cache.";
    }
    return(fetch);
}
######定義vcl_psss函數
sub vcl_pass {
    if (req.request == "PURGE") {
       error 502 "Purged On A Passed Object.";
    }
    return(pass);
}
######定義vcl_fetch函數
sub vcl_fetch {
######定義緩存,如果匹配到已定義文件結尾的緩存1天,其他則緩存1小時
    if (req.request == "GET" && req.url ~ "\.(html|jpg|png|bmp|jpeg|gif|js|ico|swf|css)$") {
       set beresp.ttl = 1d;
       set beresp.http.expires = beresp.ttl;
    } else {
       set beresp.ttl = 1h;
    }
    return(deliver);
}
######定義在http首部中,如果請求命中顯示"HIT",未命中則顯示"MISS"
sub vcl_deliver {
    if (obj.hits > 0) {
       set resp.http.X-Cache = "HIT";
    } else {
       set resp.http.X-Cache = "MISS";
    }
}
----------------------------------------------------------------------
[root@varnish ~]# service varnish restart    #重啓服務生效,重啓服務器後所有緩存將被清除,當然也可以不用重啓服務使其生效,如下:
----------------------------------------------------------------------
[root@varnish ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
varnish> help                        #獲取幫助
varnish> vcl.load acl_1 default.vcl  #加載acl文件,acl_1爲配置名稱
200    
VCL compiled.
varnish> vcl.list                    #查看加載的acl文件列表
200    
active          7 boot
available       0 acl_1
varnish> vcl.use acl_1               #應用acl文件
200
varnish> quit                        #退出
------------------------------------------------------------------------
註釋:  -S:指定varnish的密鑰文件  -T:指定varnish服務器地址及管理端口,默認端口爲"6082"

2、如果要想讓後端服務器記錄客戶端的真實IP地址需要修改Apache記錄日誌格式,如下:

LogFormat "%{X-Forwarded-For}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


三、服務驗證

1、對服務器做壓力測試,如下:

######後端服務器不經過緩存測試
[root@localhost ~]# ab -c 100 -n 1000 http://172.16.14.2/index.php
Concurrency Level:      1000
Time taken for tests:   6.812 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Non-2xx responses:      10051
Total transferred:      2281577 bytes
HTML transferred:       0 bytes
Requests per second:    1468.04 [#/sec] (mean)  #每秒請求併發
Time per request:       681.179 [ms] (mean)
Time per request:       0.681 [ms] (mean, across all concurrent requests)
Transfer rate:          327.10 [Kbytes/sec] received
----------------------------------------------------------------------
######經過緩存測試
[root@localhost ~]# ab -c 1000 -n 10000 http://172.16.14.1/index.php
Concurrency Level:      1000
Time taken for tests:   2.594 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Non-2xx responses:      10056
Total transferred:      3117360 bytes
HTML transferred:       0 bytes
Requests per second:    3855.05 [#/sec] (mean)
Time per request:       259.400 [ms] (mean)
Time per request:       0.259 [ms] (mean, across all concurrent requests)
Transfer rate:          1173.59 [Kbytes/sec] received
----------------------------------------------------------------------
註釋:從上面數據中可以看出,經過緩存做壓力測試併發量高

2、測試緩存是否能命中

[root@lamp2 ~]# curl -I http://172.16.14.1/index.php
HTTP/1.1 301 Moved Permanently
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
location: forum.php
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Accept-Ranges: bytes
Date: Wed, 09 Oct 2013 01:09:01 GMT
X-Varnish: 2142028839
Age: 0
Via: 1.1 varnish
Connection: keep-alive
X-Cache: MISS    #第一次請求,未命中顯示"MISS"
------------------------------------------------------------------------
[root@lamp2 ~]# curl -I http://172.16.14.1/index.php
HTTP/1.1 301 Moved Permanently
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
location: forum.php
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Accept-Ranges: bytes
Date: Wed, 09 Oct 2013 01:09:08 GMT
X-Varnish: 2142028841 2142028839
Age: 7
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT    #第二次請求,命中則顯示"HIT"

3、驗證動、靜分離的效果

[root@web ~]# service httpd stop    #停止提供靜態頁面的httpd服務
Stopping httpd:                                            [  OK  ]

093626794.gif註釋:從上圖中可以看出,提供靜態頁面的服務停止後,所有圖片都不能顯示,當然把服務再啓動起來就可以訪問正常了,這裏就不在測試了...

4、驗證健康狀態檢測

095950691.gif

5、查看緩存命中率狀態;命中率的高低

095319814.gif

6、驗證手動清除緩存

[root@lamp2 ~]# curl -X PURGE http://172.16.14.1/index.php
<?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>200 Purged.</title>
  </head>
  <body>
    <h1>Error 200 Purged.</h1>
    <p>Purged.</p>
    <h3>Guru Meditation:</h3>
    <p>XID: 580728625</p>
    <hr>
    <p>Varnish cache server</p>
  </body>
</html>                #註釋:已經成功清除緩存
----------------------------------------------------------------------
[root@lamp2 ~]# curl -I http://172.16.14.1/index.php
HTTP/1.1 301 Moved Permanently
Server: Apache/2.2.15 (CentOS)
X-Powered-By: PHP/5.3.3
location: forum.php
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Accept-Ranges: bytes
Date: Wed, 09 Oct 2013 02:03:03 GMT
X-Varnish: 580728626
Age: 0
Via: 1.1 varnish
Connection: keep-alive
X-Cache: MISS
註釋:由於上面清除了緩存,這裏第一次請求爲"MISS"

到此,Varnish的配置及驗證已全部完成,更多的驗證這裏就不在做了,如果各位博友有興趣可以多做一些測試;如有疑問請留言,更多內容請繼續關注後續更新...



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章