CDN:content distribute network(内容分发网络)或者content delivery network(内容交付网络)。CDN的任务是将内容从源站传递给用户。
CDN是构建在现有网络基础之上的智能虚拟网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。
1.用户在浏览器输入URL
2.浏览器向本地DNS请求域名解析
3.如果本地DNS缓存有该域名的解析结果,则直接将解析结果返回给浏览器
4.如果本地DNS缓存中无该域名的解析结果,则以递归方式向整个DNS系统请求域名解析,在获得应答后将解析结果返回给浏览器
5.浏览器获得解析结果,提取出IP信息,使用IP向服务器请求数据
6.服务器返回数据给浏览器
1.用户在浏览器中输入URL
2.浏览器向本地DNS请求域名解析,DNS会将域名解析权转交给CNAME指向的CDN专用的DNS服务器
3.CDN专用的DNS服务器将CDN的全局负载均衡设备的IP返回给浏览器
4.浏览器向CDN全局负载均衡设备发起URL请求
5.CDN全局负载均衡设备根据请求的URL和用户的IP地址,将用户请求转发到用户所在区域的区域负载均衡设备
6.区域负载均衡设备,根据用户IP、请求URL、缓存服务器的负载情况等,返回一台合适的服务器IP给用户
7.用户向缓存服务器发起请求
8.缓存服务器响应用户请求,如果用户请求的内容缓存服务器上不存在,则缓存服务器要向上一级缓存服务器请求内容,直到追溯到网站的源服务器
varnish是一个反向HTTP代理,有时称为HTTP加速器或web加速器。
varnish将文件或文件片段储存在内存中,使他们能够快速被提供。
varnish本质上是一个键/值存储,它通常使用url作为键。
varnish是为现代硬件、现在操作系统和现代工作负载而设计的。
仅仅作为一个代理服务器:帮客户端去问服务端要数据,要回来的数据直接给客户端自己不缓存一份,这种情况是客户的隐私信息、热点信息、更新比较快的数据,不缓存,只代理。
既代理又缓存:帮客户端去问服务端要数据,要回来的数据先给自己缓存一份,然后再发给客户端,这种情况是用于更新比较慢的数据,此时varnish既代理又缓存。
Varnish 主要存在两个进程:manage 进程及 child 进程,其中:
manage 进程:更新配置,vcl 文件编译,varnish 监控,初始化 varnish 及提供 varnish 管理接口。
child 进程:主要进行请求任务的处理,接受请求等。
vcl 的处理流程,主要是由 Varnish 的状态机决定,可以通过 vcl 配置文件来对 varnish 状态机各个步骤所做的操作进行配置。
其中的各个状态介绍:
vcl_recv:
vcl_recv 是 http 请求到达后进入的第一个状态,在这个状态中,可以对请求进行以下的一些处理:
- 修改 client 请求,以减少缓存决策时的差异性。
- 根据 client 请求,决定缓存策略。
- 重定向请求 。
- 决定处理请求的 backend(即后端 webserver )。
在 vcl_recv 可以进入 vcl_pass, vcl_pipe,vcl_lookup,vcl_error。
vcl_pipe:
若连接存活期间其请求被 vcl_recv 传递至 vcl_pipe ,那么这请求后的所有请求,将直接经 vcl_recv 到达 backend,varnish 不再查找,及存储及请求的对象,就如同 client 与 backend 直接通信一样, 不会记录任何通信的日志。
vcl_pass:
进入 vcl_pass 的请求,请求会直接发送至 backend , 但不会缓存, 可进入 restart , 会增加 restart 计数。
vcl_hash:
根据请求的特征,构建 hash 值,通常是以 host+url 的形式建立 Hash 值,可进入 vcl_hit 及 vcl_miss 。
vcl_hit:
可进入 vcl_pass 及v cl_deliver,vcl_restart。
vcl_miss:
可进入 vcl_pass 及 vcl_fetch,vcl_restart。
vcl_fetch:
将请求传递至 backend, 决定是是否缓存,可进入 hit_for_pass: 仅vcl_fetch 可进入,与 pass 功能类似,不过其会利用 beresp 建立一个 hitforpass 对象,以防止同一对象被缓存,在 hitforpass 对象存在期间,同一请求的结果都不会被缓存,请求会直接进入 pass。
vcl_deliver:
在缓存数据将要发送到客户端时调用。
deliver:缓存取到的对象,并发送至服务端,也可进入 restart , 增加 restart 计数,当 restart 计数大于 max_restarts 时会报错。
vcl_error:
出错时调用,以上的各状态通常情况下都可进入 vcl_error。
实验环境:
1.在所有实验机中需要关闭火墙,selinux,NetworkManager 避免影响。
systemctl stop NetworkManager
systemctl disable NetworkManager
systemctl stop firewalld.service
systemctl disable firewalld.servicevim
vim /etc/sysconfig/selinux ##关闭selinux
2.使用一个虚拟机server1作为varnish代理服务器。
3.在server2上作为CDN转交请求的对象,安装httpd。
echo www.westos.com > /var/www/html/index.html
systemctl restart httpd
4.在serverc上作为CDN转交请求的对象,安装httpd。
echo bbs.westos.com > /var/www/html/index.html
systemctl restart httpd
5.在rhel7主机充当用户访问。
vim /etc/hosts ##编写主机解析
192.168.43.11 www.westos.com bbs.westos.com
安装varnish:
安装varnish以及依赖性:
yum install -y jemalloc-3.6.0-1.el7.x86_64.rpm jemalloc-devel-3.6.0-1.el7.x86_64.rpm varnish-4.0.5-1.el7.x86_64.rpm
1.查看varnish中允许的最大文件数和内存
vim /usr/lib/systemd/system/varnish.service
2.检查系统允许的最大文件数和内存
注意:检查系统允许打开的最大文件数和内存需要大于varnish中允许端最大文件数。
sysctl -a | grep file
如果系统允许的最大文件数少于varnish中的最大文件数可以通过给系统增加内存的方式。
ulimit -a
3.使系统允许varnish需要的运行内存和最大文件数
vim /etc/security/limits.conf
4.varnish的启动
systemctl start varnish
启动varnish
ss -antlp
检查端口是否打开
vim /etc/varnish/varnish.params
14 VARNISH_LISTEN_PORT=80
varnish的配置文件 :/etc/varnish/default.vcl
[root@server1 ~]# rpm -qa | grep varnish
varnish-libs-4.0.5-1.el7.x86_64
varnish-4.0.5-1.el7.x86_64
[root@server1 ~]# rpm -qc varnish-4.0.5-1.el7.x86_64
/etc/logrotate.d/varnish
/etc/varnish/default.vcl
/etc/varnish/varnish.params
vim /etc/varnish/default.vcl
修改CDN配置文件
# 4.0 or 4.1 syntax.
vcl 4.1;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.43.22";
.port = "80";
}
systemctl restart varnish
vim /etc/varnish/default.vcl
修改CDN配置文件
vcl 4.1;
# Default backend definition. Set this to point to your content server.
backend default {
.host = "192.168.43.22";
.port = "80";
}
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from CDN cache";
}
else {
set resp.http.X-Cache = "MISS from CDN cache";
}
return (deliver);
}
实验环境:
主机名:server1:varnish服务器,ip:192.168.43.11
主机名:server2:web1网站服务器 ip:192.168.43.22
主机名:server4:web2网站服务器 ip:192.168.43.33
1.在server1中:
vim /etc/varnish/default.vcl
修改CDN配置文件
vcl 4.1;
import directors;导入模块
#请求不同域名(同一IP),分配不同后端
backend web1 {
.host = "192.168.43.22";
.port = "80";
}
backend web2 {
.host = "192.168.43.33";
.port = "80";
}
sub vcl_init {
new lb = directors.round_robin();
lb.add_backend(web1);
lb.add_backend(web2);
}
sub vcl_recv {
if (req.http.hosts ~ "^(www.)?westos.com"){
set req.http.host = "www.westos.com";
set req.backend_hint = web1;
}
elsif (req.http.host ~ "^bbs.westos.com"){
set req.backend_hint = web2;
}
else {
return (synth(404,"Not in cache"));
}
}
2.在server3中配置nginx并写入页面server333
[root@server3 nginx-1.18.0]# ls
auto CHANGES.ru configure html man src
CHANGES conf contrib LICENSE README
[root@server4 nginx-1.18.0]# ./configure --prefix=/usr/local/nginx/ --with-http_ssl_module --with-http_realip_module
注意上面编译时加入的模块,下面要用到
3.此时,在客户端进行测试:先写入主机解析
vim /etc/hosts
192.158.43.11 server1 www.westos.com bbs.westos.com
# curl www,westos.com
server222
# curl bbs.westos.com
server333
4.配置健康检查
probe backend_healthcheck {
.url = "/index.html";##用于测试是否存活
.window = 3;#window:基于最近的多少次检查来判断其健康状态
.threshold = 2;#threshhold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的;
.interval = 3s;
}
backend web1 {
.host = "192.168.43.22";
.port = "80";
.probe = backend_healthcheck;
}
backend web2 {
.host = "192.168.43.33";
.port = "80";
.probe = backend_healthcheck;
}
5.server3中nginx的配置文件
server {
listen 80;
server_name bbs.westos.com;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.43.33
}
}
测试:
访问www.westos.com会实现轮询
如果关闭server2的htttpd,仅能访问到server3
重新开启server2的httpd,可以重新轮询