CDN的全称是Content Delivery Network,即内容奋发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
Varnish是高性能开源的反向代理服务器和HTTP缓存服务器
Varnish的功能与Squid服务器相似,都可以用来做HTTP缓存
Squid是从硬盘读取缓存的数据,而Varnish把数据存放在内存中,直接从读取内存,避免了频繁在内存、磁盘中交换文件,所以Varnish要相对更高效,但也有缺点,内存中的缓存在服务器重启后会丢失
1)初始化过程
Varnish 的master进程负责启动工作,master进程读取配置文件,根据指定的空间大小(例如管理员分配了2G内存)来创建存储空间,创建并管理child进程
child进程来处理后续任务,它会分配一些线程来执行不同的工作,例如
接受http请求
为缓存对象分配存储空间
清除过期缓存对象
释放空间 碎片整理
2)http请求处理过程
有一个专门负责接收http请求的线程,一直监听请求端口,当有请求过来时,负责唤起一个工作线程来处理请求
工作线程会分析http请求的uri,知道了这个请求想要什么,就到缓存中查找是否有这个对象
如果有,就把缓存对象直接返回给用户
如果没有,会把请求转给后端服务器处理,并等待结果,工作线程从后端得到结果内容后,先把内容作为一个缓存对象保存到缓存空间(以备下次请求这个对象时快速响应),然后再把内容返回给用户
3)分配缓存过程
有一个对象需要缓存时,根据这个对象的大小,到空闲缓存区中查找大小最适合的空闲块,找到后就把这个对象放进去
如果这个对象没有填满这个空闲块,就把剩余的空间做为一个新的空闲块
如果空闲缓存区中没地方了,就要先删除一部分缓存来腾出地方,删除是根据最近最少使用原则
4)释放缓存过程
有一个线程来负责缓存的释放工作,他定期检查缓存中所有对象的生存周期,如果某个对象在指定的时间段内没有被访问,就把这个对象删除,释放其占用的缓存空间
释放空间后,检查一下临近的内存空间是否是空闲的,如果是,就整合为一个更大的空闲块,实现空间碎片的整理
处理过程大致分为如下几个步骤:
(1)Receive 状态,也就是请求处理的入口状态,根据 VCL 规则判断该请求应该是 Pass 或
Pipe,或者进入 Lookup(本地查询)。
(2)Lookup 状态,进入此状态后,会在 hash 表中查找数据,若找到,则进入 Hit 状态,否则进
入 miss 状态。
(3)Pass 状态,在此状态下,会进入后端请求,即进入 fetch 状态。
(4)Fetch 状态,在 Fetch 状态下,对请求进行后端的获取,发送请求,获得数据,并进行本地
的存储。
(5)Deliver 状态, 将获取到的数据发送给客户端,然后完成本次请求。
【vm1:172.25.16.1】
[root@vm1 varnish]# yum install varnish-3.0.5-1.el6.x86_64.rpm varnish-libs-3.0.5-1.el6.x86_64.rpm
[root@vm1 varnish]# rpm -qc varnish-3.0.5-1.el6.x86_64 ###看生成什么文件
/etc/logrotate.d/varnish
/etc/sysconfig/varnish ###主配置文件
/etc/varnish/default.vcl
[root@vm1 varnish]# vim /etc/sysconfig/varnish
[root@vm1 varnish]# vim /etc/security/limits.conf
注:实际没有给文件所记录的那么大。目前无问题,但实际上线后会出问题。
主配置文件里面记录着varnish对系统文件数目、内存、进程数目的上限;但实际的上限主要还要看硬件大小。
[root@vm1 varnish]# ulimit -a ##看实际系统给的大小
[root@vm1 varnish]# vim /etc/varnish/default.vcl
--->
backend default {
.host = "172.25.16.2"; ##web服务器所在主机
.port = "80";
}
[root@vm1 varnish]# /etc/init.d/varnish start ##开服务
[root@vm1 varnish]# ps aux ##看进程
注:开启varnish服务会开两个进程:
1)root进程
2)varnish进程:工作线程,负责foc一个个子进程
【vm2:172.25.16.2】
[root@vm2 ~]# yum install httpd -y
[root@vm2 ~]# cd /var/www/html
[root@vm2 html]# vim index.html
this is vm2
[root@vm2 html]# /etc/init.d/httpd start
[root@foundation16 images]# curl 172.25.16.1
this is vm2
用户通过varnish访问web服务器,第一次是访问web服务器,之后会把数据缓存在内存中(有时效,主配置文件里默认120s),在刷新缓存前的每一次是访问varnish而不用去web服务器
[root@vm1 varnish]# vim /etc/varnish/default.vcl
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X- Cache = "HIT from westos cache";
}
else {
set resp.http.X- Cache = "MISS from westos cache";
}
reture (deliver);
}
[root@vm1 varnish]# /etc/init.d/varnish reload
[root@vm1 varnish]# varnishadm ban.url .*$
第一次:miss
[root@foundation16 images]# curl -I 172.25.16.1
HTTP/1.1 200 OK
Server: Apache/2.2.15 (Red Hat)
Last-Modified: Tue, 25 Dec 2018 06:19:38 GMT
ETag: "209c7-c-57dd2b2b84c1f"
Content-Type: text/html; charset=UTF-8
Content-Length: 12
Accept-Ranges: bytes
Date: Tue, 25 Dec 2018 07:29:31 GMT
X-Varnish: 242030745
Age: 0
Via: 1.1 varnish
Connection: keep-alive
X-Cache: MISS from westos cache
之后,就是命中(在缓存时效内);且age会不断增加
[root@foundation16 images]# curl -I 172.25.16.1
HTTP/1.1 200 OK
Server: Apache/2.2.15 (Red Hat)
Last-Modified: Tue, 25 Dec 2018 06:19:38 GMT
ETag: "209c7-c-57dd2b2b84c1f"
Content-Type: text/html; charset=UTF-8
Content-Length: 12
Accept-Ranges: bytes
Date: Tue, 25 Dec 2018 07:37:40 GMT
X-Varnish: 242030749 242030747
Age: 6
Via: 1.1 varnish
Connection: keep-alive
X-Cache: HIT from westos cache
【vm3:172.25.16.3】
[root@vm3 ~]# yum install httpd -y
[root@vm3 ~]# cd /var/www/html/
[root@vm3 html]# vim index.html
this is vm3
[root@vm3 html]# /etc/init.d/httpd start
[root@vm3 html]# netstat -antlpe | grep httpd
tcp 0 0 :::80 :::* LISTEN 0 9278 1063/httpd
[root@vm1 varnish]# vim /etc/varnish/default.vcl
backend web1 {
.host = "172.25.16.2";
.port = "80";
}
backend web2 {
.host = "172.25.16.3";
.port = "80";
}
sub vcl_recv {
if (req.http.host ~ "^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend = web1;
} elsif (req.http.host ~ "^bbs.westos.org") {
set req.backend = web2;
} else { error 404 "westos cache";
}
}
[root@vm1 varnish]# /etc/init.d/varnish reload
[root@foundation16 images]# vim /etc/hosts
172.25.16.1 vm1 www.westos.org westos.org bbs.westos.org dd.org
[root@foundation16 images]# curl www.westos.org
this is vm2
[root@foundation16 images]# curl westos.org
this is vm2
[root@foundation16 images]# curl bbs.westos.org
this is vm3
[root@foundation16 images]# curl dd.org ###404错误
westos cache XID: 242030755 Varnish cache server
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Error 404 westos cache
Guru Meditation:
[root@foundation16 images]# curl bb.org ##无解析
curl: (7) Failed to connect to 192.184.12.62: Network is unreachable
【vm3:172.25.16.3】
[root@vm3 html]# mkdir /www
[root@vm3 html]# mkdir /bbs
[root@vm3 html]# cd /www
[root@vm3 www]# vim index.html
vm3 /www
[root@vm3 www]# cd /bbs
[root@vm3 bbs]# vim index.html
vm3 /bbs
[root@vm3 bbs]# vim /etc/httpd/conf/httpd.conf
989 NameVirtualHost *:80
1002
1003 DocumentRoot /www
1004 ServerName www.westos.org
1005
1006
1007
1008 DocumentRoot /bbs
1009 ServerName bbs.westos.org
1010
[root@vm1 varnish]# vim /etc/varnish/default.vcl
director lb round-robin { ##定义轮询
{.backend = web1;}
{.backend = web2;}
}
sub vcl_recv {
if (req.http.host ~ "^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend = lb; ###使用轮询机制
return (pass); ##测试时用;在每次varnish访问后台服务器后不缓存,否则无法看到实验效果
} elsif (req.http.host ~ "^bbs.westos.org") {
set req.backend = web2;
} else { error 404 "westos cache";
}
}
[root@vm1 varnish]# /etc/init.d/varnish reload
3.测试
[root@foundation16 images]# curl www.westos.org
this is vm2
[root@foundation16 images]# curl www.westos.org
vm3 /www
[root@foundation16 images]# curl www.westos.org
this is vm2
[root@foundation16 images]# curl bbs.westos.org
vm3 /bbs
【varnish服务器上】
[root@vm1 varnish]# yum install unzip php httpd -y
[root@vm1 varnish]# unzip bansys.zip -d /var/www/html/
[root@vm1 varnish]# cd /var/www/html/
[root@vm1 html]# vim config.php
//varnish主机列表
//可定义多个主机列表
$var_group1 = array(
'host' => array('172.25.16.1'),
'port' => '8080',
);
//varnish群组定义
//对主机列表进行绑定
$VAR_CLUSTER = array(
'www.westos.org' => $var_group1,
);
[root@vm1 html]# vim /etc/httpd/conf/httpd.conf
136 Listen 8080 ###因为80端口已占用
[root@vm1 html]# vim /etc/varnish/default.vcl
acl westos {
"127.0.0.1";
"172.25.16.0"/24;
}
sub vcl_recv {
if (req.http.host ~ "^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend = lb;
return (pass);
} elsif (req.http.host ~ "^bbs.westos.org") {
set req.backend = web2;
} else { error 404 "westos cache";
}
}
sub vcl_recv {
if (req.request == "BAN") {
if (!client.ip ~ westos) {
error 405 "Not allowed.";
}
ban("req.url ~ " + req.url);
error 200 "ban added";
}
}
[root@vm1 html]# /etc/init.d/varnish reload
测试:
172.25.16.1:8080