近年来,服务器机房多次出现光缆被挖、机房掉电等风险事故。受此影响,支付宝、微信曾一度被迫中断业务。多机房部署在提升访问速度的同时,能够有效应对极端故障事件,一举多得。
随着易盾验证码用户量的增多,特别是海外用户的增长,原有单机房的架构已无法支持业务的发展。易盾引入多机房后,用户就近访问,有助于提升验证码加载速度,带来更好的使用体验。本文主要介绍了常见的多机房部署方案,实际落地过程中遇到的问题以及对应解决方案,希望对大家有所帮助。
01 多机房的技术挑战
-
多机房的任务协调:请求路由和会话保持多机房后,一个请求过来后,首先确认请求要路由到哪个机房进行处理,并且保证同一个会话的所有请求都路由到同一机房处理。一般首次访问路由是通过基于 DNS 的 GSLB 解析到某一具体机房,短时间内后续所有请求都会解析到同一机房。但是当用户 DNS 或地理位置发送变化后,DNS 会发生变化,如何保证继续落到相同机房?在验证码的一次会话中,包括用户的一次校验,还包括客户服务端的二次校验,这两者往往不在相同的地区,需要额外的路由机制进行保证。
-
业务数据的强一致性:数据同步方案多机房方案中,每个机房存在自己的存储组件,并都存在自己的读写操作。但大多数业务特点,都需要将各机房的业务数据在全部机房间进行共享,需要一套数据同步的方案,包括数据库,缓存,消息队列等组件,并且要保证数据的一致性。当然一致性的要求有高有底,各业务可选择适合业务场景的方案。验证码场景对接口请求的一致性要求高,但对数据存储和统计的一致性要求相对较低。
-
网络延时与不稳定:跨机房网络延迟问题当用户路由发送变化时,会存在跨机房访问,而机房间访问不同于内网环境,网络质量较差,会出现不稳定的情况,特别是国内和海外机房间更是存在网络延时大,网络连接不稳定的问题。
-
业务无感知迁移:目前易盾验证码已接入大量客户,该方案必须在保证对已接入客户无感知的情况下进行升级和迁移,包括服务不能中断,接入方式不能变更。
02 常见的业内方案
2.1 单元化方案
目前,业务的多机房方案多是采用单元化的方式,根据业务特点将服务拆分为一个一个的单元,各个单元相对独立,各自能进行写操作,提升整体写入性能。其缺点在于业务场景必须支持数据分区,业务改造成本高,数据同步方案复杂。
单元化方案主要分为以下2种:其一,按用户进行划分。一个用户注册后被分配到某一机房,后续该用户的全部请求均路由到该机房进行处理。其二,按地域进行划分。举个例子,外卖服务天然跟地理位置有关,用户、骑手和商家都根据地理位置拆分成多个独立的单元,保证整个核心业务流程都在同一机房内完成,无需进行跨机房调用。
2.2 消息同步方案
消息同步方案通过消息队列进行机房间的数据同步,底层 DB 作为 master 提供读写服务,其他机房 DB 作为 slave 只提供读服务,写入操作通过消息队列发送到主机房 DB 完成,自机房通过数据库同步工具与主机房保持同步。该方案降低了数据同步的复杂度,通过消息队列保证最终一致性。这样实施起来相对简单,业务改造成本低,但数据一致性保证较低,要求业务能接受一定的数据延迟,适用场景有限。
03 易盾验证码多机房部署方案
3.1 流量调度
易盾验证码一次会话生命周期主要包括加载验证码、校验答案、二次校验三个步骤。
图 | 易盾验证码工作流程
为了保证业务正确性,方案需要保证期间全部请求都路由到同一机房,但期间用户浏览器和客户服务端均需与易盾服务器进行通信,而这两者往往不在同一网络环境。
例如,用户可能在国外,但客户服务器在国内,测试用户请求落在国外节点,而客户服务端请求到国内机房。在这种情况下,我们必须通过一种机制将客户服务端请求转发到国外节点。
为此,易盾为每次验证码会话分配了一个机房标识,通过该标识,通过定制的网关转发模块强制将该会话的全部请求路由到同一机房。整体方案如下图所示:
首次访问时,通过基于 DNS 的 GSLB 将用户请求就近解析到本地机房,其原理是根据用户的 DNS 所在的地理位置,就近返回解析结果 IP。由于此时请求未携带机房标识,所以会直接转发到当前机房的后端节点处理。处理完成后,请求响应中会带上当前机房的标识。客户端获取到该标识后进行存储,并在该次会话的后续所有请求中,全面带上该机房标识,后续的请求无论被 DNS 解析到哪个机房,都能根据该机房标识转发到正确的机房进行处理。
该方案主要的挑战在于各机房网关必须实现正确、高效的转发,而实际业务请求如何将机房标识带上存在不同方案。
业务请求各不相同,有些是 get 请求,标识通过 form 表达传入,有些是 post 请求,有些接口由于不能增加字段,需将机房标识隐藏到现有参数中,转发逻辑维护起来较为复杂。
易盾网关逻辑通过 openresty+lua 脚本实现,使用 lua 脚本足够灵活,可满足复杂多变的定制需求。openresty 在性能上与 nginx 相当,解析逻辑对请求整体延迟的影响几乎为零。
3.2 数据同步
易盾验证码服务底层依赖的数据存储包括数据库、redis、kafka、zk、图片存储等基础组件,具体架构图如下所示:
其中,数据库层面根据业务特点,将全部的表拆分成三类:各机房共享表、各机房独有表和中心机房特有表。只需要对第一类表进行同步即可。同步方案采用内部数据库同步工具 NDC 完成,NDC 通过订阅 binlog,提供应用层数据同步能力,同步延迟在 ms 级,稳定性和性能可以得到保证。
kafka 主要用于数据异步计算和存储,业务上进行解耦,对消息延迟有 一定的容忍性。在实现上,各机房将消息发送至各自私有的 kafka 集群,统一在中心机房进行消费处理,借助于一个自研的数据同步中间件,完成消息的同步。其原理可简单理解为,从一个 kafka 集群消费消息后,发往另外一个 kafka 集群。
值得注意的是,发送者和消费者应用依赖的 kafka 集群面临跨区域网络不稳定的问题。中间件解耦能轻松解决这一问题。因此,网络问题集中交给中间件来解决。
图片访问由于使用 cdn 进行分发,天然就具备多机房就近访问的特性,无需单独进行处理。图片上传则需要考虑合理的写入方案,由于图片为读多写少操作,并且上传多为异步操作,能够容忍一定的网络延迟,所以各机房共用一套图片存储服务。
redis 为缓存服务,用于高并发低延迟数据访问场景。为了保证缓存的高性能,各机房独立部署 redis 集群,数据不进行机房间同步,由业务上进行拆分,保证各机房间缓存数据无相互依赖。
3.3 网络优化
无论是数据同步方案,还是路由转发方案,都存在跨机房网络调用的场景。由于机房间物理距离远,网络链路复杂,网络质量相较机房内网络会差很多,特别是国内机房与国外机房则更为严重,网络调用的延迟高,甚至可能会存在由于网络波动导致短时间网络中断的现象。
为了优化国内外网络问题,网易在香港设置国际网络节点,通过专线从北京、杭州、广州一直到香港贯穿整个网易自有IDC环境,通过 PNI(Private Network Interconnection)对接了 AWS、Twitch,通过 IX(Internet Exchange Point)对接了 Akamai、i3D、Valve、G-core、Cloudflare、HKcable、Apple,优化香港机房与国内机房间的网络质量。
同时,通过与云平台建立 DX 通道,可以使国际云服务器与国内服务器通过内网 IP 进行互联互通,国际云服务器通过云平台公司内部的跨国海缆专线到网易香港节点,再从香港节点专线回国内。全程专线有效消除网络丢包和时延。
经过实际的网络对比测试发现,采用香港代理和不采用香港代理的方案,在网络延迟和稳定性上有明显差异,前者效果更优。下表为请求延迟统计数据:
从上述数据可以看到平均RT降低了35%,且稳定性得到很大提升。
04 总结
验证码应用于各业务注册、登录等重要业务场景,对加载失败率和加载速度有要求。此次多机房部署有几个关键:首先,结合验证码业务特点,易盾验证码方案在请求中加入机房标识,解决了请求路由和会话保持的问题。其次,方案采用业务拆分和重构,大大简化数据同步。最后,方案通过在香港机房中转的方式,化解国内外网络不稳定的问题。在多机房方案落地后,易盾验证码服务的加载速度、稳定性、极端故障应对能力都有显著提升。