1. 前言
2. 背景
-
时效性:当 CDN 出现问题时,SRE 会手动进行 CDN 切换,因为需要人为操作,响应时长就很难保证。另外,切换后故障恢复时间也无法准确保障。 -
有效性:切换至备份 CDN 后,备份 CDN 的可用性无法验证,另外因为 Local DNS 缓存,无法解决域名劫持和跨网访问等问题。 -
精准性:CDN 的切换都是大范围的变更,无法针对某一区域或者某一项目单独进行。 -
风险性:切换至备份 CDN 之后可能会导致回源,流量剧增拖垮源站,从而引发更大的风险。
3. 目标与场景
3.1 核心目标
-
端侧 CDN 域名自动切换:在 CDN 异常时,端侧第一时间感知并自动切换 CDN 域名进行加载重试,减少对人为操作的依赖。 -
CDN 域名隔离:CDN 域名与服务厂商在区域维度实现服务隔离且服务等效,保证 CDN 切换重试的有效性。 -
更精准有效的 CDN 监控:建设更细粒度的 CDN 监控,能够按照项目维度实时监控 CDN 可用性,解决 SRE CDN 监控粒度不足,告警滞后等问题。并根据容灾监控对 CDN 容灾策略实施动态调整,减少 SRE 切换 CDN 的频率。 -
域名持续热备:保证每个 CDN 域名的持续预热,避免流量切换时导致回源。
3.2 适用场景
4. Phoenix 方案
4.1 总体设计
-
端侧容灾 SDK:负责端侧资源加载感知,CDN 切换重试,监控上报。 -
动态计算服务:根据端侧 SDK 上报数据,对多组等效域名按照城市、项目、时段等维度定时轮询计算域名可用性,动态调整流量至最优 CDN。同时也是对 CDN 可用性的日常巡检。 -
容灾监控平台:从项目维度和大盘维度提供 CDN 可用性监控和告警,为问题排查提供详细信息。 -
CDN 服务:提供完善的 CDN 链路服务,在架构上实现域名隔离,并为业务方提供等效域名服务,保证端侧容灾的有效性。等效域名,就是能够通过相同路径访问到同一资源的域名,比如:cdn1.meituan.net/src/js/test.js 和 cdn2.meituan.net/src/js/test.js 能够返回相同内容,则 cdn1.meituan.net 和 cdn2.meituan.net 互为等效域名。 -
容灾配置平台:对项目容灾域名进行配置管理,监控上报策略管理,并提供 CDN 流量人工干预等措施。
4.2 容灾流程设计
4.3 实现原理
4.3.1 端侧容灾 SDK
Web 端实现
-
通用性:美团前端技术栈相对较多,要保证容灾 SDK 能够覆盖大部分的技术框架。 -
易用性:过高的接入成本会增加开发人员的工作量,不能做到对业务的有效覆盖,方案价值也就无从谈起。 -
稳定性:方案要保持稳定可靠,不受 CDN 可用性干扰。 -
侵入性:不能侵入到正常业务,要做到即插即用,保证业务的稳定性。
Native 端容灾
-
便捷性:接入的便捷性是 SDK 设计时首先考虑的内容,即业务方可以用最简单的方式接入,实现资源容灾,同时也可以简单无残留拆除 SDK。 -
兼容性:Android 侧的特殊性在于多样的网络框架,集团内包括 Retrofit 框架,okHttp 框架,okHttp3 框架及已经很少使用的 URLConnection 框架。提供的 SDK 应当与各种网络框架兼容,同时业务方在即使变更网络框架也能够以最小的成本实现容灾功能。而 iOS 侧则考虑复用一个 NSURLProtocol 去实现对请求的拦截,降低代码的冗余度,同时实现对初始化项进行统一适配。 -
扩展性:需要在基础功能之上提供可选的高级配置来满足特殊需求,包括监控方面也要提供特殊的监控数据上报能力。
-
容灾数据缓存:定期获取及更新容灾数据,其产生的数据只会被域名更换组件使用。 -
域名更换组件:连接容灾数据缓存,容灾请求执行器,监控器的中心节点,负责匹配原始失败 Host,过滤错误码,并向容灾请求执行器提供容灾域名,向监控器提供整个容灾过程的详细数据副本。 -
容灾执行器:容灾请求的真正请求者,目前采用内部 OkHttp3Client,业务方也可以自主切换至自身的执行器。 -
监控器:分发容灾过程的详细数据,内置数据大盘的上报,若有外部自定义的监控器,也会向自定义监控器分发数据。
-
绑定器:生成适合各个网络框架的拦截器并绑定至原始请求执行者。 -
解析器:将网络框架的 Request 转换为 Phoenix 内部执行器的 Request,并将 Phoenix 内部执行器的 Response 解析为外部网络框架 Response,以此达到适配目的。
4.3.2 动态计算服务
4.3.3 容灾监控
4.3.4 CDN 服务
5. 总结与展望
6. 作者简介
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/258585.html