Varnish
Varnish是一款高性能的开源HTTP
总体架构
总体流程主进程 fork 子进程,主进程等待子进程的信号,子进程退出后,主进程重新启动子进程子进程生成若干。
Accept 线程:接受请求,将请求挂在 overflow队列上
Work 线程: 多个,从对列上摘除请求,对请求进行处理,直到完成,然后处理下一个请求
Epoll 线程: 一个请求处理称作一个 session,在 session 周期内,处理完请求后,会交给Epoll 处理,监听是否还有事件发生。
Expire :对于的对象,根据过期时间,组织成,该线程周期检查该堆的根,处理过期的文件。
线程之间的关系:
accept 线程
监听端口,接受连接。
接受后组织成 struct ses(session 结构) ,看是否有空闲的工作线程,如果有,将请求给它,
pthread_cond_signal 信号通知它没有空闲线程,如果 overflow过大,则放弃该请求。否则,
将其挂在 overflow 上(需要更多工作线程,发通知)。
从 overflow队列上摘取请求(struct ses),进入处理,处理结束后,通过 pipe通信,
将 struct ses发送给 epoll 线程。
Epoll 线程,得到传过来的 struct ses,若还没有过期,将 socket 放入 epoll 的事件中,事
件发生时,也会将其放入到 overflow中进行。
工作流程
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程序去控制。
安装配置
实验环境:
server1 varnish主机
server2 http主机
server3 http主机
安装服务
[root@server1 ~]# yum install -y varnish-3.0.5-1.el6.x86_64.rpm varnish-libs-3.0.5-1.el6.x86_64.rpm
在此路径下,修改文件[root@server1 sysconfig]# pwd/etc/sysconfig[root@server1 sysconfig]# vim varnish 配置 varnish 服务端口
[root@server2 ~]# yum install -y httpd
为了实验效果明显,编写页面如下,开启服务
查看端口
在varnish主机,server1上,修改文件
[root@server1 varnish]# pwd/etc/varnish[root@server1 varnish]# vim default.vcl 配置一个后端服务器
[root@server1 varnish]# /etc/init.d/varnish start 开启服务
查看缓存命中情况
[root@server1 varnish]# vim default.vcl
[root@server1 varnish]# /etc/init.d/varnish reload 重新加载
测试:
[root@foundation12 ~]# vim /etc/hosts 加入解析
第一次测试,可以看到,状态为miss
下来测试,状态就已改变
时间也可以在下面文件中更改
[root@server1 varnish]# vim /etc/sysconfig/varnish 更改缓存时间
当在varnish端,如下清空缓存时
[root@server1 varnish]# varnishadm ban.url .*$ 清空缓存
即使还没超过缓存时间,客户端测试,也会是miss状态
### 通过 varnishadm 手动清除缓存# varnishadm ban.url .*$#清除所有# varnishadm ban.url /index.html#清除 index.html 页面缓存# varnishadm ban.url /admin/$#清除 admin 目录缓存
在浏览器访问
上面已经在客户主机上加了解析
192.168.122.11(varnish主机)
在varnish主机加入的后端服务器为装有http服务server2(192.168.122.12)
可得:当访问
varnish的工作机制,可如下表示
firefox -> hosts/dns -> varnish -> httpd通过含有varnish的主机访问 不是自己去访问
定义多个不同域名站点的后端服务器
[root@server3 ~]# yum install -y httpd 安装服务
为实验效果明显,写入页面,并开启服务
[root@server1 varnish]# vim default.vcl [root@server1 varnish]# /etc/init.d/varnish reload
#当访问 www.westos.org 域名时从 web1 上取数据,访问 bbs.westos.org 域名时到 web2 取数据,访问其他页面报错。
客户端测试如下,切记做好解析
虚拟主机
[root@server3 html]# vim /etc/httpd/conf/httpd.conf 去掉注释
建立目录,写入页面,重启服务
加入解析
测试
定义负载均衡
定义健康检查
[root@server1 varnish]# vim default.vcl
#把多个后端聚合为一个组,并检测后端健康状况
set req.backend = lb;return (pass); #为了测试方便,不进行缓存。
[root@server1 varnish]# /etc/init.d/varnish reload
[root@server1 varnish]# /etc/init.d/varnish reload 重新加载
客户端测试
varnish cdn 推送平台
varnish主机安装
[root@server1 ~]# yum install -y httpd
[root@server1 ~]# vim /etc/httpd/conf/httpd.conf
修改监听端口
[root@server1 ~]# /etc/init.d/httpd start
[root@server1 ~]# unzip -x bansys.zip 解压
[root@server1 html]# yum install -y php 安装php[root@server1 html]# vim config.php
[root@server1 html]# /etc/init.d/httpd restart
浏览器测试
#bansys 有两种工作模式,分别是:telnet 和 http 模式。#telnet 模式需要关闭 varnish 服务管理端口的验证,注释掉/etc/sysconfig/varnish 文件中的 “ -S ${VARNISH_SECRET_FILE}”这行,重启 varnish 服务即可。
[root@server1 varnish]# vim default.vcl
[root@server1 varnish]# /etc/init.d/varnish reload