一、什么是 CDN
CDN: 缓存网络,Content Delivery Network,即内容分发网络;加速器,反向代理缓存。
基本原理:广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在
用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存
服务器直接响应用户请求内容管理和全局的网络流量管理(Traffic Management)是 CDN 的核心
所在。通过用户就近性和服务器负载的判断, CDN 确保内容以一种极为高效的方式为用户的请求提
供服务.总的来说,内容服务基于缓存服务器,也称作代理缓存(Surrogate),它位于网络的边缘,距
用户仅有"一跳"(Single Hop)之遥。同时,代理缓存是内容提供商源服务器(通常位于 CDN 服务
提供商的数据中心)的一个透明镜像。这样的架构使得 CDN 服务提供商能够代表他们客户,即内容
供应商,向最终用户提供尽可能好的体验,而这些用户是不能容忍请求响应时间有任何延迟的。
二 .什么是Varnish
varnish 是一款具有高性能的开源 HTTP 加速器,具有反向代理、缓存的功能。严格意义上说,Varnish是一个高性能的反向代理软件,只不过与其出色的缓存功能相比,企业更愿意使用其搭建缓存服务器。同时,于其工作在Web Server的前端,有一部分企业已经在生产环境中使用其作为旧版本的squid的替代方案,以在相同的服务器成本下提供更好的缓存效果,Varnish更是作为CDN缓存服务器的可选服务之一。
三. 什么是VCL
VCL是varnish配置语言:varnish是一个专门用于描述varnish请求处理和文件缓存策略规则的语言。
当一个新的配置加载后,varnishd管理进程将会将其转换为C代码并编译,然后加载到服务器进程。
VCL语法格式,处理过程大致分为如下几个步骤:
(1)Receive 状态,也就是请求处理的入口状态,根据 VCL 规则判断该请求应该是 Pass 或Pipe,或者进入 Lookup(本地缓存查询)。
(2)Lookup 状态,进入此状态后,会在 hash 表中查找数据,若找到,则进入 Hit 状态,否则进入 miss 状态。
(3)Pass 状态,在此状态下,会进入后端请求,即进入 fetch 状态。
(4)Fetch 状态,在 Fetch 状态下,对请求进行后端的获取,发送请求,获得数据,并进行本地的存储。
(5)Deliver 状态, 将获取到的数据发送给客户端,然后完成本次请求
实验环境:
rhel7.3 selinux and firewalld disabled
server1 (varnish) 172.25.37.1
server2 (apache)172.25.37.2
server3 (apache) 172.25.37.3
1.安装varnish
yum install -y varnish-4.0.5-1.el7.x86_64.rpm varnish-libs-4.0.5-1.el7.x86_64.rpm jemalloc-3.6.0-1.el7.x86_64.rpm
#查看配置文件
#安装好后会生成vainish用户和用户组
2.配置
server1 代理服务器:
在/usr/lib/systemd/system/varnish.service中,查看varnish配置要求(允许的最大打开文件数及限制的锁定内存大小)
LimitNOFILE=131072 #要求打开文件数最大为131072
LimitMEMLOCK=82000 #要求内存为82000KB
但是系统默认打开文件数为1024,
ulimit -a 查看系统最大打开文件数
所以修改系统配置,以符合varnish要求:
1)将代理服务器的内存扩大到2048M;
2)修改系统最大打开文件数
- 可以使用命令临时修改:ulimit -a #查看所有服务默认打开文件最大数,以及默认存储容量
命令:ulimit -n 131072 #将所有服务所开启的最大文件数该为131072
命令:ulimit -m 82000 #将所有的最大容量改为82MB - 在文件中将VARNISH服务配置永久更改:
vim /etc/security/limits.conf
# End of file
varnish - nofile 131072
varnish - memlock 82000
systemctl start varnish
设置默认后端提供web服务的服务器以及缓存命中情况
vim /etc/varnish/default.vcl
backend default {
.host = "172.25.37.2";
.port = "80";
}
修改varnish监听端口
vim /etc/varnish/varnish.params
VARNISH_LISTEN_PORT=80
缓存命中情况
sub vcl_deliver {
# Happens when we have all the pieces we need, and are about to send the
# response to the client.
#
# You can do accounting or modifying the final object here.
if(obj.hits>0){
set resp.http.X-Cache="HIT from westos cache";
}
else{
set resp.http.X-Cache="MISS from westos cache";
}
return(deliver);
}
systemctl restart varnish
server2 web服务器
下载apache服务
vim /var/www/html/index.html
server2
将向代理服务器的请求转发到后端服务器
真机作为客户端访问代理,代理将请求转发到后端server2
curl 172.25.37.1
curl -I 172.25.37.1
通过 varnishadm 手动清除缓存
清除代理服务器缓存,/表示“清除所有”
varnishadm ban req.url “~” / #清除所有缓存
varnishadm ban req.url “~” /index.html #清除 index.html 页面缓存
3.多后端(定义多个不同域名站点的后端服务器)
server3 web服务器:
vim /var/www/html/index.html
server3's page
server1:
vim /etc/varnish/default.vcl
#定义多个不同域名站点的后端服务器
backend web1 {
.host = "172.25.30.2";
.port = "80";
}
backend web2 {
.host = "172.25.30.3";
.port = "80";
} ##定义两个后端服务器,并设置http端口。
sub vcl_recv {
if (req.http.host ~"^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend_hint = web1; ##如果访问信息是以www.westos开头,或在以westos开头,
由后端服务器1为其服务。
}elsif (req.http.host ~"^bbs.westos.org") {
set req.backend_hint = web2; ##访问域名为bbs.westos.org,则由后端服务器2为其服务。
}else {
return (synth(405)); ##返回报错
}
}
systemctl restart varnish ##重启Varnish
客户端:
作本地解析
vim /etc/hosts
172.25.37.1 server1 bbs.westos.org www.westos.org westos.com
访问www.westos.org或者westos.org,server2提供服务,
访问bbs.westos.org,server3提供服务。
4.负载均衡
server1 代理:
vim /etc/varnish/default.vcl #注意末尾加’,‘!
import directors from "/usr/lib64/varnish/vmods/libvmod_directors.so"; #从提供调度的插件导入调度器
#find / -name vmods
#cd /usr/lib64/varnish/vmods 在该路径下找到调度插件
#定义多个不同域名站点的后端服务器
backend web1 { #后端服务器web1
.host = "172.25.37.2";
.port = "80";
}
backend web2 { #添加后端服务器web2
.host = "172.25.37.3";
.port = "80";
}
#man vmod_directors
sub vcl_init { #定义负载均衡
new lb = directors.round_robin();
lb.add_backend(web1);
lb.add_backend(web2);
}
#当访问 www.westos.org 域名时,转发作负载均衡,访问 bbs.westos.org 域名时到 web2 取数据,
访问其他页面报错 。
sub vcl_recv {
# Happens before we check if we have this in cache already.
#
# Typically you clean up the request here, removing cookies you don't need,
# rewriting the request, etc.
if (req.http.host ~ "^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend_hint = lb.backend(); #访问www.westos.org时作轮询
return (pass); #设置为不缓存,只为测试
} elsif (req.http.host ~ "^bbs.westos.org") {
set req.backend_hint = web2;
#访问bbs.westos.org时,转发给web2
} else {
return (synth(405));
}
}
systemctl restart varnish
客户端:
作本地解析
vim /etc/hosts
172.25.37.1 server1 bbs.westos.org www.westos.org
测试:
[kiosk@foundation37 ~]$ curl bbs.westos.org
server3
[kiosk@foundation37 ~]$ curl bbs.westos.org
server3
[kiosk@foundation37 ~]$ curl www.westos.org
server3
[kiosk@foundation37 ~]$ curl www.westos.org
server2
[kiosk@foundation37 ~]$ curl www.westos.org
server3
访问bbs.westos.org时,server3提供服务,
访问www.westos.org或westos.com,server2,server3轮流提供服务
5.上面实验结果中,由于在访问www.westos.org和bbs.westos.org时,有可能都是server3提供服务
为做区别,使不同域名访问不同的资源,server3做虚拟主机。
vim /etc/httpd/conf.d/vhost.conf
<VirtualHost *:80>
DocumentRoot /www
ServerName www.westos.org
</VirtualHost>
<Directory "/www">
Require all granted
</Directory> ##定义虚拟主机访问文件夹www
<VirtualHost *:80>
DocumentRoot /bbs
ServerName bbs.westos.org
</VirtualHost>
<Directory "/bbs">
Require all granted
</Directory> ##定义虚拟主机访问文件夹bbs
mkdir /bbs ##新建目录
mkdir /www
vim /bbs/index.html ##新建访问界面
server3.bbs
vim /www/index.html
server3.www
访问结果:
[kiosk@foundation37 ~]$ curl bbs.westos.org
server3.bbs
[kiosk@foundation37 ~]$ curl bbs.westos.org
server3.bbs
[kiosk@foundation37 ~]$ curl www.westos.org
server3.www
[kiosk@foundation37 ~]$ curl www.westos.org
server2
[kiosk@foundation37 ~]$ curl www.westos.org
server3.www
6.CDN推送管理
server1:
yum install unzip php httpd -y
unzip /mnt/bansys.zip -d /var/www/html #提供CDN推送管理图形界面
mv bansys/* /var/www/html/
vim /var/www/html/bansys/config.php
<?php
//varnish主机列表
//可定义多个主机列表
$var_group1 = array(
'host' => array('172.25.37.1'),
'port' => '8080',
);
//varnish群组定义
//对主机列表进行绑定
$VAR_CLUSTER = array(
'www.westos.com' => $var_group1,
);
//varnish版本
//2.x和3.x推送命令不一样
$VAR_VERSION = "3";
?>
修改apache监听端口
vim /etc/httpd/conf/httpd.conf
Listen 8080
systemctl restart httpd
做访问控制列表acl:
acl westos{
"127.0.0.1";
"172.25.37.0"/24;
}
if (req.method == "BAN") {
if (!client.ip ~ westos) {
return (synth(405,"Not allowed."));
}
ban("req.url ~ " + req.url);
return (purge);
}