网络科技

    今日:464| 主题:245747
收藏本版
互联网、科技极客的综合动态。

[其他] Monzo是如何从0开始构建7*24小时不停歇的银行后台系统的?

[复制链接]
来治猩猩的你 发表于 2016-11-30 07:25:46
33 0

立即注册CoLaBug.com会员,免费获得投稿人的专业资料,享用更多功能,玩转个人品牌!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
对于银行后台系统来说,稳定性是非常重要的;而对于移动银行来说,还需要面对数以亿计的客户。Monzo遇到的正是这种挑战,客户一方面需要7*24小时能够管理他们的钱,因此数据延时、单点故障等是不可接受的;另一方面又希望他们的需求能够很快实现。
  正因为如此,Monzo的后台系统从一开始就设计成分布式微服务架构。一些大型互联网公司(例如亚马逊、Netflix、Twitter等)的实践已经证明,独立大型应用在用户数量快速增长或者开发人员数量增长之后,会导致扩容、需求响应等一系列问题。同时,Monzo的业务发展方向,需要针对不同地区的客户进行定制化,为了提高开发效率,必须减少开发团队之间的耦合。
  Monzo后台系统开发人员最初只有3个人,必须从务实开始。最初的团队选择了他们相对熟悉的技术,确定了方向就开始构建产品,但是技术时刻在改变。
   
Monzo是如何从0开始构建7*24小时不停歇的银行后台系统的?-1 (亚马逊,Netflix,Twitter,互联网,稳定性)

  Monzo开发工作室
   当Monzo beta版本 发布的时候,他们的后台服务已经有将近100个,同时开发团队也在快速增长。此时,他们开始考虑现有系统的架构问题,梳理出以下几个着重关心的领域:
  
       
  • 集群管理:随着服务数量的增加,需要有个自动化的方式管理大量服务器、分布式任务和服务器故障;   
  • 多语种服务:在Monzo主要使用Go语言进行开发,但是没有一种语言的生态环境可以满足整个银行后台系统的需要,因此整个后台需要能够承载多种语言环境的服务;   
  • 远程调用框架:由于有大量离散的服务,分布在不同的主机、数据中心、甚至不同大陆,后台系统必须有一个强大的远程服务调用层,以处理模块故障,降低延迟,理清调用链路。   
  • 异步消息:为了提高后台系统的性能和可伸缩性,Monzo通过异步消息队列将业务逻辑放入“后台”运行,消息队列必须保证极强的可靠性,以避免消息丢失的发生。  
  下面我们就来逐一了解这些系统的详细设计和选型。
  集群管理

  Monzo系统包含大量微服务,如果一台主机上只部署一个服务,会造成对服务器的大量浪费。按照传统方式将服务器归类,会增加服务扩容的难度。因此,一个支持快速伸缩的集群调度系统,应该抽象出应用程序的运行环境,将运行环境和底层硬件进行隔离。调度算法根据应用程序负载和可用资源,对其进行扩容和缩容。另外,Monzo在设计集群管理系统时,希望能够让所有的应用程序共享一个调度器,因此它不仅需要能够调度无状态服务,还需要能够调度有状态服务。
   容器化的提出,特别是 Docker 的兴起,将前面提到的抽象层进行了标准化。首先,通过将应用程序及其运行时依赖打包成一个镜像,使得应用程序运行环境和主机解耦;然后,通过整合Linux内核的隔离特性( cgroup 、 namespace ),使得主机上运行的多个服务之间能够相互隔离,减少干扰。这样,集群管理服务对应用程序可以做到黑盒,将重心放到服务编排上去。
   Monzo最初使用 Mesos + Marathon 的架构,随后切换到了运行在 CoreOS 上的 Kubernetes 。下图展示了在切换到Kubernetes之后,整体开销的变化:

Monzo是如何从0开始构建7*24小时不停歇的银行后台系统的?-2 (亚马逊,Netflix,Twitter,互联网,稳定性)

   从上图可以看见,使用Kubernetes之后,整体开销开始下降。这是因为所有系统都共用资源池。例如,之前Monzo的构建服务搭建在独立的Jenkins服务器上,使用了Kubernetes之后,构建服务由Kubernetes根据机器可用资源分配到现有机器上。Kubernetes的 资源分配和限制模块 可以尽可能的利用机器空闲资源,并且保证低优先级的任务不会影响高优先级任务。
   另外,通过在AWS上将Kubernetes以 HA模式 部署之后,系统稳定性有了明显的增强,Monzo开始在AWS上部署类似Netflix的 Simian Army ,对生产环境服务进行破坏性操作,以验证生产环境对服务失败的容错能力。
  多语种服务

   Monzo后台系统主要使用 Go语言 编写,因为Go语言在构建低延时高并发应用程序上有先天的优势。但是一种语言很难完成整个银行后台系统的搭建,因为系统中可能会用到大量不同语言编写的开源软件,同时技术人员也会有不同的语言偏重。
  Docker的出现解决了多语种应用部署的问题,它将应用程序及其运行环境一并打包,调度系统无需关注其内部使用的具体语言。但是多种编程语言的混用,会降低代码的复用程度,因为无法再抽取公共代码成为类库相互引用。
   为了解决这个问题,Monzo将大量基础服务采用RPC的方式暴露出来,将“代码共享”变成了“基础服务共享”。例如,如果要获取一个分布式锁,无需通过客户端访问 etcd ,而只需要通过封装好的RPC接口即可。通过将基础服务(例如数据库、消息队列等)RPC化,每种新的语言只需要发起RPC调用,即可使用现有的基础服务。通过这种访问,Monzo完成了对Java、Python和Scala等语言的兼容。
  RPC框架

  上一节提到了,Monzo通过RPC的方式将基础服务暴露出去,因此它们的基础架构需要一个强大的RPC框架,以支撑其微服务架构。
  首先是传输协议,为了能够让多种语言构建的服务之间能够方面交互,HTTP协议是首选的传输协议。几乎每种语言都有实现HTTP协议的标准库,这能够降低使用门槛。
  另外,要能够支撑整个微服务架构,RPC框架还应该有以下这些特性:
  
       
  • 负载均衡:大部分HTTP库都实现了 基于DNS的轮询负载均衡 ,但是这个方式比较生硬。理想的负载均衡应该能够选择最合适的目标服务器,以达到较低的失败率,较小的延时。这样即使集群中出现因为故障而进行复制的副本,也不会影响整个系统的性能。   
  • 自动重试:对于分布式系统来说,故障是难以避免的。如果一个 幂等调用 失败,RPC系统应该要能够自动请求集群中的其他副本,以确保集群中存在少量故障节点时,系统整体仍然可用。   
  • 连接池:如果每个请求都需要重新创建连接,远程调用的延迟会大大增加。理想情况下每个远程调用请求都应该尽可能复用之前已经创建的连接。   
  • 路由:对于一个RPC系统来说,能够运行时修改目标机器是非常有必要的。例如一个新版本服务上线,可能需要一定的灰度过程。从新上限到100%使用,期间需要通过路由功能逐步将流量引到新版本服务上。  
   基于上述这些特性,Monzo最终选择了 Finagle 。它拥有上述所有特性,并且自身的模块化设计也降低了学习成本。另外,Twitter已经使用该框架多年,说明它经受了实战的考验。刚好,在今年 linkerd 发布了,它是基于Finagle的进程外代理,这意味着那些不运行在JVM上的语言也能够使用Finagle的这些特性。
   Monzo将linkerd在Kubernetes上以 守护集(daemon set) 方式部署,这样每台服务器上都会运行linkerd服务。应用服务首先和本机上的linkerd服务进行交互,然后linkerd再通过 Power of Two Choices + Peak EWMA(exponentially-weighted moving average)方式 做负载均衡。该算法通过请求往返时间和请求次数加权计算均线,然后从其中选择最优的n个结果,再从结果集中随机挑选。这种负载均衡方式兼顾了选取最优后端,又避免了因为后端失效导致的抖动。
  异步消息

  Monzo的大部分业务逻辑在后台都是通过异步消息完成的。虽然有些操作本身耗时很短,但是通过异步消息,可以更快的向用户反馈任务状态。
  由于大量核心逻辑都采取了异步化,每个消息都非常重要,一个完整业务操作每个步骤的消息都不能跳过,即使发生了无法恢复的异常,整个流程也应该能够在故障修复之后继续执行下去。因此,对于异步消息架构来说,必须满足以下特性:
  
       
  • 高可用:消息发送者在发出消息之后,无需再关注消息的消费情况。即使消费者节点或者消息系统本身出现故障,该消息也必须确保被最终消费者处理。   
  • 可扩展性:由于整个系统中会有大量消息流转,消息系统本身必须能够水平扩展。当业务压力过大时,可以像其他微服务一样简单的扩展消息系统的容量。   
  • 持久化:在任何情况下,消息系统必须保证消息不会丢失。即使出现消息系统服务器故障,或者消费者出现故障时,消息最终也能够被消费者消费。   
  • 可回放:消息系统支持回放,可以方便的重现每一个消息的处理流程,对于排查问题、故障恢复等场景非常有用。   
  • 至少一次投递:消息系统首要保证消息必须被正确消费,但是要确保投递且仅投递一次基本上是 不可能的 ,因此消息系统需要在通常情况下尽可能确保不会重复投递。  
   基于上述特性,在比较了多重消息中间件之后,Monzo最终选择了 Kafka 。虽然从架构上来看,Kafka和一般的消息中间件有着很大的不同,它更像是一个可复制的提交日志(commit log),但是它的特性刚好可以满足Monzo对于异步消息架构的要求。首先Kafka的复制和分区特性,可以满足对高可用和可扩展性的要求。其次,Kafka的消费者仅仅维护了一个消息日志中的游标,这样可以降低 发布/订阅模型 模式的成本,另外还可以通过修改游标来重新处理过去的消息。
  总结

  Kubernetes、Docker、linkerd、Kafka,Monzo通过一系列开源软件,构建了他们的7*24小时银行后台系统,其中的选型、运用对于其他系统也有一定的借鉴意义。
   感谢郭蕾对本文的审校。
   给InfoQ中文站投稿或者参与内容翻译工作,[email protected]博(@InfoQ,@丁晓昀),微信(微信号: InfoQChina )关注我们。
友荐云推荐




上一篇:The State of Front-End Tooling 2016 – Results
下一篇:Instagram isn't alerting people when you screenshot, you creep
酷辣虫提示酷辣虫禁止发表任何与中华人民共和国法律有抵触的内容!所有内容由用户发布,并不代表酷辣虫的观点,酷辣虫无法对用户发布内容真实性提供任何的保证,请自行验证并承担风险与后果。如您有版权、违规等问题,请通过"联系我们"或"违规举报"告知我们处理。

*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

我要投稿

推荐阅读

扫码访问 @iTTTTT瑞翔 的微博
回页顶回复上一篇下一篇回列表手机版
手机版/CoLaBug.com ( 粤ICP备05003221号 | 文网文[2010]257号 )|网站地图 酷辣虫

© 2001-2016 Comsenz Inc. Design: Dean. DiscuzFans.

返回顶部 返回列表