[转][笔记] 2.安装与配置 Varnish
转自陈sir的博客(可能有一定的修改):
http://freeloda.blog.51cto.com/2033581/1297414
目录:
- 七、安装与配置 Varnish
- 八、配置一个简单的Varnish实例
- 九、Varnish 检测后端主机的健康状态
- 十、Varnish 对应两台Web服务器的配置实例
- 十一、Varnish 对应多台Web服务器的配置实例
注,操作系统 CentOS 6.8 x86_64,软件版本 Varnish 4.0。
七、安装与配置 Varnish
1.实验拓扑
vm1.guli.com(192.168.0.71)
/
Varnish
(192.168.0.120)
\
lamp1.guli.com(192.168.0.171)
2. 安装 Varnish
yum install epel-release
rpm --nosignature -i https://repo.varnish-cache.org/redhat/varnish-4.0.el6.rpm
yum install varnish
3. 查看安装的文件
[root@vm_mac ~]# rpm -ql varnish
/etc/logrotate.d/varnish
/etc/rc.d/init.d/varnish
/etc/rc.d/init.d/varnishlog
/etc/rc.d/init.d/varnishncsa
/etc/sysconfig/varnish
/etc/varnish
/etc/varnish/default.vcl
/usr/bin/varnishadm
/usr/bin/varnishhist
/usr/bin/varnishlog
/usr/bin/varnishncsa
/usr/bin/varnishstat
/usr/bin/varnishtest
/usr/bin/varnishtop
/usr/sbin/varnish_reload_vcl
/usr/sbin/varnishd
/usr/share/doc/varnish
/usr/share/doc/varnish-4.0.3
/usr/share/doc/varnish-4.0.3/ChangeLog
/usr/share/doc/varnish-4.0.3/LICENSE
/usr/share/doc/varnish-4.0.3/README
/usr/share/doc/varnish-4.0.3/README.redhat
/usr/share/doc/varnish/builtin.vcl
/usr/share/doc/varnish/example.vcl
/usr/share/man/man1/varnishadm.1.gz
/usr/share/man/man1/varnishd.1.gz
/usr/share/man/man1/varnishhist.1.gz
/usr/share/man/man1/varnishlog.1.gz
/usr/share/man/man1/varnishncsa.1.gz
/usr/share/man/man1/varnishstat.1.gz
/usr/share/man/man1/varnishtest.1.gz
/usr/share/man/man1/varnishtop.1.gz
/usr/share/man/man3/vmod_directors.3.gz
/usr/share/man/man3/vmod_std.3.gz
/usr/share/man/man7/varnish-cli.7.gz
/usr/share/man/man7/varnish-counters.7.gz
/usr/share/man/man7/vcl.7.gz
/usr/share/man/man7/vsl-query.7.gz
/usr/share/man/man7/vsl.7.gz
/var/lib/varnish
/var/log/varnish
4.查看一下启动脚本的配置文件
[root@vm_mac ~]# cat /etc/sysconfig/varnish
# Configuration file for varnish
#
# /etc/init.d/varnish expects the variable $DAEMON_OPTS to be set from this
# shell script fragment.
#
# Maximum number of open files (for ulimit -n)
NFILES=131072 # 最大打开文件数
# Locked shared memory (for ulimit -l)
# Default log size is 82MB + header
MEMLOCK=82000 # 默认日志大小
# Maximum number of threads (for ulimit -u)
NPROCS="unlimited" # 最大线程数
# Maximum size of corefile (for ulimit -c). Default in Fedora is 0
# DAEMON_COREFILE_LIMIT="unlimited" # 最大内核打开的文件数
# Set this to 1 to make init script reload try to switch vcl without restart.
# To make this work, you need to set the following variables
# explicit: VARNISH_VCL_CONF, VARNISH_ADMIN_LISTEN_ADDRESS,
# VARNISH_ADMIN_LISTEN_PORT, VARNISH_SECRET_FILE, or in short,
# use Alternative 3, Advanced configuration, below
RELOAD_VCL=1 # 是否自动加载 VCL
# This file contains 4 alternatives, please use only one.
## Alternative 1, Minimal configuration, no VCL # 方案1,最小配置,不方便
#
# Listen on port 6081, administration on localhost:6082, and forward to
# content server on localhost:8080. Use a fixed-size cache file.
#
#DAEMON_OPTS="-a :6081 \
# -T localhost:6082 \
# -b localhost:8080 \
# -u varnish -g varnish \
# -s file,/var/lib/varnish/varnish_storage.bin,1G"
## Alternative 2, Configuration with VCL # 方案2,配置组件
#
# Listen on port 6081, administration on localhost:6082, and forward to
# one content server selected by the vcl file, based on the request. Use a
# fixed-size cache file.
#
#DAEMON_OPTS="-a :6081 \
# -T localhost:6082 \
# -f /etc/varnish/default.vcl \
# -u varnish -g varnish \
# -S /etc/varnish/secret \
# -s file,/var/lib/varnish/varnish_storage.bin,1G"
## Alternative 3, Advanced configuration # 方案3,高级配置
#
# See varnishd(1) for more information.
#
# # Main configuration file. You probably want to change it :)
VARNISH_VCL_CONF=/etc/varnish/default.vcl # 默认的VCL存放位置
#
# # Default address and port to bind to
# # Blank address means all IPv4 and IPv6 interfaces, otherwise specify
# # a host name, an IPv4 dotted quad, or an IPv6 address in brackets.
# VARNISH_LISTEN_ADDRESS=
VARNISH_LISTEN_PORT=6081 # Varnish 服务监听端口
#
# # Telnet admin interface listen address and port
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 # 管理接口 IP
VARNISH_ADMIN_LISTEN_PORT=6082 # 管理端口
#
# # Shared secret file for admin interface
VARNISH_SECRET_FILE=/etc/varnish/secret # 默认的加密文件
#
# # The minimum number of worker threads to start
VARNISH_MIN_THREADS=50 # 最小线程数
#
# # The Maximum number of worker threads to start
VARNISH_MAX_THREADS=1000 # 最大线程数
#
# # Idle timeout for worker threads
VARNISH_THREAD_TIMEOUT=120 # 线程超时时间
#
# # Cache file size: in bytes, optionally using k / M / G / T suffix,
# # or in percentage of available disk space using the % suffix.
VARNISH_STORAGE_SIZE=256M # 设置存储大小
#
# # Backend storage specification # 后端存储方式,这里默认是 malloc 方式
VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}"
#
# # Default TTL used when the backend does not specify one # 默认的TTL,当后端没有明确指定时使用
VARNISH_TTL=120
#
# # DAEMON_OPTS is used by the init script. If you add or remove options, make
# # sure you update this section, too. # 所有启动项
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} \
-p thread_pool_min=${VARNISH_MIN_THREADS} \
-p thread_pool_max=${VARNISH_MAX_THREADS} \
-p thread_pool_timeout=${VARNISH_THREAD_TIMEOUT} \
-u varnish -g varnish \
-S ${VARNISH_SECRET_FILE} \
-s ${VARNISH_STORAGE}"
#
## Alternative 4, Do It Yourself. See varnishd(1) for more information. # 方案4,设置你自己的配置
#
# DAEMON_OPTS=""
5.修改启动脚本配置文件
[root@varnish sysconfig]# vim /etc/sysconfig/varnish
VARNISH_LISTEN_PORT=80 # Varnish 服务监听端口,这里改为 80
6.启动Varnish
[root@vm_mac ~]# /etc/init.d/varnish start
Starting Varnish Cache: [ OK ]
7.查看端口
[root@vm_mac ~]# netstat -ntlp | grep varnish
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 2823/varnishd
tcp 0 0 127.0.0.1:6082 0.0.0.0:* LISTEN 2821/varnishd
tcp 0 0 :::80 :::* LISTEN 2823/varnishd
8.连接一下管理端口
[root@vm_mac ~]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,2.6.32-358.el6.x86_64,x86_64,-smalloc,-smalloc,-hcritbit
varnish-4.0.3 revision b8c4a34
Type 'help' for command list.
Type 'quit' to close CLI session.
varnish>
9.查看所有管理命令
varnish> help
200
help [<command>] # 查看帮助
ping [<timestamp>]
auth <response>
quit
banner # 查看 banner
status # 查看状态
start
stop
vcl.load <configname> <filename> # 加载 vcl
vcl.inline <configname> <quoted_VCLstring>
vcl.use <configname> # 使用/切换 vcl
vcl.discard <configname>
vcl.list # 查看 vcl 列表
param.show [-l] [<param>] # 查看 vcl 内容
param.set <param> <value>
panic.show
panic.clear
storage.list
vcl.show [-v] <configname>
backend.list [<backend_expression>] # 后端主机列表
backend.set_health <backend_expression> <state>
ban <field> <operator> <arg> [&& <field> <oper> <arg>]...
ban.list
测试一下
varnish> status
200
Child in state running
10.安装并配置httpd服务器
[root@web1 ~]# yum install -y httpd
[root@web1 ~]# cat /var/www/html/index.html
<h1>Web1.test.com</h1>
[root@web1 ~]# service httpd start
正在启动 httpd:
注,好了。下面们来配置一个简单的Varnish实例!
八、配置一个简单的Varnish实例
1.增加VCL配置文件
[root@varnish ~]# cd /etc/varnish/
[root@varnish varnish]# cp default.vcl test.vcl
[root@varnish varnish]# vim test.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.171";
.port = "80";
}
backend webserver {
.host = "192.168.0.71";
.port = "80";
}
sub vcl_recv {
set req.backend_hint = webserver;
}
注,大家可以看到,这里只定义了简单的vcl_recv其它的都没有配置,varnish会自动加载默认的vcl文件即default.vcl。
2.加载VCL配置文件
varnish> vcl.load test test.vcl
200
VCL compiled.
varnish> vcl.list
200
active 0 boot
available 0 test
varnish> vcl.use test
200
VCL 'test' now active
3.测试一下
注,从图中我们可以看出,可以正常访问后端口的服务器,但是我们不知道是否命中。下面我们来修改一下配置文件,显示是否命中缓存。
4.修改配置文件
[root@varnish varnish]# vim test.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.171";
.port = "80";
}
backend webserver {
.host = "192.168.0.71";
.port = "80";
}
sub vcl_recv {
set req.backend_hint = webserver;
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
5.再次加载一下VCL配置文件
varnish> vcl.load test1 test.vcl
200
VCL compiled.
varnish> vcl.list
200
available 0 boot
active 2 test
available 0 test1
varnish> vcl.use test1
200
6.再次测试一下
注,大家可以看到,第一次访问时没有命中,X-Cache: Miss via 192.168.0.120,让我们再次访问一下。
注,大家可以看到第二次访问命中,X-Cache: Hit form 192.168.0.120。刚才我们测试了命中的情况,下面我们来设置条件,不让缓存命中,该怎么做。
7.配置某个内容不让命中
[root@varnish varnish]# vim test.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.171";
.port = "80";
}
backend webserver {
.host = "192.168.0.71";
.port = "80";
}
#设置条件,当客户端请求 test.html 文件时不缓存(pass)
sub vcl_recv {
set req.backend_hint = webserver;
if (req.url ~ "^/test.html$") {
return(pass);
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
在 192.168.0.71 上添加一个 test.html 测试页面:
[root@vm1 ~]# echo "<h1>test for no cache</h1>" >> /var/www/html/test.html
8.重新加载配置并测试
varnish> vcl.load test2 ./test.vcl
200
VCL compiled.
varnish> vcl.list
200
available 0 boot
available 0 test
active 0 test1
available 0 test2
varnish> vcl.use test2
200
VCL 'test2' now active
注,大家可以看到,无论你访问多少次,缓存都不会命中的。X-Cache: Miss via 192.168.0.120。大家可以看到我们只要设置条件就能控制任意的文件是否能被缓存,下面我们再来说几个案例。
9.控制某个目录下的文件不让缓存
[root@varnish varnish]# vim test.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.171";
.port = "80";
}
backend webserver {
.host = "192.168.0.71";
.port = "80";
}
#设置条件,当客户端请求的 URI 以 /bbs/ 起始时,请求的文件时不缓存(pass)
sub vcl_recv {
set req.backend_hint = webserver;
if (req.url ~ "^/bbs/") {
return(pass);
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
10.控制以.php结尾的文件不让缓存
[root@varnish varnish]# vim test.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.171";
.port = "80";
}
backend webserver {
.host = "192.168.0.71";
.port = "80";
}
#设置条件,当客户端请求的 URI 以 php 结尾时,请求的文件时不缓存(pass)
sub vcl_recv {
set req.backend_hint = webserver;
if (req.url ~ "\.php$") {
return(pass);
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
注,上面的所有案例都是根据用户请求的内容做出决策的,下面我们来配置根据响应的内容做出决策。
11.根据响应的内容做出决策案例
[root@varnish varnish]# vim test.vcl
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.0.171";
.port = "80";
}
backend webserver {
.host = "192.168.0.71";
.port = "80";
}
#设置条件,当客户端请求的 URI 以 php 结尾时,请求的文件时不缓存(pass)
sub vcl_recv {
set req.backend_hint = webserver;
if (req.url ~ "\.php$") {
return(pass);
}
}
# 如果请求方法是 GET,且请求的是静态内容时,设置缓存时间为 3600s(1h)
sub vcl_backend_response {
if (bereq.method == "GET" && bereq.url ~ "\.(html|css|js|jpg|jpeg|png|gif)$") {
set beresp.ttl = 3600s;
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
九、Varnish 检测后端主机的健康状态
Varnish可以检测后端主机的健康状态,在判定后端主机失效时能自动将其从可用后端主机列表中移除,而一旦其重新变得可用还可以自动将其设定为可用。为了避免误判,Varnish在探测后端主机的健康状态发生转变时(比如某次探测时某后端主机突然成为不可用状态),通常需要连续执行几次探测均为新状态才将其标记为转换后的状态。
每个后端服务器当前探测的健康状态探测方法通过 .probe 进行设定,其结果可由 req.backend.healthy 变量获取,也可通过 varnishlog 中的 Backend_health 查看或 varnishadm 的 debug.health 查看。
backend web1 {
.host = "www.test.com";
.probe = {
.url = "/.healthtest.html";
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
.probe中的探测指令常用的有:
(1) .url:探测后端主机健康状态时请求的URL,默认为“/”;
(2) .request: 探测后端主机健康状态时所请求内容的详细格式,定义后,它会替换.url指定的探测方式;比如:
.request =
"GET /.healthtest.html HTTP/1.1"
"Host: www.test.com"
"Connection: close";
(3) .window:设定在判定后端主机健康状态时基于最近多少次的探测进行,默认是8;
(4) .threshold:在.window中指定的次数中,至少有多少次是成功的才判定后端主机正健康运行;默认是3;
(5) .initial:Varnish启动时对后端主机至少需要多少次的成功探测,默认同.threshold;
(6) .expected_response:期望后端主机响应的状态码,默认为200;
(7) .interval:探测请求的发送周期,默认为5秒;
(8) .timeout:每次探测请求的过期时长,默认为2秒;
因此,如上示例中表示每隔1秒对此后端主机www.test.com探测一次,请求的URL为http://www.test.com/.healthtest.html,在最近5次的探测请求中至少有3次是成功的(响应码为200)就判定此后端主机为正常工作状态。
如果Varnish在某时刻没有任何可用的后端主机,它将尝试使用缓存对象的“宽容副本”(graced copy),当然,此时VCL中的各种规则依然有效。因此,更好的办法是在VCL规则中判断 req.backend.healthy 变量显示某后端主机不可用时,为此后端主机增大 req.grace 变量的值以设定适用的宽容期限长度。
十、Varnish 对应两台Web服务器的配置实例
案例1:根据条件进行判断,对动静内容的请求进行分离。
[root@varnish ~]# vim /etc/varnish/test.vcl
backend webserver1 {
.host = "192.168.11.201";
.port = "80";
}
backend webserver2 {
.host = "192.168.11.202";
.port = "80";
}
# 如果请求 php 页面,发给 webserver1, 如果请求静态页面,发给 webserver 2
sub vcl_recv {
if (req.url ~ "\.php$") {
set req.backend = webserver1;
}
if (req.url ~ "\.(html|css|js|jpg|jpeg|png|gif)$") {
set req.backend = webserver2;
}
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
案例2:定义为Web集群
我们可以将多个后端服务器组成一组,Varnish 中的组被称为 directors。
我们定义多个后端服务器,然后组成一个组。这要求你加载一个 VMOD:directors 模块。然后在 vcl_init 中调用一些 actions:
[root@varnish ~]# vim /etc/varnish/test.vcl
import directors; # load the directors
backend webserver1 {
.host = "192.168.0.171";
.port = "80";
}
backend webserver2 {
.host = "192.168.0.71";
.port = "80";
}
sub vcl_init {
new bar = directors.round_robin();
bar.add_backend(server1);
bar.add_backend(server2);
}
sub vcl_recv {
# send all traffic to the bar director:
set req.backend_hint = bar.backend();
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}
案例3:为Web集群添加健康检查
[root@varnish ~]# vim /etc/varnish/test.vcl
import directors; # load the directors
backend webserver1 {
.host = "192.168.0.171";
.port = "80";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
backend webserver2 {
.host = "192.168.0.71";
.port = "80";
.probe = {
.url = "/";
.timeout = 1s;
.interval = 5s;
.window = 5;
.threshold = 3;
}
}
sub vcl_init {
new bar = directors.round_robin();
bar.add_backend(webserver1);
bar.add_backend(webserver2);
}
sub vcl_recv {
# send all traffic to the bar director:
set req.backend_hint = bar.backend();
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "Hit from"+" "+server.ip;
} else {
set resp.http.X-Cache = "Miss via"+" "+server.ip;
}
}