缓存网络,ContentDeliveryNetwork,即内容分发网络;加速器,反向代理缓存
基本原理:广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。
尽可能避开互联网上有可能影响数据传输速度和稳定性的环节,使内容传输的更快、更稳定。通过放置节点服务器在现有的互联网基础之上形成一个智能虚拟网络。CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决Internet网络拥挤的状况,提高用户访问网站的响应速度。
内容分发网络(CDN)是一种新型网络构建方式,代表了一种基于质量与秩序的网络服务模式。包括分布式存储、负载均衡、网络请求的重定向和内容管理4个要件。
内容管理和全局的网络流量管理(Traffic Management)是CDN的核心所在。通过用户就近性和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务。
内容服务基于缓存服务器,也称作代理缓存(Surrogate),它位于网络的边缘,距用户仅有"一跳"(Single Hop)之遥。同时,代理缓存是内容提供商源服务器(通常位于CDN服务提供商的数据中心)的一个透明镜像。这样的架构使得CDN服务提供商能够代表他们客户,即内容供应商,向最终用户提供尽可能好的体验,而这些用户是不能容忍请求响应时间有任何延迟的。
Varnish是高性能开源的反向代理服务器和HTTP缓存服务器,Varnish的功能与Squid服务器相似,都可以用来做HTTP缓存。
Squid是从硬盘读取缓存的数据,而Varnish把数据存放在内存中,直接从读取内存,避免了频繁在内存、磁盘中交换文件,所以Varnish要相对更高效,但也有缺点,内存中的缓存在服务器重启后会丢失
varnish启动时会产生2个进程,一个由root开启(主进程),一个由varnish开启(子进程);主进程 fork 子进程,主进程等待子进程的信号,子进程退出后,主进程重新启动子进程。
子进程生成若干线程,具体对客户的请求进行处理:
Varnish 的master进程负责启动工作,master进程读取配置文件,根据指定的空间大小(例如管理员分配了2G内存)来创建存储空间,创建并管理child进程
child进程来处理后续任务,它会分配一些线程来执行不同的工作,例如:
http请求处理过程
Varnish的某个负责接受新HTTP连接的线程开始等待用户,如果有新的HTTP连接过来,它总负责接收,然后叫醒某个等待中的线程,并把具体的处理过程交给它。Worker线程读入HTTP请求的URI,查找已有的object,如果命中则直接返回并回复用户。如果没有命中,则需要将所请求的内容,从后端服务器中取过来,存到缓存中,然后再回复。
分配缓存过程
它根据所读到object的大小,创建相应大小的缓存文件。为了读写方便,程序会把每个object的大小变为最接近其大小的内存页面倍数。然后从现有的空闲存储结构体中查找,找到最合适的大小的空闲存储块,分配给它。如果空闲块没有用完,就把多余的内存另外组成一个空闲存储块,挂到管理结构体上。如果缓存已满,就根据LRU机制,把最旧的object释放掉
释放缓存的过程
有一个超时线程,检测缓存中所有object的生存期,如果超初设定的TTL(Time To Live)没有被访问,就删除之,并且释放相应的结构体及存储内存。注意释放时会检查该存储内存块前面或后面的空闲内存块,如果前面或后面的空闲内存和该释放内存是连续的,就将它们合并成更大一块内存
大部分其他的系统使用配置指令,让您打开或者关闭一些开关。 Varnish 使用区域配置语言,这种语言叫做“VCL”(varnish configuration language)。
VCL 语言是 varnish (HTTP 加速器)的一种限定域语言,目的在于规定请求的处理
和内容的缓存策略。
当一个新的配置文件被加载,varnish 管理进程把 vcl 转换成 c 代码,然后编译成动
态共享库连接到服务器进程。
安装 varnish 的系统需要 C 编译器,VCL 编译需要 C 编译器来完成。系统的 C 编译器把 VCL 编译成动态共享库,然后供varnish 使用。所以没有 C 编译器,varnish 不能运行。
在 VCL 中,有 3 个重要的数据结构:
VCL 支持以下运算符:
符号 | 运算 |
---|---|
= | 赋值运算 |
== | 对比 |
~ | 匹配,在 ACL 中和正则表达式中都可以用 |
! | 否定 |
&& | 逻辑或 |
|| |
逻辑非u |
VCL 文件被分为多个子程序,不同的子程序在不同的时间里执行,比如一个子程序在接到请求时执行,另一个子程序在接收到后端服务器传送的文件时执行。
varnish 将在不同阶段执行它的子程序代码,因为它的代码是一行一行执行的,不存在优先级问题。随时可以调用这个子程序中的功能并且当他执行完成后就退出。
子程序在 VCL 中没有参数,也没有返回值。调用一个子程序,使用子程序的关键字名字:
这里有很多子程序和 varnish 的工作流程相关。这些子程序会检查和操作 http 头文件和各种各样的请求。决定哪个哪些请求被使用。
vcl_recv
在请求开始的时候被调用,当一个完整的请求被接受到,并被解析,它的作用就是决定是否给这个请求提供服务,怎么服务,如果服务,哪个后端会被选取。
vcl_recv 子程序以下面的关键字结束:
error code [reason] \返回规定的代码给客户端,并终止请求。
pass \转换到 pass 模式,控制权会传递给 vcl_pass。
pipe \转换到 pipe 模式,控制权会传递给 vcl_pipe。
lookup \在 cache 中查找请求目标,控制权最终会传递给 vcl_hit 或者vcl_miss,取决于目标是否在 cache 中
vcl_pass
请求进入 pass 模式的时候被调用,在这个模式,请求会被 passed 到后端服务器,后端服务器的应答会被 passed 给客户端,但是不会被缓存。相同客户端的随后的请求正常处理。
vcl_pipe
请求进入 pipe 模式的时候被调用,在这个模式,请求会被 passed 到后端服务器,在连接关闭前,无论是这个客户端还是对应的后端服务器的数据,都会进入 pass 模式。
vcl_hit
当一个请求从 cache 中命中需要的内容,vcl_hit 子程序以下面关键字结束:
error code [reason] \返回规定的代码给客户端,并终止请求。
pass\继续进入 pass 模式,控制权转交 vcl_pass 子程序。
deliver \提交命中的目标给客户端,控制权转交 vcl_deliver 子程序
vcl_miss
当需要的内容没有在缓存中命中的时候被调用,决定是否尝试到后端服务器查找目标,从哪个后端服务器查找目标?vcl_miss 子程序以下面的关键字结束:
error code [reason] \返回规定的代码给客户端,并终止请求
pass \进入 pass 模式,控制权转交给 vcl_pass
fetch \从后端服务器获得请求目标,控制权转交给 vcl_fetch
vcl_fetch
目标成功从后端服务器中获取的时候被调用,vcl_fetch 子程序以下面的关键字结束:
error code [reason] \返回规定的代码给客户端,并终止请求
pass \进入 pass 模式,控制权转交给 vcl_pass
deliver \可能把找到的目标插入缓存中,然后发送给客户端,控制权转交给vcl_deliver
vcl_deliver
当一个没有被 cached 内容交付给客户端的时候被调用,vcl_deliver 子程序以下面关键字结束:
error code [reason] \返回规定的代码给客户端,并终止请求。
pass \进入 pass 模式,控制权转交给 vcl_pass
deliver \交付目标给客户端
准备环境:
为了实验的纯净性,已经实验的完整行,准备三台主机,并且全部关闭防火墙,调整selinux 为disabled
代理服务主机:172.25.18.2
后端资源服务器:172.25.18.3
用户主机: 172.25.18.4
可通过官网进行下载varnish包,然后进行安装。
2 代理服务器安装配置varnish
1 安装包:
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
[root@server1 varnish]#
yum install 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 -y # 对安装包以及其依赖进行安装
[root@server1 varnish]# rpm -qc varnish-4.0.5-1.el7.x86_64 # 查看varnish在系统中生成的文件
/etc/logrotate.d/varnish
/etc/varnish/default.vcl # varnish配置文件
/etc/varnish/varnish.params
当varnish下载完毕之后iu,系统会默认存在varnish用户
[root@lucky2 varnish]# id varnish
uid=997(varnish) gid=995(varnish) groups=995(varnish)
2 查看varnish的服务文件
vim /usr/lib/systemd/system/varnish.service
查看varnish服务中设定的最大开启文件数量以及锁定的内存大小:
Varnish打开的最大文件数限制为131072
Varnish锁定的共享内存大小为82M
3 查看本机系统最大文件访问数量,修改虚拟机内存大小
sysctl -a | grep file # 查看本机系统最大文件访问数量
由于系统最大文件访问数量不满足varnish要求,所以此时更改虚拟机配置,增加内存至2048M
4、全局临时更改共享文件及最大文件数
[root@lucky2 ~]# ulimit -n 131072 临时更改共享的文件最大数
[root@lucky2 ~]# ulimit -l 82 临时更改最大内存
[root@lucky2 ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 7273
max locked memory (kbytes, -l) 82 临时更改成功
max memory size (kbytes, -m) unlimited
open files (-n) 131072 临时更改成功
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 8192
cpu time (seconds, -t) unlimited
max user processes (-u) 7273
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
5 编辑varnish用户的限制文件(与varnish配置文件中限制相对应)
vim /etc/security/limits.conf # 编辑该文件,将最大文件访问数以及锁定的内存大小写入文件最后
6 varnish主配置文件中指定后端服务器:
vim /etc/varnish/default.vcl # 编辑varnish主配置文件
7 修改varnish服务端口:
root@server1 ~]# vim /etc/varnish/varnish.params ##在该文件中编辑更改端口为80
systemctl restart varnish # 重新启动varnish服务
后端资源服务器,安装http服务,在共享目录中编写共享文件。
[root@lucky3 ~]# yum install httpd -y
[root@lucky3 ~]# cd /var/www/html/
[root@lucky3 html]# vim index.html
[root@lucky3 html]# cat index.html
小鸡哔哔哟
[root@lucky3 html]# systemctl restart httpd
可以使用物理主机直接进行测试,得道里面所写的内容。
[root@foundation25 network-scripts]# curl 172.25.18.3
小鸡哔哔哟
[root@foundation25 network-scripts]# curl 172.25.18.3
小鸡哔哔哟
[root@foundation25 network-scripts]# curl 172.25.18.3
小鸡哔哔哟
作为varnish代理端,在配置文件中添加了后端服务器的ip及端口,在访问代理端的时候实际是在访问后端服务器,则第一次访问会产生缓存,下一次访问的时侯则由缓存服务器直接响应客户端需求,减少延时。
修改配置文件,在缓存数据时发送信息给客户端(查看缓存命中情况),根据数据是来自后端服务器还是来自缓存的内容,返回不同的消息给客户端主机。
[root@lucky2 2108]# vim /etc/varnish/default.vcl
vcl_deliver
在缓存数据将要发送到客户端时调用的子进程。
服务重启 [root@lucky2 varnish]# systemctl restart varnish
先清楚缓存,在进行测验
varnishadm ban req.url "~" / # 清理所有的缓存
varnishadm ban req.url "~" /index.html # 对指定文件的缓存进行清理
测试:当首次访问的时候,内容从后端服务器中提取,返回信息MISS from lcg cache,当再次访问相同的内容的时候,代理服务器上已经缓存内容,直接返回数据,返回信息HIT from lcg cache
先对varnish服务器的缓存进行清理:
[root@lucky2 varnish]# varnishadm ban req.url "~" /
[kiosk@foundation25 ~]$ curl -I 172.25.18.2
HTTP/1.1 200 OK
Date: Thu, 20 Jun 2019 07:25:05 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Last-Modified: Thu, 20 Jun 2019 07:12:00 GMT
ETag: "10-58bbc0fe074d0"
Content-Length: 16
Content-Type: text/html; charset=UTF-8
X-Varnish: 32782
Age: 0
Via: 1.1 varnish-v4
X-cache: MISS from lcg cache 第一次访问是没有的,
Connection: keep-alive
[kiosk@foundation25 ~]$ curl -I 172.25.18.2
HTTP/1.1 200 OK
Date: Thu, 20 Jun 2019 07:25:05 GMT
Server: Apache/2.4.6 (Red Hat Enterprise Linux)
Last-Modified: Thu, 20 Jun 2019 07:12:00 GMT
ETag: "10-58bbc0fe074d0"
Content-Length: 16
Content-Type: text/html; charset=UTF-8
X-Varnish: 17 32783
Age: 2
Via: 1.1 varnish-v4
X-Cache: HIT from lcg cache 第二次访问 因为已经有了缓存的,就是hit了
Connection: keep-alive
在使用不同的域名访问同一台代理服务器的时候,可以进行设置,将请求由发送到不同的后端服务器。
需要在代理服务器的varnish配置文件中设置多个后端服务器,并在vcl_recv 子程序中设置对不同的域名请求发送到不同的后端服务器。
vim /etc/varnish/default.vcl # 编辑配置文件
backend web1 { 后端服务器
.host = "172.25.18.3";
.port = "80";
}
backend web2 {
.host = "172.25.18.4"; 另一个后端服务器
.port = "80";
}
sub vcl_recv {
if (req.http.host ~"^(www.)?westos.org"){ #如果域名是以www.westos.org或者是westos.org
set req.http.host = "www.westos.org"; # 全部认定域名赋值为www.westos.org
set req.backend_hint =web1; # 将请求发送给web1 后端服务器
}elsif(req.http.host ~"^bbs.westos.org"){ #如果域名是 bbs.westos.orhg
set req.backend_hint = web2; #将请求发送给web2服务器
}else{
return(synth(405)); #如果都不是报405错误
}
}
物理主机中添加域名解析
[kiosk@foundation25 ~]$ vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.18.2 www.westos.org westos.org bbs.westos.org
[root@foundation25 kiosk]# curl www.westos.org
小鸡哔哔哟
[root@foundation25 kiosk]# curl westos.org
小鸡哔哔哟
[root@foundation25 kiosk]# curl bbs.westos.org
lucky4
当某台后端服务器的访问压力过大的时候,可以设置多台后端服务器,提供相同的内容服务,将客户请求分配给多台服务器,减缓一台服务器的压力。
可以把多台 backends 聚合成一个组,这些组被叫做 directors。这样可以增强性能和弹力
[root@lucky2 varnish]# vim /etc/varnish/default.vcl 配置varnish 主配置文件
import directors from "/usr/lib64/varnish/vmods/libvmod_directors.so";
backend web1 {
.host = "172.25.18.3";
.port = "80"; 定义第一个后端服务器
}
backend web2 {
.host = "172.25.18.4";
.port = "80"; 定义定二个后端服务器
}
sub vcl_init {
new lb =directors.round_robin(); 新建一个组
lb.add_backend(web1); 将web1 放到这个组
lb.add_backend(web2); 将web2 放到这个组
}
sub vcl_recv {
if (req.http.host ~"^(www.)?westos.org"){
set req.http.host = "www.westos.org";
set req.backend_hint =lb.backend(); # 发送请求循环组,让组中的后端服务器轮流处理请求
return (pass); 设置直接将请求发送到后端服务器,并且不缓存返回的内容,如果进行缓存,再次访问的时候就会直接从缓存中提取内容,轮询的效果就不明显
}elsif(req.http.host ~"^bbs.westos.org"){
set req.backend_hint = web2;
}else{
return(synth(405));
}
}
round_robin()
这个 director 是一个循环的 director。它的含义就是 director 使用循环的方式把backends 分给请求。
测试:
为了效果明显,在web1和web2中设置的内容不一致,实际应用中,这两台服务器中提供的内容服务应该一致。由此达到负载均衡的目的
[root@foundation25 kiosk]# curl www.westos.org
小鸡哔哔哟
[root@foundation25 kiosk]# curl www.westos.org
lucky4
[root@foundation25 kiosk]# curl www.westos.org
小鸡哔哔哟
[root@foundation25 kiosk]# curl www.westos.org
lucky4
[root@foundation25 kiosk]# curl www.westos.org
小鸡哔哔哟
[root@foundation25 kiosk]# curl www.westos.org
lucky4
五 可以在后端服务上设置虚拟主机,当不同的域名被发送到同一个后端服务器,可以让其访问不同的内容。
后端服务器设置:
[root@lucky4 html]# vim /etc/httpd/conf.d/vhost.conf
DocumentRoot /www
servername www.westos.org
Require all granted
DocumentRoot /bbs
servername bbs.westos.org
Require all granted
查看不同的主机设置不同的内容
[root@lucky4 ~]# cat /www/index.html
www.westos.org
[root@lucky4 ~]# cat /bbs/index.html
bbs.westos.org
测试:需要提前在物理主机中做好本地域名解析
目前:www.westos.org 域名会轮流在web1 和web2 之间进行轮换,bbs.westos.org 一直被发送给为web2
[root@foundation25 kiosk]# curl www.westos.org
www.westos.org
[root@foundation25 kiosk]# curl www.westos.org
小鸡哔哔哟
[root@foundation25 kiosk]# curl www.westos.org
www.westos.org
[root@foundation25 kiosk]# curl bbs.westos.org
bbs.westos.org
[root@foundation25 kiosk]# curl bbs.westos.org
bbs.westos.org
[root@foundation25 kiosk]# curl bbs.westos.org
bbs.westos.org
为了更加快捷方便及时对代理服务器中缓存内容进行清理更新。可以在代理服务器上设置网络推送页面,直接在网页上推送平台对代理服务器缓存进行修改。
1 代理服务器上安装php 以及http
由于推送平台使用的是php进行编写,需要安装php插件识别php脚本内容。
yum install php httpd -y
更改http端口为8080,80默认端口已经被varnish占用,当以相同断空进行访问时会因为端口冲突而失败。修改完成后启动httpd服务。
2 解压平台安装包到httpd公共目录里
[root@lucky2 html]# unzip bansys.zip -d /var/www/html/ 将压缩包解压到公共目录中
[root@lucky2 varnish]# cd /var/www/html/
[root@lucky2 html]# ls
bansys
[root@lucky2 varnish]# cd /var/www/html/
[root@lucky2 html]# ls
bansys
[root@lucky2 html]# mv bansys/* /var/www/html/ 将目录下的文件移动到公共目录中方便人们查看
[root@lucky2 html]# ls
bansys class_socket.php config.php index.php purge_action.php static
修改httpd端口为i8080
[root@lucky2 html]# vim /etc/httpd/conf/httpd.conf
[root@lucky2 html]# systemctl restart httpd
[root@lucky2 html]# vim config.php
重启服务
[root@lucky2 html]# systemctl restart varnish
5 客户端进行测试:http://172.25.47.110:8080/