Serverless 实战:通过 Component 实现多地域部署容灾

作者|刘宇
策划|田晓旭
单点故障是实际生产中无法避免的 , 单副本的存储方案也早已无法满足业务的可靠性要求 。 现在 , 我们通常都会做双机存储架构 , 会涉及到主备、主从、主主模式 。
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
在Serverless架构下 , 高可用方案或者容灾方案是否还需要主备、主从以及主主等模式?如果还需要 , 那么又是什么样子?
1Serverless与多地域部署
针对服务可用性 , 几乎每个云厂商都会有非常高的承诺 , 但是我们也不能掉以轻心 , 认为不会出现故障导致不可用 , 容灾方案是必须要有的 。
在传统主机时代有主备、主从以及主主模式 , 这个模式更多针对的是单台机器或者某个集群 。 但是在Serverless架构下 , 没有机器和集群的概念(至少在用户层面没有) , 是不是就表示在Serverless架构下无法做容灾?
理论上 , 云厂商会保证整个服务的可用性 , 如果云厂商管理的某个机器出现故障 , 机器会被及时剔除 , 确保新的函数在安全、稳定、健康的环境下启动 , 正常提供服务 。 但在实际情况中 , 由于某些原因 , 云厂商也可能会在某个地域出现大规模故障 , 这时如何确保服务依旧可用 , 而不是苦苦等待云厂商的恢复?
针对单地域解析的网站 , 我们可以实现多地域的主备方案 。 在云函数中 , 多地域的主备方案更加经济实惠 , 因为函数是按量付费的 , 完全可以将函数复制到其他的地域 , 只要不进行触发 , 就不会产生额外的费用 。 相对于传统主机时代的主备模式 , 这种主备方案显得更加人性化 。
一般情况下 , 单地域部署的服务中比较容易出问题的是API网关服务、云函数服务、数据库服务 。 其中 , 数据库服务可以考虑跨地域主从、跨区域同步 , 一旦出现问题 , 就在函数中做一个负载 , 确保整体数据不会出现问题 , 在腾讯云的云数据库描述下可以看到:
本地IDC机房MySQL数据库与云数据库MySQL之间可以通过数据迁移服务实时同步数据 , 本地IDC机房如遇到断电、网络故障等引起数据库服务中断 , 可迅速切换数据库服务至作为灾难备份的云数据库MySQL实例 , 实现数据库容灾;同时 , 云数据库MySQL可支持同城多可用区灾备/跨城灾备 , 保障高可用 。所以说 , 数据库相关服务的容灾可以通过备用数据库来提高可用性 。
那么云函数和API网关怎么解决?
以多地域部署容灾为例 , 我们可以考虑这样的架构:
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
同样是作为单地域解析服务 , 相对来说 , 多地域部署更加安全稳定 , 一旦某个地域的服务出现问题(例如API网关 , 云函数) , 都可以通过监控程序及时发现 , 并且迅速切换解析到其它地域 。 多地域部署的监控函数与时间触发器进行结合 , 定期进行网站可用性的排查 , 一旦出现问题 , 就可以在云解析层面进行解析切换 , 实现单地域服务的多地域部署容灾方案:
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
这个方案的逻辑是先请求服务是否可用 , 如果不可用 , 则获取容灾列表 , 剔除不可用的服务 , 并通过云解析进行可用区的解析 。 在实际生产中 , 一旦确定某个服务不可用 , 还要进行精确告警 , 在获得到不可用解析记录对应的服务之后 , 通过邮件或者企业微信、短信等方法进行告警 。
至此 , 一个简单版的“高可用”服务就算做好了 , 有的读者可能有所疑问:
【Serverless 实战:通过 Component 实现多地域部署容灾】对服务进行修复 , 是否比切换解析更加靠谱呢?
针对问题1 , 其实切换解析是需要时间的 , 虽然一小部分的机房可能不会按照设定的TTL进行生效 , 但是大部分的机房都是可以按照设定及时生效 , 所以需要注意的是 , 在添加解析的时候要尽可能地确保TTL时间短一些 , 目前腾讯云的云解析付费版最低TTL可以设置为1s , 免费版是600s 。
针对问题2 , 在云函数上运行服务很少会因为流量太高导致服务不可用 , 或者服务中存在bug导致整个项目不可用 , 因为云厂商会解决很大一部分的可用性 , 例如流量并发问题等 。 另外 , 就算是程序中存在bug , 在Serverless架构下 , 函数的前一次后一次运行实际上关联性不大 , 所以完全可以通过告警来确定 , 人为排查消灭隐患 。 事实上 , 在Serverless架构下出现大规模服务性灾难 , 多数情况都是云厂商的问题(此处已经排除掉用户代码层面的bug) , 而这种问题一旦出现 , 就不是我们能够掌控的了 , 是否可以修复、什么时候修复 。
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
如果是API网关层面出现问题 , 可以通过上一层来解决 , 例如云解析的切换;如果是函数层面出现问题 , 可以考虑切换到API网关到同区域的备用函数;如果是函数服务的整个区域性故障(概率非常低) , 可以考虑切换解析到备用区 。
如果不是单地域提供服务 , 那么就需要考虑多地域部署、多地域就近接入以及多地域容灾方案 。
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
从上图可以看到 , 我们将一个域名 , 划分地域进行解析 , 例如华北、华东两个地区 , 就可分别解析到北京1区、北京2区两个不同的机房中两台不同的服务器上 。 当其中一个服务不可用时 , 其他区域不受影响 , 可以使用云函数对解析进行修改 , 将其解析到每个地区的备用服务上 。
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
整体结构图:
Serverless 实战:通过 Component 实现多地域部署容灾
文章图片
传统的服务需要每个地区部署多套服务 , 无疑大大增加了成本 , 但是在Serverless架构下 , 即使部署了多套云函数还是按量付费 , 大大节约了成本 。
若采用Serverless架构作为后端服务 , 以华北地区为例 , 华北地区用户在访问后端服务的时候 , 通过DNS重定向到北京区的API网关 , 然后再由API网关触发北京区云函数 , 此时我们需要两个云函数对服务进行监控 , 一个函数对云函数进行监控 , 当云函数服务失效之后 , 可以将API网关绑定到备用的函数上 , 另一个监控是对API网关进行监控 , 当某个地域的API网关失效之后 , 可以对解析进行修改 , 重定向到备用地域的API网关上 , 尽可能快速的保证服务的可用性 。
如果想要让服务更稳定 , 可以增加数据库/对象存储的主备与监控 , 以及数据库/对象存储封装函数的主备与监控 , 这样就可以在四个层次做监控告警以及服务保障:在我们的服务中 , 通常数据库或者存储模块不会同时在多个区域部署 , 也可能只有一套主备服务 , 此时 , 可以通过对数据库和对象存储做一层封装 , 即在外层增加一个对应的函数 , 通过内网对数据库以及对象存储进行数据转发等 , 通过外部云函数调用invoke(专线调用)大幅度降低由于网络原因造成的延时 , 当云数据库/对象存储出现问题 , 在接入层(数据库/对象存储封装函数)一侧 , 进行切换 , 将云数据库/对象存储切换到备用服务上 , 并进行告警;当接入层发生故障 , 无法继续服务时 , 在逻辑函数初(北京区/上海区/广州区) , 切换封装函数 , 即通过内部专线(函数间调用)调用备用接入层函数;同理 , 当逻辑函数/业务函数出现故障 , 监控脚本对API网关侧的后端服务进行切换 , 切换到备用逻辑函数/业务函数上;如果当API网关出现故障 , 无法继续提供服务 , 则只能在解析层面做切换 。 在整个这样的一个流程中 , 每一阶段或者说每一层面都有自身的负载机制 , 主备策略 , 可以根据不同组件出现故障的实际情况 , 进行多层级的自动切换 , 进而保证业务可用时长的一个最大化 。


    推荐阅读