微信邦 发表于 2018-5-9 09:08:37

腾讯织云:如何优雅地实现高可用系统?

作者 许应珂




高可用系统的挑战
高可用系统是运维界老生常谈的话题之一。现在很多企业都要求平均无故障时间每年五个 9 的服务可用性。
一方面系统单点是高可用最大的天敌,这不得不在系统设计时增加“冗余”,容易造成资源浪费。
另一方面,单机硬件配置往往支撑不了海量计算,分布式集群越来越成为当今主流的服务模式。伴随着分布式开发的系统设计,在运维方面也经常面临挑战,如海量运维时如何自动剔除异常单机异常免遭业务故障,自动化运维时,如何做到弹性伸缩对服务调用方透明。
因此一个优雅的高可用方案是解放运维劳动力,走向自动化运维的基石。在笔者看来,一个优雅的高可用方案设计必须具备以下几个特点:
(1)具备负载均衡、服务异常发现和剔除的能力;(2)具备扩缩容服务对调用方透明;(3)具备高可用架构自身无单点,易维护性;
举例一种常见的基于 LVS 实现高可用的设计。
LVS 是一款四层协议的负载均衡系统(如下图),虽然它能够基于权重调整后端负载,当后端机器端口不可达时,也可以对异常机器自动剔除和恢复,但毕竟交付给调用方 Virtual IP,一旦机房变迁,还是需要周知调用方更改 VIP,加上 LVS 的 LD(Load Director,负载均衡器) 本身存在单点隐患,必须通过 KeepAlived 做双机冷备,无法实现横向扩展。单凭 LVS 自身系统维护成本就略高。
有人会说,在 LVS 的 Virtual IP前面加上域名,改用 DNS+LVS+KeepAlived 组合拳,这也算是一种常用的解决方案。但今天笔者会给大家介绍腾讯织云路由如何更优雅地实现高可用。织云路由 DNS 来袭
织云路由是一款实现负载均衡和自动容错的名字服务系统,具备 DNS,负载均衡,故障自动剔除,就近访问,过载保护等特性。织云路由由 DNS 功能和高级功能组成,如下表格是和业界通用的解决方案简单对比:

一方面,织云路由DNS 功能相比原生的 DNS 有如下关键特性:
(1)支持基于权重的负载均衡,通过管理系统调整服务器集群的权重,实现按比例分配流量调整负载;(2)宕机机器秒级主动剔除,通过 ping+tcp 连接 +udp 发包主动探测服务器集群的端口存活健康状态;(3)易用性好,通过管理系统注册域名,绑定多 IP 地址,调用方则可以使用 ping/dig 等系统工具(或者 getaddrinfo 系统调用)解析域名背后的 IP 地址,无需代码嵌入。
另一方面,织云路由提供一站式服务,完整的配套(管理系统、监控、DNS Server、Client Agent)(如下图),支持RESTful API接口扩展,同时封装 C、java、php、Python等高级语言的 API 库提供调用。相比其他负载均衡方案,DNS Server 部署简单,易平行扩展且对客户端透明。目前织云路由在腾讯 QQ、Qzone、移动支付等诸多产品中广泛使用,支持上万节点访问。它是在时间的长河中饱受考验,最终产出的智慧结晶。
实现三步曲
1、注册域名:服务方在管理系统上注册一个域名,作为一切对外提供服务的入口,域名的规范是由一串点分隔的字符串标识的名字。为了防止误劫持其他域名,可以严格限定顶级域名。之后调用方直接使用这个域名访问后端服务,而无需关心后端服务具体哪些 IP,实现服务和 IP 的解耦。
2、给域名绑定真实服务器 IP:服务方可以在管理系统给已注册的域名绑定多个服务器IP+端口+静态权重,可以实现基于权重的负载均衡和基于 IP+PORT 的异常自动剔除能力。如果使用 API 方法(可提供 C、Java、Python、php 等不同语言API)获取后端 IP+PORT,则可以实现更高级的功能,包括动态负载均衡、就近访问、过载保护等;

3、调用方部署 Agent:Agent 主要做两件事情:一是本地劫持 DNS 解析,获取 IP 地址(高级功能还可以获取管理系统注册的端口信息);二是实现负载均衡算法和异常检测;
关于 DNS 解析过程是通过向“/etc/resolv.conf”文件注入一个本地DNS Name Server 地址 127.0.0.1 并设置其为首先 DNS Name Server。Linux 操作系统在解析域名时,会从/etc/resolv.conf中获取对应的 DNS Name Server,并按序查询域名。127.0.0.1的 Name Server(也即 DNS 解析 Agent)因此可以拦截所有的DNS 请求,如果该域名在管理系统中已注册,则按权重和主动探测的健康状况选择对应的 IP 返回,如果不在,则直接返回失败,让下一个 Name Server 处理。完成以上三步,调用方就可以直接使用域名访问了。
这里举一个简单的 http 服务案例,分析织云路由是如何做服务调用和自动容错的。织云路由DNS在 http 服务的应用实践
1、服务方模拟 http 服务环境:先准备两台机器(1核2G内存):

10.100.71.232CentOS Linux release 7.2
10.100.71.233CentOS Linux release 7.2
在~/http 目录存放一个 index.html静态页面,并用 Python 的 SimpleHTTPServer 模块在 80 端口监听 http 服务,如下:

2、调用方请求服务:(1)使用 dig 工具解析 test1.encho.local 域名,可以获取到已配置的 IP 地址,每次 dig 获取的 IP 地址会根据静态权重比例分配。
(2)curl 发起请求,亦能够快速响应服务。(3)同样是 curl 请求,我们模拟调用方以 10次/秒的频率发送,持续 100 秒,期间服务器 10.100.71.232 突然宕机。如下是调用方请求服务器 IP 次数分布的时序图。
Agent 共经历三个周期:发现期:即机器宕机后且 Agent 未踢掉宕机机器的时间段,持续时间在秒级内,该周期调用方仍会请求到异常 IP,此时 http 返回码是 400;剔除期:Agent 自动踢掉宕机机器,并持续检测已宕机机器是否恢复,该周期调用方不会请求到宕机 IP;恢复期:当 Agent 检测到宕机服务已恢复,在下一周期重新分配请求给这台机器;小结
从上面的案例也可以看出,织云路由在调用方和服务方充当的“DNS”的角色,对调用方完全无代码侵入,和业务实现真正的解耦。我们只需要在调用方安装一个 Agent,不需要服务方再增加至少 2 台机器搭建 HA,就可以实现负载均衡和自动容错。同时服务方增删改服务器IP和权重对调用方完全透明,为自动化伸缩和灰度带来便捷。
如果你想针对业务服务健康状态(比如业务自定义返回码)决定是否自动剔除,可以使用织云路由的高级功能,通过 API 库调用获取 IP+PORT 和主动上报服务健康状态。无论如何,织云路由一直致力于提供一套具备负载均衡和自动容错的高可用解决方案。
页: [1]
查看完整版本: 腾讯织云:如何优雅地实现高可用系统?