CDN
内容分发网络(Content Delivery Network,简称 CDN),将源内容同步到全国各边缘节点,配合精准的调度系统,将用户的请求分配至最适合他的节点,使用户可以以最快的速度取得他所需的内容,解决网络带宽小、用户访问量大、网点分布不均等问题,提高用户访问的响应速度。
工作原理
CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
cdn 高速缓存器 varnish服务器
Varnish
Varnish 是一款高性能且开源的反向代理服务器和 HTTP 加速器,其采用全新的软件体系机构,和现在的硬件体系紧密配合,与传统的squid 相比,varnish 具有性能更高、速度更快、管理更加方便等诸多优点,很多大型的网站都开始尝试使用 varnish 来替换 squid,这些都促进varnish 迅速发展起来
varnish 工作原理
用户通过浏览器访问http服务器,但是需要先经过http加速器varnish服务器,如果用户访问的内容在varnish的cache中,则直接从varnish服务器返回该访问内容,但是如果不再varnish的cache中,就先从后端的http服务器中取出用户需要访问的内容,并保存在varnish的cache中,以便下次的访问。
varnish的状态引擎(state engine)
说道varnish的状态引擎,不得不说vcl(Varnish Configuration Language:varnish配置缓存策略的工具)。它是基于域的一种简单的编程语言,支持算数运算、允许使用正则表达式、支持if语句等。使用vcl语言编写的缓存策略通常保存于.vcl文件中,其需要编译成二进制的格式后才能由varnish调用。
VCL用于让管理员定义缓存策略,而定义好的策略将由varnish的management进程分析、转换成C代码、编译成二进制程序并连接至child进程。varnish内部有几个所谓的状态(state),在这些状态上可以附加通过VCL定义的策略以完成相应的缓存处理机制,因此VCL也经常被称作“域专用”语言或状态引擎,“域专用”指的是有些数据仅出现于特定的状态中。
具体的状态的是通过定义内置函数来实现的,具体过程如下图:
varnish的反向代理实现
二、Varnish反向代理实现
实验环境:
server1: varnish (172.25.254.1)
server2: 后端Apache服务器(172.25.254.2)
server3: 测试机(172.25.254.3)
varnish下载
1.阿里巴巴开源镜像站下载 网址:http://mirrors.aliyun.com/
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
jemalloc-devel-3.6.0-1.el7.x86_64.rpm
安装上面四个包即可
varnish 主配置文件:/etc/varnish/default.vcl
优化varnish
为了使varnish工作在最优状态下,varnish要求(在/usr/lib/systemd/system/varnish.service
文件中查看):
- 系统中最大打开文件数为131072
- 其需要锁定的内存空间是82M
因此需要进行如下操作:
查看系统最大文件数:
[root@server1 ~]# sysctl -a | grep file
fs.file-max = 47100
fs.file-nr = 960 0 47100
fs.xfs.filestream_centisecs = 3000
达不到要求的文件数,因此首先需要增大虚拟机的内存,增大虚拟机的内存后即可实现:
[root@server1 ~]# sysctl -a | grep file
fs.file-max = 149289 #大于131072
fs.file-nr = 1056 0 149289
fs.xfs.filestream_centisecs = 3000
之后修改系统限制文件:
vim /etc/security/limits.conf
写入:
62 varnish - nofile 131072
63 varnish - memlock 82000
实现varnish反向代理
实验环境:
server1: varnish (172.25.254.1)
server2: 后端Apache服务器(172.25.254.2)
server3: 测试机(172.25.254.3)
1.修改varnish主配置文件
在server1:
vim /etc/varnish/default.vcl
修改:
17 backend web1 {
18 .host = "172.25.254.2"; #web服务器ip
19 .port = "80"; #Apache端口
20 }
2.配置web服务器
在server2安装apache并编写测试页:
[root@server2 ~]# yum install httpd -y
[root@server2 ~]# cd /var/www/html/
[root@server2 html]# vim index.html
[root@server2 html]# cat index.html
server2
[root@server2 ~]# systemctl start httpd
3.修改varnish端口
用户访问web服务器也是80端口,若要做反向代理,即表示用户访问varnish服务器是80端口。故需要更改varnish端口:
在server1:
[root@server1 varnish]# ls
default.vcl secret varnish.params
[root@server1 varnish]# vim varnish.params
VARNISH_LISTEN_PORT=80
4.打开varnish
在server1:
[root@server1 ~]# systemctl start varnish
查看开启端口:
[root@server1 ~]# netstat -antlupe | grep varnish
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 0 42013 2742/varnishd
tcp 0 0 127.0.0.1:6082 0.0.0.0:* LISTEN 0 42075 2742/varnishd
tcp6 0 0 :::80 :::* LISTEN 0 42014 2742/varnishd
tcp6 0 0 ::1:6082 :::* LISTEN 0 42074 2742/varnishd
5.测试
在客户端(server3):
[root@server3 ~]# curl -I server1
HTTP/1.1 200 OK
Date: Tue, 25 Aug 2020 01:33:56 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Last-Modified: Fri, 07 Aug 2020 07:45:47 GMT
ETag: "8-5ac44cb07c487"
Content-Length: 8
Content-Type: text/html; charset=UTF-8
X-Varnish: 2
Age: 0
Via: 1.1 varnish-v4
Connection: keep-alive
[root@server3 ~]# curl -I server1
HTTP/1.1 200 OK
Date: Tue, 25 Aug 2020 01:33:56 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Last-Modified: Fri, 07 Aug 2020 07:45:47 GMT
ETag: "8-5ac44cb07c487"
Content-Length: 8
Content-Type: text/html; charset=UTF-8
X-Varnish: 5 3
Age: 8
Via: 1.1 varnish-v4
Connection: keep-alive
[root@server3 ~]# curl server2
server2
[root@server3 ~]# curl server1
server2
反向代理成功实现
三.判断是否加速
在varnish服务器主配置文件vcl_deliver
模块中写入:
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 redhat cache";
}
else {
set resp.http.X-Cache = "MISS from redhat cache";
}
return(deliver);
}
测试:
[root@server3 ~]# curl -I server1
HTTP/1.1 200 OK
Date: Tue, 25 Aug 2020 01:52:26 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Last-Modified: Fri, 07 Aug 2020 07:45:47 GMT
ETag: "8-5ac44cb07c487"
Content-Length: 8
Content-Type: text/html; charset=UTF-8
X-Varnish: 2
Age: 0
Via: 1.1 varnish-v4
X-Cache: MISS from redhat cache
Connection: keep-alive
[root@server3 ~]# curl -I server1
HTTP/1.1 200 OK
Date: Tue, 25 Aug 2020 01:52:26 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Last-Modified: Fri, 07 Aug 2020 07:45:47 GMT
ETag: "8-5ac44cb07c487"
Content-Length: 8
Content-Type: text/html; charset=UTF-8
X-Varnish: 5 3
Age: 4
Via: 1.1 varnish-v4
X-Cache: HIT from redhat cache
Connection: keep-alive
四、varnish缓存清除
1.命令
[root@server1 ~]# varnishadm ban req.url "~" / #清除所有
[root@server1 ~]# varnishadm ban req.url "~" /index.html #清除指定页面
ban
表示清理缓存中满足表达式的对象
2.使用varnish操作界面
[root@server1 ~]# varnishadm
200
-----------------------------
Varnish Cache CLI 1.0
-----------------------------
Linux,3.10.0-514.el7.x86_64,x86_64,-junix,-smalloc,-sdefault,-hcritbit
varnish-6.3.1 revision 6e96ff048692235e64565211a38c41432a26c055
Type 'help' for command list.
Type 'quit' to close CLI session.
varnish> ban req.url ~ "/index.html" #清除缓存
200
varnish> quit
500
Closing CLI connection
五、varnish负载均衡实现
1.实验环境:
主机名:server1
:varnish服务器,ip:172.25.254.1
主机名:server2
:web1网站服务器 ip:172.25.254.2,
主机名:server4
:web2网站服务器 ip:172.25.254.4,
物理机(客户端server4
)
在server1中:
[root@server1 ~]# vim /etc/varnish/default.vcl
17 backend web1 {
18 .host = "172.25.63.2";
19 .port = "80";
20 }
21
22 backend web2 {
23 .host = "172.25.254.4";
24 .port = "80";
25 }
2.配置web2服务器
在server4安装nginx并编写测试页:
3.编写rev_recv
模块:
[root@server1 ~]# vim /etc/varnish/default.vcl
38 sub vcl_recv {
39 # Happens before we check if we have this in cache already.
40 #
41 # Typically you clean up the request here, removing cookies you don't ne ed,
42 # rewriting the request, etc.
43 if (req.http.host ~ "^(www.)?westos.org") {
44 set req.http.host = "www.westos.org";
45 set req.backend_hint = web1;
46
47 } elsif (req.http.host ~ "^bbs.westos.org") {
48 set req.backend_hint = web2;
49 } else {
50 return (synth(405));
51 }
52 }
此时,在客户端进行测试:
[root@server3 ~]# curl bbs.westos.org
server4
[root@server3 ~]# curl www.westos.org
server2
4.varnish负载均衡的配置
[root@server1 ~]# vim /etc/varnish/default.vcl
vcl 4.0;
import directors; ##添加模块
sub vcl_init { ##把多个后端聚合为一个组
new web_cluster = directors.round_robin();
web_cluster.add_backend(web1);
web_cluster.add_backend(web2);
}
if (req.http.host ~ "^(www.)?westos.org") {
set req.http.host = "www.westos.org";
set req.backend_hint = web_cluster.backend(); ##把web1修改为
return(pass); ##添加轮询
}
在server4的nginx配置文件中 添加一个虚拟主机
server {
listen 80;
server_name bbs.westos.org;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://172.25.254.3;
}
}
上述的负载均衡无健康检查机制
健康检测
probe backend_healthcheck { #probe:定义健康状态检测方法
.url = "/index.html"; #哪个 url 需要 varnish 请求
.window = 3; #window:基于最近的多少次检查来判断其健康状态;
.threshold = 2;
#threshhold:最近.window中定义的这么次检查中至有.threshhold定义的次数是成功的;
.interval = 3s; #interval:检测频度;
}
backend web1 {
.host = "172.25.13.250";
.port = "80";
.probe = backend_healthcheck;
}
backend web2 {
.host = "172.25.13.3";
.port = "80";
.probe = backend_healthcheck;
}
down掉一个也不会访问失败