首页 > 代码库 > 怎样用虚拟机搭建varnish及varnish的基本应用
怎样用虚拟机搭建varnish及varnish的基本应用
Varnish
是web缓存、代理服务器,单个并发访问量在5000个左右,因此它适合中小企业的规模。
Varnish 的作者Poul-Henning Kamp是FreeBSD的内核开发者之一,他认为现在的计算机比起1975年已经复杂许多。在1975年时,储存媒介只有两种:内存与硬盘。但现在计算 机系统的内存除了主存外,还包括了cpu内的L1、L2,甚至有L3快取。硬盘上也有自己的快取装置,因此squid cache自行处理物件替换的架构不可能得知这些情况而做到最佳化,但操作系统可以得知这些情况,所以这部份的工作应该交给操作系统处理,这就是 Varnish cache设计架构
Varnish与一般服务器软件类似,分为master(management)进程和child(worker,主要做cache的工作)进程。master进程读入命令,进行一些初始化,然后fork并监控child进程。child进程分配若干线程进行工作,主要包括一些管理线程和很多woker线程。
针对文件缓存部分,master读入存储配置(-s file[,path[,size[,granularity]]] ),调用合适的存储类型,然后创建/读入相应大小的缓存大文件。接着,master初始化管理该存储空间的结构体。这些变量都是全局变量,在fork以后会被child进程所继承(包括文件描述符)。
在child进程主线程初始化过程中,将前面打开的存储大文件整个mmap到内存中(如果超出系统的虚拟内存,mmap失败,进程会减少原来的配置mmap大小,然后继续mmap),此时创建并初始化空闲存储结构体,挂到存储管理结构体,以待分配。
接着,真正的工作开始,Varnish的某个负责接受新HTTP连接的线程开始等待用户,如果有新的HTTP连接过来,它总负责接收,然后叫醒某个等待中的线程,并把具体的处理过程交给它。Worker线程读入HTTP请求的URI,查找已有的object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
分配缓存的过程是这样的:它根据所读到object的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个object的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据LRU机制,把最旧的object释放掉。
释放缓存的过程是这样的:有一个超时线程,检测缓存中所有object的生存期,如果超初设定的TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存。
整个文件缓存的管理,没有考虑文件与内存的关系,实际上是将所有的object都考虑是在内存中,如果系统内存不足,系统会自动将其换到swap空间,而不需要varnish程序去控制。
一、基本的IP配置
主机 ip
node1.edu.com 172.16.24.1 192.168.24.1
node2.edu.com 192.168.24.11
node3.edu.com 192.168.24.12
2)所需要的varnish安装包
varnish-3.0.4-1.el6.x86_64.rpm
varnish-docs-3.0.4-1.el6.x86_64.rpm
varnish-libs-3.0.4-1.el6.x86_64.rpm
3)配置服务
node1
配置两块网卡(172.16.24.1,192.168.24.1)
node2 (192.168.24.11)
yum install php php-mysql mysql-server
提供web页面并开启web服务
#im /var/www/html/index.html
#h1>node2.edu.com</h1>
#ervice httpd start
node3(192.168.24.12)
yum install php php-mysql mysql-server
提供web页面并开启web服务
#im /var/www/html/index.html
#h1>node3.edu.com</h1>
#ervice httpd start
4)在主机1 上安装varnish
[root@node1 ~]# rpm -ivh varnish*.rpm
Preparing... ########################################### [100%]
1:varnish-libs ########################################### [ 33%]
2:varnish ########################################### [ 67%]
3:varnish-docs ########################################### [100%]
二、配置文件的意义
NFILES=131072 打开最大的文件数
MEMLOCK=82000 用多大内存空间来保存日志信息的
NPROCS="unlimited"
RELOAD_VCL=1 重新读取服务时是否重新读取VCL并重新编译vcl文件
DAEMON_OPTS="-a :6081 \ 指定监听的地 址和端口
# -T localhost:6082 \ 管理连接所使用的地址和端口
# -b localhost:8080 \
# -u varnish -g varnish \
# -s file,/var/lib/varnish/varnish_storage.bin,1G" 缓存类型
-S 服务器端使用的指定密钥文件
VARNISH_VCL_CONF=/etc/varnish/default.vcl默认读取的vcl文件
VARNISH_LISTEN_PORT=80 监听的端口
VARNISH_ADMIN_LISTEN_ADDRESS=127.0.0.1 管理接口所监听的地址
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_STORAGE= 存储方式
1)编辑配置文件,定义varnish
[root@node1 varnish]# vim /etc/sysconfig/varnish
VARNISH_LISTEN_PORT=80 #定义监听的端口
VARNISH_STORAGE="malloc,100M" #定义使用内存来存储
2)启动服务
[root@node1 ~]# service varnish start
Starting varnish HTTP accelerator: [ OK ]
[root@node1 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 :::111 :::*
LISTEN 0 128 *:111 *:*
LISTEN 0 128 :::80 :::*
LISTEN 0 128 *:80 *:*
3)定义单个后端服务器
#cd /etc/varnish/
#vim text.vcl
backend webser{
.host = "192.168.24.11";
.port = "80";
}
4)连接varnish
[root@node1 varnish]# varnishadm -S /etc/varnish/secret -T 127.0.0.1:6082
200 201
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,2.6.32-431.el6.x86_64,x86_64,-smalloc,-hcritbit
varnish> vcl.load test1 text.vcl
200
VCL compiled.
varnish> vcl.use test1
200
5)查看服务是否连接
三、定义vcl文件让varnish支持更多的功能
1)定义多台主机
backend web1 {
.host = "backweb1.magedu.com";
.port = "80";
}
director webservers random {
.retries = 5;
{
.backend = web1;
.weight = 2;
}
{
.backend = {
.host = "backweb2.magedu.com";
.port = "80";
}
.weight = 3;
}
}
backend web1{
.host = "192.168.24.11";
.port = "80";
}
backend web2 {
.host = "192.168.24.12";
.port = "80";
}
director webserves random {
{
.backend = web1;
.weight = 2;
}
{
.backend = web2;
.weight = 3;
}
sub vcl_recv {
set req.backend = webserves;
if (req.url ~ "test.html") {
return(pass);
}
return(lookup);
}
2)设定是否命中
sub vcl_deliver {
set resp.http.X-Age = resp.http.Age;
unset resp.http.Age;
if (obj.hits > 0) {
set resp.http.X-Cache = “HIT”;
} else {
set resp.http.X-Cache = “MISS”;
}
}
3)判断是哪个主机命中的
backend webser{
.host = "192.168.24.11";
.port = "80";
}
sub vcl_deliver {
set resp.http.X-Age = resp.http.Age;
unset resp.http.Age;
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from "+ server.ip;
} else {
set resp.http.X-Cache = "MISS";
}
}
~
~
~ backend webser{
.host = "192.168.24.11";
.port = "80";
}
sub vcl_recv {
if (req.url ~ "test.html") {
return(pass);
}
return(lookup);
}
sub vcl_fetch {
if (req.url ~ "\.(jpg|jpeg|gif|png)$") {
set beresp.ttl = 7200s;
}
if (req.url ~ "\.(html|css|js)$") {
set beresp.ttl = 1200s;
}
}
sub vcl_deliver {
set resp.http.X-Age = resp.http.Age;
unset resp.http.Age;
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from "+ server.ip;
} else {
set resp.http.X-Cache = "MISS";
}
}