数人云“告别人肉运维”上海 Meetup 的实录第一弹来啦!本次分享的嘉宾是饿了么技术运营部资深专家王伟珣。从源头出发,饿了么基于架构和平台设计的"design for failure"实践,作到自动化运营和运维实践,防止人为操做失误。前端
王伟珣 / 饿了么技术运营部资深专家redis
曾是 EMC Pivotal 亚太区 CTO office 资深架构师,成功在中国和亚太各个等行业推广使用了新一代分布式数据库和 Docker 。中国移动游戏基地和视频基地平台技术负责人。拥有五项技术发明专利,国内第一代互联网建设者, GNU/Linux 开源运动和信息安全国内最先的推广者。数据库
你们好!我加入饿了么大半年了,今天分享一下饿了么在技术架构运营方面的一些实践经验,基于这个架构饿了么已经作了一两年的时间。缓存
首先,饿了么很是强调 design for failure 。饿了么如今的 IT 架构通过多年的发展,已经变得至关复杂了。在这个 IT 架构里面,要追求三个 9 、四个 9 ,甚至六个 9 。在这种复杂的软硬件架构状况下, 15 分钟以内人肉去判断故障在哪里是很难的,更况且还面临着业务的中断带来各类缘由。前有 Gitlab 这个事情人肉操做的出错,一个系统可能你要运行五年、十年甚至更长,谁都不敢担保再怎么样细心都不出错。这么多年,各类各样的软硬件 bug 、生产过程当中的质量问题都会碰到,因此纯粹是靠各类各样对人的一些约束或者 SOP ,实际上不能完全解决问题。安全
个人理念是采用负载分担多活,以分布式架构去作到 design for failure 。互联网多数会考虑负载分担多活,但实际上在广义的 IT 行业里面好比说芯片设计以及航空航天,飞机和卫星上的软硬件设计,自己也有这样的一些要求。你们若是从企业级去学习、被 IOE 洗脑的话,那么他们提这个比较少。由于要作到负载分担多活,就不会去买 IOE 那种大设备了。服务器
作到负载分担多活,能够获得的一个收益是自动容错,不管是硬件的质量问题,仍是外界环境,好比光缆挂断、掉电、软硬件的 bug ,它都可以自动断定而且自动容错切换。好比作卫星的软件,卫星发射上天,低温 110 度,高温 180 度,上天之后要工做 15 年,不能修、不能换,可想而知这个要求很高的。按照最高要求去对比,企业级的不少要求已经低得多了。若是作一个软硬件要求 15 年不能修、不能换,一直工做下去,并且环境那么恶劣,发射的时候加速度 10 到 100 个 G ,它要在实验室里面抗住 100 个 G 振动,才能抵得住发射过程当中的挑战,因此这种负载分担多活相比航空航天软件是一个不算高的要求。微信
在负载分担多活的架构上,首先要解决机房内的架构,这个架构按照业内的术语是叫 SOA 分布式架构,在这个图上看上去有点复杂,简单来说就是每一个模块其实是多个的,每一个单元它是多个负载分担,并且可以自动地扩展和容错切换。这个架构在一些友商,例如 Netflex 开源的部件里也有相似的设计理念, Google SRE 的书里面也提到了他们的作法,饿了么跟 Google 、以及你们所知的腾讯阿里也实现了相似的架构。网络
先介绍一下它工做的结构。核心是 SOAGateway 去负责后面全部服务部件互相之间的负载分担、调度、征错、容错等等。前端有一个 HTTPizza 的环节,在它外围的外层有一个 APIRouter ,它是负责广域的负载均衡,会根据一些后台的状况,基于就近规则或者是出事故的时候切换规则,把请求业务指派到某一个机房去。进到这个机房之后会有一个转换的环节,把 HTTP 协议转成高性能的二进制的 Thrift 协议,而后经过 SOAGateway ,根据调用的服务转到不一样的服务单元。全部的服务单元有一个公共的注册和健康检查的环节,还有 Service 的注册环节。在下面有几个公共的数据服务部分,好比 DBA 数据库部分,还有很是大量的 Redis Cluster 部分,以及一些异步的服务调用环节,用 mq ,饿了么有自研的 maxmq ,也有在用老的 Redis mq 。架构
在整个分布式架构里面核心是 SOAGateway ,如今也有称之为微服务的中间件,这跟已经开源了很长期的像 Spring 、 JBoss 这些中间件是不同的。 Netflex 开源了一个,有点像 v1.5 的版本,可是它还依赖 Spring ,没有完全作到彻底的语言中立化和彻底的松耦合。负载均衡
整个分布式系统如今有 1100 多个服务部件,有 7000 多台服务器,全部服务的启动、配置管理,启动的时候会自动登记,服务发现,健康检查,以及断路器、智能路由、控制总线等等都在这个中间件去作。核心是一个分布式服务架构,模块之间为了作到高性能和语言中立是用了 Thrift RPC 协议,这样就使得每个模块的开发者不用关心具体的开发语言了。内部有 PHP 、 Pyhton 、 Go 还有 Java 来作不一样的部件、不一样的模块。
design for failure 最核心的就是这个中间件,具备服务高可用性的功能,可以作到自动负载均衡、自动的熔断与容错。熔断是指某一个部件若是响应时间或者是链接数超过阀值的状况下,它会对某些请求限流,或者在有新请求的时候会把非关键业务环节临时的自动关闭掉熔断。容错是好比这个系统部署了 80 个或者 100 个服务器,部署了那么多份,但其中某一个服务器因为网络或者硬件的各类故障,由于在服务注册环节是有一个心跳检查的,包括服务本身也有一个心跳上报的机制,一旦发现某一个服务器有问题就会自动把它排除,因此对攻击、故障、网络的拥塞以及服务的过载可以自动的应对、自动的限流切换,达到服务的高可用性。
Thrift 协议是一个高性能的语言中立的协议,已经支持了各类开发语言。固然,这个分布式服务架构涉及的系统很是庞大,前面也提到有 7000 多台服务器在生产,因此配套了一个 Web 管理界面。另外,饿了么已经可以作到程序的分布式分发,如今在作 Docker 化的软件分发,有关功能正在开发中。
design for failure 是一个很重要的架构设计理念,在这个设计过程当中饿了么也有一些技术的实践。 SOA 架构或者另一个名词叫微服务化,主要是对这个服务进行有效的拆分,使得部署可以方便化,不会各个环节互相的牵扯。在整个治理服务架构的设计中,咱们也参考业内一些成功经验,业务模块基本上是先按照业务流程的 BU 再划分,根据业务来进行划分大的模块,那么由一系列的服务来组成某个 BU 的业务系统,每个服务是能够单独部署的,并且全部的这些服务版本是根据业务周期去肯定而不是说根据某一个项目。
在新一代的 SOA 架构里,强调的是强内聚弱耦合,前面提到的这些服务功能和流程逻辑是每个服务组件本身承担的,中央的 SOAGateway 只负责派发以及服务寻址等。在初次调用的时候 SOAGateway 会经过状态查询和服务注册,帮你指派到哪个服务单元,服务单元之间是 P2P 直连的。在某一些业务模块流程,它也经过 SOAGateway 集群进行派发调度。前面所说的整个 1000 多个模块的系统,它的发布、部署是由软件开发的各个小团队作 DevOps ,即整个发布系统,他们能够本身去操做。在发布过程当中,分布式架构里的灰度发布、随时回滚,发布过程也就是生产过程当中遇到各类差错跟切换的容错也是整个架构必备的一个部分。
饿了么在自研 SOAGateway 的同时,也自研了一个 Redis Cluster 的软件 Corvus ,现已开源。 Corvus 要比 Redis Cluster 官方的版本稍微早一点出来,在 Redis Cluster 架构的设计理念在部件自己也是实现了一样的分布式多活负载分担的架构,这里着重介绍一下它在数据 Cache 的层面作到数据的分片,主从同步,在磁盘作一个 AOF 的缓存等等,这样的结构来保证高性能的同时高可靠,作到多活主从,它的 slot 节点也是能够读的。
前面介绍的是单机房内的分布式多活的架构实现。另外,饿了么也在作多活的平台架构。你们每天在用的微信、 QQ 以及 3G 、 4G 网络,都是所有 IP 化的,也是由很是庞大的多机房分布式系统来为你们服务。不管打开微信也好,仍是打开饿了么也好,客户端其实会自动上报本身的一些 ID 状态,后来会有一个 Gateway ,各家可能叫法不一样,会根据用户的各类属性状态把用户派发到某一个服务的单位,好比饿了么如今初步分红南北两部分,北方用户在打开客户端连入系统的时候,没有感知地就被派发到了北京的数据中心。若是南方的话,那么就会被自动派发到了南方的数据中心。
固然,南方和北方之间是做为互备双活的,假设北京的系统挂了,最外层的 API Router 会知道,它就会把全部请求所有给派发到南方去。由于南方、北方其实都有全部用户的数据,即持久化层的数据是全量的,只是应用层服务模块的逻辑是分别部署。里面的数据复制是多活的核心环节,以后我会细讲如何作到双向的复制。南北是双活,同时又是为互备。饿了么作到了多活之后,灾备通常也达到了一样的要求,本质上是互为灾备、互为备份的。
IOE 经常讲的“两地三中心”,那个是卖盒子的作法,不是真正考虑到 design for failure 的作法。在多活的这个架构里有一个基础,必须对用户在业务入口逻辑的时候就立刻进行 sharding ,不是传统数据库 sharding ,数据库 sharding 其实是为了负载分担的而不是为了作多活的。因此在业务入口的这个环节基于业务逻辑作 sharding 之后,后面分红两个双活仍是分多活本质上没有区别了。饿了么的商家是按地域分布的,在上海作的消费请求与在北京作固然是不一样的,因此业务的逻辑就是自然分割、自然分布了。
互联网公司好比微信,也有相似的逻辑。用户连上去的时候会就进到某一个经常使用服务机房,若是用户从上海到成都,用户短时间内接入成都之后,它会帮你转到上海,但若是在成都多待了多少天,有一个后台逻辑,会把该用户持久化数据的归属主服务点切入到成都。如今 3G 、 4G 的通信网络全 IP 化了,也是有相似的结构,开户的所在地好比上海就在上海,可是到北京去之后,北京的访问登记中心会自动跟上海 HLR 链接得到用户的属性和注册,才使得用户在北京可以通话,通信网络自然也是一个多活的。
在饿了么架构里面由于涉及到比较多的商户逻辑和用户逻辑,持久化数据量比较大,核心是数据库里面有一个 DRC 的环节,承担数据复制的工做。这个工做有两个用途,一方面用户换地方的时候,好比从上海到北京,那么用户开机是连到北京的,该信息在北京也要有,因此持久化数据是全量的。前面也提到双活即灾备,起到灾备的做用。在数据复制的技术上面,是基于数据库软件层面来作的,也具备灵活性和能够作多路分发的好处,这里只是最简单的广域的双向复制功能。复制过程当中还会去通知远端 Redis Cache 的刷新,会去通知一些 mq 的状态变动,都是 N 对 N 的一个多向的功能。
最后总结一下个人理念,真正要作到整个系统让你们晚上不会老是接到电话去修故障,关键在于一开始的架构设计要设计成一个双活或者多活,使得你们的工做更加的轻松,更加不须要人肉或者紧急修理。
能够举另一个例子,好比你们有些时候会纠结安全,由于平时用的 Linux 、 Windows 在设计之初就不是安全的。在前几年出了一个 seL4 的新操做系统,它是从设计之初就考虑安全的,因此它得到了最高级的安全认证: EAL6 、世界惟一的一个最高级安全认证。从设计开源之后到如今那么多年,它是被数学证实安全的,到如今为止尚未发现它的漏洞。这就是设计出发点和设计基础不一样,因此会致使最后有不少工做的不一样。最安全的操做系统,没有人发现有安全漏洞,由于它是从新按照安全去设计的。可是, Linux 或者是 Windows ,它设计之初就是为了赶时间,不少安全没有考虑,因此后面各类各样的漏洞就被发现出来,这个例子就是基础不一样致使的结果不一样。
个人分享就到这里,谢谢你们!