cdn的技术原理及用varnish简单实现(实验)

cdn的技术原理:

CDN的全称是Content Delivery Network,即内容分发网络。其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上。其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。 CDN的实现需要依赖多种网络技术的支持,其中负载均衡技术、动态内容分发与复制技术、缓存技术是比较主要的几个。

通常网络访问中会有"三公里"路程

第一公里为:源站到ISP接入点
第二公里为:源站ISP接入点到访问用户的ISP接入点
第三公里(最后一公里)为:用户ISP接入点到用户客户端

第一公里的耗时取决于源站自身响应能力和出口带宽
第二公里的耗时取决于从源站的接入点到最终用户的接入点之间的传输路径,主要为网络运营商之间的互连瓶颈问题,不同地区骨干网之间的数据交换、传输,会导致传输途中的路由阻塞和延迟
第三公里的耗时取决于最终用户接入Internet的方式,会越来越快,以后不会是瓶颈

而CDN网络层主要用来加速第二公里,怎么加速呢?原理并不难,下面简单介绍下:
首先看下访问网站的一个普通流程
cdn的技术原理及用varnish简单实现(实验)

再看下有CDN层的访问流程
cdn的技术原理及用varnish简单实现(实验)
负载均衡集群扮演的角色很重要,它是一个CDN网络的神经中枢,主要功能是负责对所有发起服务请求的用户进行访问调度,确定提供给用户的最终实际访问地址(即哪一台边缘Cache机).大多数CDN系统的负载均衡系统是分级实现的.一般而言,两级调度体系分为全局负载均衡(GSLB)和本地负载均衡(SLB).其中,全局负载均衡(GSLB)主要根据用户就近性原则,通过对每个服务节点进行"最优"判断,确定向用户提供服务的Cache的物理位置.最通用的 GSLB实现方法是基于DNS解析的方式实现,也有一些系统采用了应用层重定向等方式来解决.本地负载均衡(SLB)主要负责节点内部的设备负载均衡,当用户请求从GSLB调度到SLB时,SLB会根据节点内各Cache设备的实际能力或内容分布等因素对用户进行重定向,常用的本地负载均衡方法有基于4层调度(常用的LVS)、基于7层调度(常用的nginx)、链路负载调度(只能DNS)等.

源站WEB服务器内容到CDN边缘节点集群主要用两种内容分发技术:PUSH和PULL.PUSH即主动分发.通常由CDN厂商的内容管理系统发起(主动刷新),将内容从源或者中心资源库分发到各边缘的Cache节点.而PULL是被动分发.通常由用户请求驱动.当用户请求的内容在本地的边缘Cache上不存在(未命中)时,Cache启动PULL方法从源站或者其他CDN节点即时获取内容.

而CDN的好处不止是加速,还可以有效地降低源站负载,降低高额的带宽成本(不必按峰值带宽直接向ISP购买带宽),防止DDOS等攻击。

Varnish介绍:

varnish是一款高性能的开源HTTP加速器,具有反向代理,缓存的功能。

处理过程大致分为如下几个步骤:

Receive 状态,也就是请求处理的入口状态,根据 VCL 规则判断该请求应该是 Pass 或 Pipe,或者进入
Lookup(本地查询)。 Lookup 状态,进入此状态后,会在 hash 表中查找数据,若找到,则进入 Hit 状态,否则进入 miss
状态。
Pass 状态,在此状态下,会进入后端请求,即进入 fetch 状态。
Fetch 状态,在 Fetch状态下,对请求进行后端的获取,发送请求,获得数据,并进行本地的存储。
Deliver 状态, 将获取到的数据发送给客户端,然后完成本次请求。

用varniash简单实现cdn加速:

安装软件

在官网下载varnish-libs-3.0.5-1.el6.x86_64.rpm和varnish-3.0.5-1.el6.x86_64.rpm

首先将我varnish的安装包(scp /home/kiosk/Desktop/varnish-* [email protected]????)拷到我们的提供varnish服务的虚拟机上(server1):

[[email protected] yum.repos.d]# yum install varnish-3.0.5-1.el6.x86_64.rpm 
varnish-libs-3.0.5-1.el6.x86_64.rpm -y		#安装
#安装完成后,在系统的/etc/passwd中生成varnish用户,对varnish的访问控制实质上是对varnish用户的控制实现的
[[email protected] ~]# rpm -qc varnish-3.0.5-1.el6.x86_64		#查看发布目录
/etc/logrotate.d/varnish
/etc/sysconfig/varnish
/etc/varnish/default.vcl

配置 varnish 服务端口

[[email protected] ~]# vim /etc/sysconfig/varnish
8 NFILES=131072 # 最多能打开的文件数,varnish会自动调整该值
12 MEMLOCK=82000 # 最多能使用的内存空间,varnish会自动调整该值
15 NPROCS=“unlimited” # 单个用户所能运行的最大线程数
66 VARNISH_LISTEN_PORT=80 #修改端口
cdn的技术原理及用varnish简单实现(实验)

修改varnish用户的限制文件

因为varnish这个程序运行在varnish这个用户的私有空间内,内核对普通用户限制的最大文件数为 1024.对varnish用户限制的最大文件数为131072,我们需要满足131072这个最大值。

[[email protected] ~]# vim /etc/security/limits.conf 
#End of file
varnish         -       nofile          131072			#这3行添加到末尾去
varnish         -       memlock         82000
varnish         -       nproc           unlimited

但是使用sysctl -a | grep file 是98864 ,但是server1没有这么多,我们需要给该虚拟机家内存。
[[email protected] ~]# sysctl -a | grep file
fs.file-nr = 448 0 98865
fs.file-max = 98865
修改方式:
(1) poweroff关闭server1
(2)进入虚拟机管理截面,点击小灯泡:将memory改成2048
cdn的技术原理及用varnish简单实现(实验)
开启server1重新ssh连接sysctl -a | grep file 看到最大文件数是188464
[[email protected] ~]# sysctl -a | grep file
fs.file-nr = 448 0 188464
fs.file-max = 188464

配置一台后端服务器

先修改varnish的默认配置文件

[[email protected] ~]# vim /etc/varnish/default.vcl
backend default {
  .host = "172.25.254.2";
  .port = "80";
}

开启服务,编写配置文件后要重新加载默认文件

[[email protected] ~]# /etc/init.d/varnish start
Starting Varnish Cache:                                    [  OK  ]
[[email protected] ~]# /etc/init.d/varnish reload
Loading vcl from /etc/varnish/default.vcl
Current running config name is boot
Using new config name reload_2019-04-17T18:32:34
VCL compiled.

available       0 boot
active          0 reload_2019-04-17T18:32:34

Done

配置后端(在server2上安装apache服务)

[[email protected] yum.repos.d]# yum install httpd -y
[[email protected] yum.repos.d]# cd /var/www/html/
[[email protected] html]# vim index.html
[[email protected] html]# cat index.html 
<h1>server2.example.com</h1>
[[email protected] html]# /etc/init.d/httpd start
Starting httpd: httpd: apr_sockaddr_info_get() failed for server2.localdomain
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
  • 测试:

    现在在真机上curl 172.25.254.1访问到的是server2的内容
    [[email protected] ~]# curl 172.25.254.1

    server2.example.com

    在浏览器上搜172.25.254.1也是server2的内容

清除cdn缓存

1.辑配置文件,查看缓存命中情况

[ [email protected] ~]# vim /etc/varnish/default.vcl
backend default {
  .host = "172.25.254.2";
  .port = "80";
}
 
sub vcl_deliver {
if (obj.hits > 0) {
set resp.http.X-Cache = "HIT from server2.cache";
}                        # 在varnish中命中HIT访问的域名
else {
set resp.http.X-Cache = "MISS from server2cache";
}                        # 后端服务器中得到MISS访问的域名
return (deliver);
}

修改完后重新加载配置文件
[[email protected] ~]# /etc/init.d/varnish reload

  • 测试(用物理机)
    第一次没有缓存到,则miss
    [[email protected] ~]# curl -I 172.25.254.1
    HTTP/1.1 200 OK
    Server: Apache/2.2.15 (Red Hat)
    Last-Modified: Wed, 17 Apr 2019 10:36:02 GMT
    ETag: “5f3c5-1d-586b773bf6abe”
    Content-Type: text/html; charset=UTF-8
    Content-Length: 29
    Accept-Ranges: bytes
    Date: Wed, 17 Apr 2019 10:48:23 GMT
    X-Varnish: 1234931996
    Age: 0
    Via: 1.1 varnish
    Connection: keep-alive
    X-Cache: MISS from westos cache
    第二次缓存到了,则hit,之后一直都是hit
    [[email protected] ~]# curl -I 172.25.254.1
    HTTP/1.1 200 OK
    Server: Apache/2.2.15 (Red Hat)
    Last-Modified: Wed, 17 Apr 2019 10:36:02 GMT
    ETag: “5f3c5-1d-586b773bf6abe”
    Content-Type: text/html; charset=UTF-8
    Content-Length: 29
    Accept-Ranges: bytes
    Date: Wed, 17 Apr 2019 10:48:31 GMT
    X-Varnish: 1234931997 1234931996
    Age: 7
    Via: 1.1 varnish
    Connection: keep-alive
    X-Cache: HIT from westos cache
  • 清除缓存的命令(在server1清除)
    [[email protected] ~]# varnishadm ban.url .*$ ##清除所有缓存
    [[email protected] ~]# varnishadm ban.url /index.html ##清除网页的缓存
    [[email protected] ~]# varnishadm ban.url /admin/$ ##清除admin 目录缓存
  • 显示miss,则清除缓存成功(否则为hit)
    [[email protected] ~]# curl -I 172.25.254.1
    HTTP/1.1 200 OK
    Server: Apache/2.2.15 (Red Hat)
    Last-Modified: Wed, 17 Apr 2019 10:36:02 GMT
    ETag: “5f3c5-1d-586b773bf6abe”
    Content-Type: text/html; charset=UTF-8
    Content-Length: 29
    Accept-Ranges: bytes
    Date: Wed, 17 Apr 2019 10:53:50 GMT
    X-Varnish: 1234931998
    Age: 0
    Via: 1.1 varnish
    Connection: keep-alive
    X-Cache:MISS from westos cache

CDN加速的实现(多个后端服务器实现负载均衡)

部署varnish服务

[[email protected] ~]# vim /etc/varnish/default.vcl
backend web1 {
  .host = "172.25.254.2";
  .port = "80";
}

backend web1 {
  .host = "172.25.254.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";
}
}

##当访问www.westos.org域名时从web1上取数据,当访问bbs.westos.org域名时从web2上取数据

重新加载配置文件
[[email protected] ~]# /etc/init.d/varnish reload
[[email protected] ~]# /etc/init.d/varnish restart
增加后端server3(同server2)

物理机中的访问测试(需要先写本地解析)

[[email protected] ~]# curl bbs.westos.org
<h1>server3.example.com</h1>
[[email protected] ~]# curl www.westos.org
<h1>server2.example.com</h1>

一台主机多个解析(虚拟主机)

在server3的httpd的默认发布目录中建立两个虚拟主机
[[email protected] html]# vim /etc/httpd/conf/httpd.conf
#在文章末尾添加这两个模块
<VirtualHost *:80>
DocumentRoot /www
ServerName www.westos.org

<VirtualHost *:80>
DocumentRoot /bbs
ServerName bbs.westos.org

创建目录/www 和/bbs,并编辑相应的前端文件
[[email protected] html]# mkdir /www
[[email protected] html]# mkdir /bbs
[[email protected] html]# vim /www/index.html
[[email protected] html]# vim /bbs/index.html
[[email protected] html]# cat /bbs/index.html

bbs.westos.org -- server3

重启httpd服务 [[email protected] html]# /etc/init.d/httpd restart
  • 测试:
    在主机添加解析:
    vim /etc/hosts
    cdn的技术原理及用varnish简单实现(实验)
    cdn的技术原理及用varnish简单实现(实验)

负载均衡

  • 负载均衡(Load Balance,简称LB)是一种服务器或网络设备的集群技术。负载均衡将特定的业务(网络服务、网络流量等)分担给多个服务器或网络设备,从而提高了业务处理能力,保证了业务的高可用性。
  • 负载均衡算法的种类有很多种,常见的负载均衡算法包括轮询法、随机法、源地址哈希法、加权轮询法、加权随机法、最小连接法等,应根据具体的使用场景选取对应的算法。
  • 在varnish中我们采用的是轮询法,平衡对待每一个后端服务器。

配置varnish,加入轮询规则:

 [[email protected] ~]# 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);	#为了测试方便,不进行缓存。
} elsif (req.http.host ~ "^bbs.westos.org") {
set req.backend = web2;
} else {
error 404 "westos cache";
}
}

重启服务

  • 测试
    cdn的技术原理及用varnish简单实现(实验)

cdn的推送管理

[[email protected] ~]# scp -r ‘/home/kiosk/Desktop/bansys.zip’ [email protected]:/var/www/html

[[email protected] html]# yum install gcc php -y
[[email protected] html]# unzip bansys.zip
[[email protected] html]# cd bansys
[[email protected] bansys]# ls
class_socket.php config.php index.php purge_action.php static
[[email protected] bansys]# mv * …/
[[email protected] bansys]# cd …
[[email protected] html]# ls
bansys class_socket.php index.php static
bansys.zip config.php purge_action.php
[[email protected] html]# rm -fr bansys*
[[email protected] html]# ls
class_socket.php config.php index.php purge_action.php static
[[email protected] html]# vi config.php cdn的技术原理及用varnish简单实现(实验)
将http的端口改为8080

  • 测试

cdn的技术原理及用varnish简单实现(实验)