CDN指南

CDN是Content Delivery Network的缩写,直译为“内容分发网络”。工作思路是把用户需要访问的内容缓存在边缘节点,就近访问,进而绕开经互联网骨干传输数据的不稳定性和速度瓶颈,起到提升最终用户体验的效果。通过在网络各处放置节点服务器所构成的基于现有互联网基础的一层智能虚拟网络,CDN系统能够实时地根据网络流量和各节点的连接、负载状况,以及到用户的距离和响应时间等综合信息,将用户的请求重新导向离用户最近的服务节点上。其目的是使用户就近获取所需的内容,解决 Internet拥挤的状况,提高用户访问网站的响应速度。
CDN分为静态加速和动态加速两部分,分别介绍如下。
静态加速
通过缓存静态资源到CDN节点,使用户可以就近访问CDN节点来获取资源,避免用户直接从源站获取数据,提升用户访问速度和质量。
如图11-1所示,相比用户直接访问源站,访问CDN节点可以带来以下收益:CDN节点更靠近用户,可以提供更小的网络延迟及更快的访问速度;CDN节点数量远大于源站,可以支撑更大的请求数量;CDN节点多地域部署,可以提供更好的容灾能力。
静态加速可以分为小文件类业务、下载类业务。两者之间的区别在于文件大小以及访问方式,以及由此带来的业务不同侧重点。
1
图11-1  用户访问CDN节点和源站的路径
小文件类业务:主要是通过浏览器访问的网页、图片、JS、CSS等内容尺寸比较小(无严格限制,一般为数KB至几百KB)的文件。特点是单次请求文件较小,请求总数较大,主要消耗CPU和带宽资源。一般都是直接在浏览器中展示,对访问成功率要求较高,要求RTT延时要尽量低,即节点要部署得离用户近。
下载类业务:相对于静态资源类业务,下载类业务的单文件尺寸要大很多,需要更多的磁盘空间和带宽资源,对CPU的消耗不如小文件类业务大。并且下载类业务的下载时间会比较长,相对于静态资源类业务更注重于吞吐量,而不是RTT延时。
动态加速
静态加速业务是通过将文件缓存至CDN节点来提高用户的访问速度的,而动态加速是通过尽量减少用户到源站之间请求的网络耗时来提高用户体验的。可用的技术有TCP单边加速、多路TCP合并回源、回源压缩。
TCP单边加速:主要原理就是在用户通过公网直接访问源站比较慢时,通过各种方式让用户请求绕过拥堵的网络环节。例如,在用户访问质量良好的区域建立CDN节点,用户访问先经过CDN节点,通过CDN节点中转至源站;或者在某些关键CDN节点使用专线和源站联通,以确保CDN节点到源站的回源质量(见图11-2)。
2
图11-2  TCP单边加速示意图
多路TCP合并回源:在CDN节点将多个用户的数据合并在一个TCP连接上回源至源站,以减少回源时新建TCP连接带来的额外时间消耗(见图11-3)。
3
图11-3  多路TCP合并回源示意图
回源压缩:将回源数据流进行压缩,减少在网络上传输的回源数据量。
自建CDN
初期公司更多的是使用第三方公司提供的CDN服务,随着业务量和业务需求的增加,第三方CDN在质量和运维效率上逐渐不能满足业务需求。为了提升CDN的质量,提高运维效率,自建CDN是一个不错的选择。在某案例中,使用自建CDN后,不仅业务质量有了明显提升,成本也有了大幅度降低,并且从侧面帮助公司在使用第三方CDN服务时提高了议价能力。
该案例中,自建CDN支持静态加速和动态加速业务,带宽容量达数百Gbps,日常支撑了全公司90%以上的CDN流量,多次支撑了业务的大型发布推广活动(活动带宽相比日常带宽增长数倍)。自建CDN在设计之初就针对公司业务的特性,以及从节点选择、软硬件配置到参数优化都进行了有针对性的调整。
在该案例中,针对公司业务的特点,我们首先开始了大文件静态加速的工作,随后逐步进行小文件静态加速和动态加速的工作。同时,CDN管理和调度系统也随着CDN的发展不断完善。CDN系统整体框图如图11-4所示。
4
图11-4  CDN系统整体框图
◎ CDN业务系统:对用户直接提供CDN加速的缓存服务器和代理服务器。
◎ 私有调度系统:公司的HTTP调度服务器和302调度服务器。
◎ GSLB系统:支持智能解析的DNS服务器。
◎ 流量收集系统:采集节点交换机、服务器和各业务的流量。
◎ 质量收集系统:对质量评测数据的采集、存储。
◎ 日志统计系统:统计CDN访问日志、调度系统日志。
◎ 质量分析系统:通过质量评测数据和日志统计数据,汇总统计出质量排序结果。
◎ CMDB系统:管理CDN节点的资产信息及状态跟踪。
◎ 调度决策系统:根据质量排序结果、流量数据以及CMDB系统的服务器状态,计算出一个最优化的调度方案,并生成相关调度系统的配置文件。
◎ 监控系统:对节点各类设备的基础监控及业务可用性监控。
◎ 告警系统:CDN告警系统会做两件事情,一是在告警发生时通知运维人员;二是会同时向调度决策系统发送信令,可以实现某些特定故障的自动化修改调度处理。
◎ 自动化接口:提供给CDN业务使用者的一些刷新、预加载等接口。
◎ Portal展示系统:展示CDN业务运行的各项数据。
◎ 配置变更系统:CDN运维人员进行各种日常运维操作的系统。
CDN硬件及节点选型
CDN的目的是在尽量低的成本下为用户提供尽可能高的服务质量,所以在硬件选型时成本是一个很重要的考虑因素。
针对静态资源类业务,在硬件选型上主要评估在节点出口带宽满载时,所使用的硬件总成本。例如,相同配置的1台万兆服务器和10台千兆服务器都可以跑满10Gbps带宽,这时肯定会选择万兆服务器。当然,在硬件选型时还要考虑实际业务对CPU、内存、磁盘的使用情况。
CDN服务器选型策略
静态资源类业务使用的机型规格为E5-2620 *2 + 128GB RAM + 2TB SAS *4 + 480GB SSD *6。关键指标:万兆网卡+大内存+SSD存储。使用万兆网卡可以有效避免单机网络吞吐达到瓶颈;大内存可以将更多的数据缓存在内存中,降低磁盘IO的使用;SSD可以提供更好的随机IO读/写性能。总体目标就是避免出现木桶效应。
动态加速类业务使用的机型规格为E5-2620 *2 + 64GB RAM + 600GB SAS *2。因为此类业务对带宽使用量较少,主要是大量TCP连接数对CPU的消耗,所以在硬件选型上主要侧重于CPU和内存,对于磁盘和网卡没有要求。
在做硬件选型时,发现相对于Broadcom网卡,Intel网卡无论是在CPU使用率还是小包性能上都要优秀很多,所以无论是千兆还是万兆服务器,都推荐使用Intel网卡。
CDN节点建设策略
伴随着业务发展,会需要陆续新建CDN节点,以保证CDN的整体带宽使用率控制在一个合理的水平。显而易见,在带宽缺口最大的区域新建CDN节点是最优的节点建设策略。通过日志统计系统可以得出各个省份运营商的带宽使用量及使用比例(将日志中的客户端IP地址通过IP地址库映射为具体的省份运营商,再将每条请求响应的大小以5分钟为粒度做聚合,除以300秒后即得到各个省份运营商的带宽使用量),再和当前已有节点的分布做对比,即可得到各省份运营商带宽需求及当前带宽供应、当前带宽缺口一览表(见表11-1,非真实数据,仅做示例)。
5
表11-1  各省份运营商带宽需求及当前带宽供应、当前带宽缺口一览表
确定了在哪些区域新建CDN节点后,后续的工作就是实际的选点了。在选点过程中,主要考核候选节点的成本和质量,节点的成本可以用单位带宽成本来衡量,这个不是本文重点,暂且按下不表。
这里主要介绍如何测量评估候选节点质量。为了使评测结果更接近用户真实体验及更具有横向可比性,我们使用JS测速来评测一个候选节点的质量。简单来讲,就是让部分真实用户去下载被评估的候选节点的一个固定大小的文件,然后记录每次用户下载的成功率及耗时,统计全部用户的平均下载成功率及耗时作为衡量节点质量的依据。从实践上看,此种方法效果良好。
在节点建设方面,我们采用的是模块化方案,一个节点有多少交换机、多少服务器,交换机以及服务器的型号配置如何,网线怎么连、电源线怎么插,全部都是固定统一的。基本可以说,各个节点的区别就只有IP地址是不一样的。并且交换机和服务器都是预先配置好后才发往外地节点上架的。采用这样的模块化方案,不仅可以显著降低使用过程中的运维成本,而且在节点建设中的便利性也是很显著的——无须我们的工程师去现场施工,数据中心现场代维工程师只要参照我们提供的一份标准化上架文档,就可以快速地完成上架施工。并且配置和流程都是高度标准化的,可以最大程度地避免(以及快速发现)上架误操作或漏操作。
CDN缓存系统
常见缓存服务器的简要对比
◎ Squid:老牌的缓存服务器,但是性能较差,无法满足自建CDN对于高性能的需求。
◎ Nginx:性能好,插件丰富,支持广泛,但缓存功能偏弱,在某案例中,动态加速服务就是在Nginx的基础上修改而来的。
◎ Varnish:配置方便,性能好,但不支持持久化缓存是其一大缺陷。
◎ Apache Traffic Server(ATS):性能好,对于缓存的支持很完善,但是插件不够丰富,很多业务需求需要自行开发插件来完成。
经过综合对比,自建CDN的静态加速服务使用了ATS。
ATS功能介绍
◎ 具有完整的正向代理和反向代理功能,并且支持集群工作模式。
◎ 使用parent配置时可以自动屏蔽故障源站。
◎ 具有内存缓存和磁盘缓存自动淘汰功能,支持直接写裸磁盘。
◎ 拥有丰富的日志格式配置。
◎ 支持插件开发,可以定制业务专有需求。
ATS配置要点说明
1.回源配置
回源配置示意图如图11-5所示。
6
图11-5  回源配置示意图
使用parent配置有以下好处:
实现多个源站负载均衡;故障源站自动屏蔽;源站DNS解析和回源Host解耦合。
remap和parent配置的区别如下:
remap是将用户访问的域名映射成另一个域名(可以是其本身),映射后的域名将用作回源请求和用来生成缓存的key。即,如果两个不同的域名同时remap到同一个域名,则两个域名下的相同的URI指向同一份缓存。而parent则负责将回源请求发送到特定的parent域名(或IP地址),而不是去DNS查询remap后的域名。
record.config文件配置如下:
CONFIG proxy.config.http.no_dns_just_forward_to_parent INT 1 #启用parent.config配置
CONFIG proxy.config.url_remap.remap_required INT 1  #启用remap.config配置
CONFIG proxy.config.url_remap.pristine_host_hdr INT 0 #这个配置项的意思是在remap后是否保留HTTP请求头中的Host项,务必配置成0(不保留)
remap.config文件配置如下:
remap     http://www.safecdn.cn   http://$1.safecdn.cn
remap_map http://(.*).safeidc.cn  http://$1.safeidc.cn
上面的三个remap配置都是很典型的配置,按字面意思理解即可。
2.缓存配置
(1)内存缓存配置(record.config文件)
CONFIG proxy.config.cache.ram_cache.size INT 1G #配置内存缓存大小
CONFIG proxy.config.cache.ram_cache_cutoff INT 50M #配置内存缓存的最大单文件尺寸
CONFIG proxy.config.http.record_tcp_mem_hit INT 1 #记录内存缓存命中
CONFIG proxy.config.cache.ram_cache.algorithm INT 1 #内存淘汰方式,默认为1(LRU)即可
(2)磁盘缓存配置(storage.config文件)
ATS支持两种磁盘缓存方式,一种是以文件的形式缓存在文件系统上,配置项是:/var/cache 500G(路径+存储大小);另一种是直接写裸盘,配置项是:/dev/sdb(磁盘设备的路径),这时不需要指定存储大小。
需要注意的是,ATS使用裸盘时需要更改磁盘设备的权限。在CentOS环境中可以在/etc/udev/rules.d/下新建一个99-trafficserver.rules文件,并添加如下内容:
KERNEL=="sd[c-z]*", MODE="0660",OWNER="root", GROUP="root"
 
(3)interim storage缓存配置(record.config文件)
为了解决SATA磁盘随机读/写差的问题,ATS支持内存——SSD(interim storage)——SATA磁盘三级缓存。将最常访问的内容放到SSD中,降低对SATA磁盘的随机读数量。相关配置项如下:
LOCAL proxy.config.cache.interim.storage STRING /dev/sdb
注意:interim storage机制默认是不开启的,请在编译时使用“–enable-interim-cache”参数开启。
更详细的资料请参见官方文档:http://trafficserver.readthedocs.org/en/latest/。
CDN调度系统
DNS调度
DNS调度示意图如图11-6所示。
8
图11-6  DNS调度示意图
DNS调度是通过对不同的Local DNS服务器返回不同的解析结果来实现智能解析和就近调度的。比如,给黑龙江联通的Local DNS返回黑龙江联通CDN节点的IP地址,给广东电信Local DNS返回广东电信CDN节点的IP地址。
CDN的DNS服务主要实现两个需求:智能解析以及edns-client-subnet支持。也有很多开源的DNS软件支持IP解析调度和edns-client-subnet,如PowerDNS。在某案例中,CDN主要使用DNSPod服务,小部分使用自建DNS服务(后续会逐步迁移到自建DNS服务)。自己研发DNS服务,主要考虑到一些特殊的业务场景和监控需求。
1.一个自建DNS服务实现简述——SmartDNS
SmartDNS(智能DNS),根据配置,能够支持针对不同的DNS请求返回不同的解析结果。SmartDNS获取DNS请求的源IP地址或者客户端IP地址(支持EDNS协议的请求可以获取客户端IP地址),根据本地的静态IP地址库获取请求IP地址的特性,包括所在的国家、省份、城市、ISP等,然后根据调度配置返回解析结果。支持A、SOA、NS记录的查询,支持DNS forward功能。
一个开源的Python版本SmartDNS,供大家参考:https://github.com/xiaomi- sa/smartdns。接下来介绍它的部分细节实现。
SmartDNS响应DNS请求的处理流程如图11-7所示。
IPPool类的初始化和该类中的FindIP函数进行解析处理是SmartDNS中最关键的两个要素,这两个要素在下面详细介绍。IPPool类的初始化示意图如图11-8所示。
9
图11-7  SmartDNS响应DNS请求的处理流程
10
 图11-8  IPPool类的初始化示意图
ip.csv为IP地址库文件,格式如下:
200000001,200000010,中国,陕西,西安,电信
其中各个字段的含义分别为IP段起始地址,IP段截止地址,IP段所属国家,IP段所属省份,IP段所属城市,IP段所属ISP。
a.yaml配置文件格式如下:
test.test.com:
ttl: 3600
default: 5.5.5.5 2.2.2.2
中国,广东,,联通: 1.1.1.1 3.3.3.1
中国,广东,,电信: 1.1.1.2 3.3.3.2
配置中地域信息的key包括4个字段,分别带有不同的权重——国家:8;省份:4;城市:2;运营商:1。
在初始化阶段,会生成一个名为iphash的字典,结构如图11-9所示。
11
图11-9  名为iphash的字典结构
其中,iphash的key为ip.csv每一条记录的起始IP地址,value为一个list,list长度为6,list的前5个字段分别为以该key为起始IP记录的IP段截止、IP段所属国家、IP段所属省份、IP段所属城市、IP段所属ISP,第6个字段是一个hash,key为a.yaml里面配置的域名,value为长度为2的list。iphash[IP段起始地址][6][域名1][0]为域名1在该IP段的最优解析,iphash[IP段起始地址][6][域名1][1]为该最优解析的总权值,该总权值暂时只做参考。
在iphash初始化过程中最关键的是iphash[IP段起始地址][6][域名1]的最优解析的计算,最简单、直接的方式是直接遍历域名1的所有调度配置,挑选出满足条件且总权值最高的解析,即为最优解析。这种方式记录整个iphash的时间复杂度为O(xyz),x为ip.csv记录数,y为域名总数量,z为各个域名的调度配置数。为了优化启动速度,优化了寻找最优解析的方法:事先将每个域名调度配置生成一棵树,这棵树是用字典模拟出来的,这样需要最优解析的时候就不需要遍历所有的调度配置了,而是最多检索15次即可找到最优,即时间复杂度为O(15xy)。具体实现请参考IPPool的LoadRecord和JoinIP两个方法。
有了初始化后的iphash数据结构之后,每次请求处理的时候,只需要定位请求IP地址处于哪个IP段,找到IP段起始IP地址,然后从iphash中取出最优解析即可。具体流程如图11-10所示。
12
图11-10  计算最优解析的具体流程图
2.edns-client-subnet支持
CDN使用DNS获取查询IP地址,根据IP地址对用户进行地域调度。但这里获取的IP地址是DNS地址,而不是用户真实的IP地址。在大多数情况下,我们假设用户通常会使用离自己网络最近的Local DNS,CDN调度基本还是准确的。但也有很多Local DNS设置错误的情况,或者用户使用Google Public DNS(8.8.8.8/8.8.4.4)或openDNS。
比如国内用户设置了Local DNS为8.8.8.8,我们得到的DNS Query IP地址是74.125.16.208,判断IP地址属于美国加利福尼亚州山景市谷歌公司,这个时候,我们的DNS会返回离美国加州最近的CDN节点IP地址给用户,于是国内用户错误地调度到美国CDN节点上。
为了解决上述问题,Google提交了一份DNS扩展协议,允许Local DNS传递用户的IP地址给authoritative DNS Server。CDN的DNS支持该协议后,就可以获取用户真实的IP地址,进行准确的调度。
edns-client-subnet流程示意图如图11-11所示。
13
图11-11  edns-client-subnet流程示意图
DNS Query会包含header和RR两部分,这里只介绍我们关注的地方,在网上可以搜到很多关于DNS协议的介绍,在这里就不做过多描述了。header会描述本次请求中Questions、Answer RRs、Authority RRs和Additional RRs的数量,RR部分会详细描述每个资源的内容,所有的RR格式是相同的,如下所示:                                 
14
edns-client-subnet是对EDNS协议的扩展,附加在一个DNS请求的Additional RRs区域,这里重点描述edns-client-subnet的结构。EDNS协议Extension mechanisms for DNS(EDNS0),请参考http://tools.ietf.org/html/draft-ietf-dnsind-edns0-01。
EDNS0每个字段的结构和描述如下:
Field Name   Field Type     Description
——————————————————
NAME         domain name    empty (root domain)
TYPE         u_int16_t      OPT
CLASS        u_int16_t      sender’s UDP payload size
TTL          u_int32_t      extended RCODE and flags
RDLEN        u_int16_t      describes RDATA
RDATA        octet stream   {attribute,value} pairs
OPT的值为41,详细的协议值如下:
(A, NS, MD, MF, CNAME, SOA, MB, MG, MR, NULL, WKS, PTR, HINFO, MINFO, MX, TXT,RP, AFSDB) = range(1, 19)
AAAA = 28
SRV = 33
NAPTR = 35
A6 = 38
DNAME = 39
SPF = 99
OPT = 41
RDLENGTH描述RDATAD的长度,edns-client-subnet的详细格式存在RDATA中,如下所示:       
15
OPTION-CODE:两个字节。
OPTION-LENGTH:两个字节,描述它之后的内容长度(byte)。
FAMILY:两个字节,1表示IPv4,2表示IPv6。
ADDRESS:实际存放IP地址的地方,IPv4长度为4,Google发送过来的长度一般为3,隐藏了IP地址最后一位。
理解了以上协议,就可以动手实现了。判断DNS Query是否包含Additional RRs,如果包含,则按照EDNS协议描述获取地址。用获取到的地址进行来源IP地址判断调度,封装结果返回。
BIND 9.10版本后自带的dig工具可以支持生成带EDNS扩展的请求来验证EDNS功能是否生效。命令示例:
./dig test.com @127.0.0.1 +subnet=1.1.1.1
使用WireShark抓取的支持edns-clinet-subnet的DNS请求截图如下。
发包:
16
回包:
17
私有调度
1.HTTP调度
用户通过访问一个HTTP接口,HTTP接口会判断用户的来源IP地址及其他诸如业务类型等信息,然后返回给用户一个JSON字符串,JSON字符串中包含相关的调度结果。客户端通过解析JSON字符串可以得到所需要访问的服务器IP地址列表。
HTTP调度相比DNS调度有以下优势:
可以识别用户来源IP地址,调度结果更精确;可以在URL中包含更多的业务信息,功能更强大;可以支持一次返回多个查询的结果。
HTTP调度的不便之处就是要依赖客户端支持。
2.302调度
当Web Server收到一个用户请求时,通过识别用户来源IP地址和其URL,返回一个302响应将用户的请求重定向至一个新的URL,用户使用新的URL再去下载真实的资源。
302调度可以做到针对单次请求动态调度,比DNS调度粒度更细,变更生效也更迅速,并且可以在URL上添加防盗链等信息。
302调度的缺点是增加了一次HTTP访问的时间,只适用于下载及流媒体等下载耗时较长的业务,静态小文件不适用于302调度。
302调度既可以独立使用,也可以作为DNS调度的补充。自建CDN当前就是在混合部署DNS调度和302调度,将访问国外CDN节点的中国大陆用户再重定向至国内CDN节点。
全局调度逻辑
为了实现更好的业务容灾,当前公司业务都是在多CDN供应商同时部署的。在需要时可以通过DNS View功能实现区域用户的导向;同一区域用户可以通过第三方和自建互备,提高了业务的容灾能力(见图11-12)。
18
图11-12  全局调度逻辑示意图
IP地址库维护
不管使用什么样的调度方式,一个准确的IP地址库都是调度系统中重中之重的部分,并且IP地址库在诸如日志分析等方面也有着重要的用途。所以维护一份可靠的、高准确度的IP地址库的工作具有重要意义。
我们的IP地址库最开始是直接使用网上的纯真IP地址库,这个地址库现在来看是一团糟,地理位置标记很不规范。后来陆续使用业内的收费IP地址库及友商的IP地址接口对此地址库进行了矫正规范,最终得出了一个格式规范、可信度比较高的地址库。
首先,我们将IP地址库的格式及地理位置命名进行了规范,纯真IP地址库大量存在某某学校、某某网吧的地理位置。规范后IP地址库格式为:起始IP地址,结束IP地址,国家,省份,城市,运营商。规范化格式带来的好处就是后期使用及合并裁剪都变得轻而易举。
其次,我们通过收集和购买基础库,采用投票方法进行整合,对IP地址库进行了矫正,得到自己的基础库。矫正的流程是,我们将整个IP地址库拆成以C段为单位,分别和其他的IP地址库进行比对,按照多数服从少数的原则对每个条目的信息做聚合,最后得出一个集各家之长的IP地址库。
在得到集各家之长的IP地址库后,我们和公司业务团队合作,拿到了几千万条IP地址和GPS地理坐标的关系数据(这些数据是通过天气App获取的,可信度很高),通过这些数据校验和进一步修正我们的IP地址库。经过上述一系列校验、矫正后,针对个别仍不能确认的IP地址,我们通过多节点traceroute,拿到各地到此IP地址的路由路径,以此来反推IP地址的归属。
海外CDN建设
自建还是第三方
当我们考虑海外自建CDN时,有很多现实的问题摆在眼前:服务器使用物理机还是虚拟机?服务器购买还是租赁?数据中心托管怎么解决?现场代维如何做?困难重重。反向比较的话,海外自建CDN相比海外现成的第三方CDN服务有什么优势?访问质量更好,还是成本更低?仔细评估下来,出于快速部署和扩展的考虑,主要采用了成熟的产品。海外是按照流量计费的,所以在数量小的规模下,自建优势不大。后续随着量的增长,我们会在合适的阶段评估自建。
具体到海外自建CDN节点,针对某些用户量大、我们自身掌控力也强的地区(例如中国香港地区),我们采用部署物理服务器的方式将节点直接建设到本地;针对其他用户量大的地区,则使用第三方云服务虚拟机进行节点部署。
海外源站部署
在CDN海外部署的过程中,我们遇到最多的问题就是海外回源:海外CDN节点回源到国内质量差,还会由于各种原因导致回源连接被墙。针对上述问题,我们在海外CDN回源上也做了很多优化。
针对一些文件总量较小的业务(官网静态页面等),我们将海外源站直接部署到了海外虚拟机上,这样就完全规避了回源的问题。
针对一些文件总量较大或者发布时效性要求比较高的业务,我们在海外源站新增了一个Proxy层,Proxy层会优先将回源请求代理到海外源站,针对暂时没有发步到海外源站的资源会代理到国内源站。
针对一些不便进行海外源站部署的业务,我们在中国香港地区做了一组中间层缓存服务器,通过香港地区的缓存服务器再统一回源至国内。
总而言之,尽可能地降低海外CDN回源到国内源站的次数,提升回源速度,降低被墙的风险。这是海外源站部署的主体思路。
质量评测系统
质量评测的目的是评估CDN服务质量的好坏,而监控系统则是为了及时发现服务中的问题并告警、处理。质量评测关注大层面的服务质量,监控系统关注细节的服务质量,这两个系统的主要目的还是有区别的。当然,质量评测的数据发生异常波动时,也会发送告警、处理。
客户端测试
从客户端角度去评测一个服务的质量情况,大体上可以分成以下几种方式。
(1)类似于博睿所提供的服务,通过部署在全国各地的测试节点去定期访问我们的被测试业务,统计相应的成功率和访问耗时。此种方式由于可以拿到详细的访问数据,所以在发现问题时更容易定位问题的原因。但是劣势也很明显,需要在全国各地部署节点或者使用第三方的付费服务,并且测试样本偏少,不能有效地代表真实用户,所以此种方式在我们的质量评测中已经很少使用了。
(2)对于有客户端的业务,我们联合业务开发,对一些关键的网络交互环节进行打点,统计访问成功率及访问耗时,这样得出来的结果是业务真实的质量数据,可信度及数据的丰富程度都很高。缺点是需要有客户端支持,不是所有的业务都有此条件。
(3)对于HTTP类的业务,通过在Web页面中嵌入一个JS脚本,使用JS脚本去下载业务的一个资源,统计访问的成功率及访问耗时。相比客户端打点,此种方式具有更广泛的适用性,只要被测试的业务是HTTP类型即可(CDN绝大部分业务都符合此条件)。当前我们大量使用的是此种测试方式。
服务器抓包分析
我们开发了一个工具,可以抓取用户访问的TCP流,通过服务器端全流量分析,可以对访问请求分析TCP流各个过程耗时情况(例如三次握手完成后,服务器返回了某个特定信息,累积下载了1MB的文件等)。通过大数据分析,可以得到各用户单元到不同节点的整体图表,对调度表格进行循环优化。下面就简单介绍一下这个抓包工具的实现。Tcpxm已经开源:https://github.com/xiaomi-sa/tcpxm。
Tcpxm是使用Python开发的,调用Pylibcap进行抓包的工具。它共有3个线程:一个负责抓包并分析内容;一个负责写日志;一个用来清除过期数据。Tcpxm可以很方便地抓取和分析TCP请求,打印成所需要的日志形式。
最初我们用它来抓取和分析某个App的登录时间,稍加改造就可以抓取网站访问等时间,计算用户建立TCP连接的时间、第一次发包的时间等。如下是我们之前抓取App登录时间的日志格式和每个字段说明。
2012-09-13 21:25:25 tcpxm.py [line:229] [INFO]  221.179.36.189:3103->xxx. xxx.xxx.xx:2424 [usr:54298295] [login(t6-t0+rtt):2760]  [t1:0] [rtt:217] [t3:137] [t4:0] [t5:118] [t6:2069] [t7:193]
在此用户的登录时间= t6(发送<success>的时间)– t0(收到SYN的时间)+ rtt(估算出的收到SYN包和发送ACK包的路径时间)。
具体每个t代表的时间含义如图11-13所示。日志中的t3=T3-T2,t4=T4-T3,rrt(t2)=T2-T1,……
19
图11-13  某个App登录过程时序图
CDN故障处理预案
在CDN系统运行过程中,各种大大小小的故障或者突发情况是不可避免的。因此,针对各种已知故障进行归纳总结,整理成故障处理预案,并逐步沉淀成自动化的处理过程。通过这样的不断迭代,可以不断提高服务能力,降低故障发生的概率;在故障发生时可以快速有效地介入处理,减少故障影响的范围及时间。
在CDN服务中,某业务突发增长数倍甚至十几倍的情况还是时有发生的。针对这种情况,我们建立了详细的应对预案。
故障场景:业务突发(未提前通知)导致CDN整体带宽利用率超过80%,且有进一步上涨的趋势。
关键动作:联系业务同事,确认业务突发原因(推广活动还是受攻击,抑或是其他);通盘评估,确定对此次突发是进行资源保障还是资源打压,并和业务同事达成一致;发出通告,通知可能受此影响的第三方业务。
CDN故障处理预案:
(1)我们的所有CDN业务都是多厂商部署的,并且平时对热门的资源在各厂商都有做预加载,当某一家资源不能满足业务需求时,可以快速灵活地将部分流量调度到其他厂商。
(2)我们在CDN交换机上预配置了高、中、低等不同的QoS策略,通过切换业务使用的CDN域名,让突发业务匹配高优先级的QoS策略,可以重点保证此业务的质量。如果需要打压突发业务的流量,则让突发业务匹配低优先级的QoS策略。

(3)在极端情况下,会损失突发业务的部分可用性,隔离突发业务。修改调度,将突发业务的流量调度到预配置的有限个节点,将其流量和正常业务从物理上隔离(类似数据中心将受攻击的IP流量牵引到黑洞),只提供有限的服务能力。

原创文章,作者:赛福,如若转载,请注明出处:https://www.safecdn.cn/cdn/2016/10/cdn-zn.html