一、简介
Varnish是一个cache型的HTTP反向代理。Varnish的核心功能是能能将后端web服务器返回的结果缓存起来,如果发现后续有相同的请求,Varnish将不会将这个请求转发到web服务器,而是返回缓存中的结果。这将有效的降低web服务器的负载,提升响应速度,并且每秒可以响应更多的请求。Varnish速度很快的另一个主要原因是其缓存全部都是放在内存里的,这比放在磁盘上要快的多。避免了Squid频繁在内存、磁盘中交换文件的缺点。
二、安装
1. 添加varnish用户
[root@varnish ~]# groupadd -r varnish [root@varnish ~]# useradd -r -M -s /sbin/nologin -g varnish varnish
2. 安装varnish软件
[root@varnish ~]# yum install -y gcc gcc-c++ pcre-devel make ncurses* libedit* [root@varnish ~]# tar xf varnish-3.0.5.tar.gz [root@varnish ~]# cd varnish-3.0.5 [root@varnish varnish-3.0.5]# ./configure --prefix=/usr/local/varnish \ --enable-debugging-symbols \ --enable-developer-warnings \ --enable-dependency-tracking [root@varnish varnish-3.0.5]# make [root@varnish varnish-3.0.5]# make install
3. 拷贝varnish启动所需的配置文件
[root@varnish varnish-3.0.5]# cp redhat/varnish_reload_vcl /usr/local/varnish/bin/ [root@varnish varnish-3.0.5]# cp redhat/varnish.sysconfig /etc/sysconfig/varnish [root@varnish varnish-3.0.5]# cp redhat/varnish.initrc /etc/init.d/varnish [root@varnish varnish-3.0.5]# chkconfig --add varnish [root@varnish varnish-3.0.5]# chkconfig varnish on
4. 完善安装(可以不做)
[root@varnish ~]# vim /etc/profile export PATH=$PATH:/usr/local/varnish/bin/ #最后添加这一行 [root@varnish ~]# vim /etc/man.config MANPATH /usr/local/varnish/share/man #添加这一行
5. 简单配置,让varnish足以成功启动
1)配置/etc/sysconfig/varnish这个配置文件
[root@varnish ~]# vim /etc/sysconfig/varnish ## Alternative 3, Advanced configuration # # See varnishd(1) for more information. # # # Main configuration file. You probably want to change it :) VARNISH_VCL_CONF=/usr/local/varnish/etc/varnish/default.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=80 # # # Telnet admin interface listen address and port VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 VARNISH_ADMIN_LISTEN_PORT=6082 # # # Shared secret file for admin interface VARNISH_SECRET_FILE=/usr/local/varnish/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 location #VARNISH_STORAGE_FILE=/var/lib/varnish/varnish_storage.bin # # # 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=1G # # # Backend storage specification #VARNISH_STORAGE="file,${VARNISH_STORAGE_FILE},${VARNISH_STORAGE_SIZE}" VARNISH_STORAGE="malloc,${VARNISH_STORAGE_SIZE}" # # # Default TTL used when the backend does not specify one 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} \ -w ${VARNISH_MIN_THREADS},${VARNISH_MAX_THREADS},${VARNISH_THREAD_TIMEOUT} \ -u varnish -g varnish \ -S ${VARNISH_SECRET_FILE} \ -s ${VARNISH_STORAGE}" #
/etc/init.d/varnish中的变量$DAEMON_OPTS就是在这个配置文件中设置的,这个变量其实就是指定varnishd这个进程启动的一些参数,这个配置文件中一共包括了4个可供选择的模版,这里就用第3个高级配置
VARNISH_VCL_CONF
用于指定配置文件的位置
VARNISH_LISTEN_PORT=80
指定varnish监听的端口
VARNISH_ADMIN_LISTEN_ADDRESS
指定管理接口监听的地址
VARNISH_ADMIN_LISTEN_PORT
指定管理接口监听的端口
VARNISH_SECRET_FILE
指定管理接口的密码文件
VARNISH_STORAGE=
"malloc,${VARNISH_STORAGE_SIZE}"其中malloc是一个函数,用户分配内存空间的
2)修改启动脚本
[root@varnish ~]# vim /etc/init.d/varnish exec="/usr/local/varnish/sbin/varnishd" reload_exec="/usr/local/varnish/bin/varnish_reload_vcl"
3)修改默认配置文件
[root@varnish ~]# vim /usr/local/varnish/etc/varnish/default.vcl backend default { .host = "172.16.1.20"; .port = "80"; } #指定需要代理的主机的IP地址和端口号
4)生成secret文件
[root@varnish ~]# echo -n "zhuftd" | md5sum > /usr/local/varnish/etc/varnish/secret [root@varnish ~]# chmod 644 /usr/local/varnish/etc/varnish/secret
5)修改reload文件
[root@varnish ~]# vim /usr/local/varnish/bin/varnish_reload_vcl 74 VARNISHADM="/usr/local/varnish/bin/varnishadm $secret -T $VARNISH_ADMIN_LISTEN_ADDRESS:$VARNISH_ADMIN_LISTE N_PORT"
6. 启动varnish
[root@varnish ~]# service varnish start Starting Varnish Cache: [ OK ] [root@varnish ~]# service varnish status varnishd (pid 11276) is running...
二、varnish的处理流程
主要的动作:
pass: varnish将请求转发给后端服务器。
lookup: 从hash表中查找数据。
pipe: 在client和backend之间建立一条连接,varnish不会看它们之间传送的数据。由于HTTP1.1中一个连接可以传输客户端的多个请求,所以应该通知varnish增加一个"Connection: close"的头部。
deliver: 将获取到的数据发送给客户端,完成本次请求。
VCL支持的运算符:
= | 赋值运算符 |
== | 对比 |
~ | 匹配,可以基于正则表达式匹配 |
! | 逻辑非 |
&& | 逻辑与 |
|| | 逻辑或 |
VCL中3个重要的数据结构(Requests, responses and objects)
req | 从客户端过来的请求 | req.backend | 指定对应的后端主机 |
req.http.x-forwarded-for | http请求中的源地址 | ||
http请求中的用户认证信息 | |||
req.request | 指定请求的类型,例如GET、HEAD、POST等 | ||
req.url | 指定请求的地址 | ||
req.http.Cookie | http请求中的cookie信息 | ||
客户端请求的域名或者IP地址 | |||
req.restarts | 表示请求重试的次数 | ||
beresp | 从代理的服务器端返回的响应 | beresp.url | 后端服务器返回数据的url,可以根据这个url匹配正则表达式,然后设置不同的缓存时间 |
beresp.ttl | 表示缓存的生存周期,也就是cache保留多长时间,单位是秒 | ||
obj | 存储的cache中的对象 | obj.status | 表示返回内容的请求状态代码 |
obj.response | 表示返回内容的请求状态信息 |
这个的意思是当http请求中包含认证信息和cookie时,直接转发给后端的服务器(nginx、apache等),因为当第一个用户成功认证以后,如果varnish缓存了这个信息,那么所有的其他客户端的请求将不需要认证。
三、后端服务器配置
1. 服务器配置
probe health { #配置健康检测 .url = "/index.html"; #varnish检测的页面 .interval = 10s; #检测的间隔时间 .timeout = 30ms; #检测的超时时间 .window = 5; #varnish会维持5个结果 .threshold = 3; #至少有3次window检测是成功的,才算健康 } backend web1 { #定义后端服务器1 .host = "172.16.1.20"; .port = "80"; .probe = health; #调用健康模版 .connect_timeout = 1s; #等待连接后端服务器的时间 .first_byte_timeout = 5s; #等待backend传输过来第一个字节的时间 .between_bytes_timeout = 2s; #传输时字符之间的时间间隔 } backend web2 { #定义后端服务器2 .host = "172.16.1.40"; .port = "80"; .probe = health; .connect_timeout = 1s; .first_byte_timeout = 5s; .between_bytes_timeout = 2s; }
配置完成之后还需在vcl_recv子模块中调用
sub vcl_recv { if (req.http.host ~ "www\.aa\.com"){ set req.backend = web1;} else{ set req.backend = web2;} }
2. 负载均衡
director myLB round-robin { { .backend = web1; } { .backend = web2; } } sub vcl_recv { set req.backend = myLB; } #当然负载均衡的调度机制不是只有round-robin,还有random、DNS等
3. 访问控制
acl purge { "localhost"; "127.0.0.1"; "172.16.1.0"/24; } sub vcl_recv { if (req.request == "PURGE") { if (!client.ip ~ purge) { error 405 "Not allowed."; } lookup; } }
四、内核参数优化
[root@varnish ~]# vim /etc/sysctl.conf net.ipv4.tcp_fin_timeout = 30 net.ipv4.tcp_keepalive_time = 300 net.ipv4.tcp_syncookies = 1 net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 net.ipv4.ip_local_port_range = 5000 65000
net.ipv4.
tcp_fin_timeout这个参数表示当服务器指定关闭连接时,socket保持在FIN-WAIT-2状态的最大时间。
net.ipv4
.tcp_keepalive_time这个参数表示当keepalive启用时,TCP发送keepalive消息的频度。默认是2小时,若将其设置得小一些,可以更快地清理无效的连接。
net.ipv4.tcp_syncookies = 1表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击。
net.ipv4.tcp_tw_reuse = 1
表示允许将TIME-WAIT状态的socket重新用于新的TCP连接。
net.ipv4.
tcp_tw_recycle = 1表示开启TCP连接中TIME-WAIT sockets的快速回收。
net.ipv4.
ip_local_port_range这个参数定义了在UDP和TCP连接中本地(不包括连接的远端)端口的取值范围。
五、管理
1.varnishadm
[root@varnish ~]# varnishadm -T 127.0.0.1:6082 -S /usr/local/varnish/etc/varnish/secret 200 ----------------------------- Varnish Cache CLI 1.0 ----------------------------- Linux,2.6.32-358.el6.x86_64,x86_64,-smalloc,-smalloc,-hcritbit varnish-3.0.5 revision 1a89b1f Type 'help' for command list. Type 'quit' to close CLI session. varnish> help
2. varnishlog
[root@varnish ~]# varnishlog 0 Backend_health - web1 Still healthy 4--X-RH 5 3 5 0.001350 0.001759 HTTP/1.1 200 OK 0 Backend_health - web2 Still healthy 4--X-RH 5 3 5 0.003149 0.002433 HTTP/1.1 200 OK 9 SessionOpen c 172.16.1.254 53905 0.0.0.0:80 9 ReqStart c 172.16.1.254 53905 19241885 9 RxRequest c GET 9 RxURL c / 9 RxProtocol c HTTP/1.1 9 RxHeader c Accept: text/html, application/xhtml+xml, */* 9 RxHeader c Accept-Language: zh-CN 9 RxHeader c User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0) 9 RxHeader c Accept-Encoding: gzip, deflate 9 RxHeader c Host: 172.16.1.30 9 RxHeader c If-Modified-Since: Tue, 04 Mar 2014 05:08:34 GMT 9 RxHeader c If-None-Match: "40085-5-4f3c0e55fb165" 9 RxHeader c DNT: 1 9 RxHeader c Connection: Keep-Alive 9 VCL_call c recv lookup 9 VCL_call c hash 9 Hash c / 9 Hash c 172.16.1.30 9 VCL_return c hash 9 Hit c 19241876 9 VCL_call c hit deliver 9 VCL_call c deliver deliver 9 TxProtocol c HTTP/1.1 9 TxStatus c 304 #表示从缓存中取的数据 9 TxResponse c Not Modified 9 TxHeader c Server: Apache/2.2.15 (Red Hat) 9 TxHeader c Last-Modified: Tue, 04 Mar 2014 05:08:34 GMT 9 TxHeader c ETag: "40085-5-4f3c0e55fb165" 9 TxHeader c Content-Type: text/html; charset=UTF-8 9 TxHeader c Accept-Ranges: bytes 9 TxHeader c Date: Sun, 23 Mar 2014 09:09:33 GMT 9 TxHeader c X-Varnish: 19241885 19241876 9 TxHeader c Age: 9 9 TxHeader c Via: 1.1 varnish 9 TxHeader c Connection: keep-alive 9 Length c 0 9 ReqEnd c 19241885 1395565773.935906887 1395565773.936139584 0.000288963 0.000075579 0.000157118
3. varnishstat
这个命令可以查看varnish的工作状态,缓存命中率等信息