我们前台容错的秘诀

现代银行如何安排? 有一个后台办公室,执行各种操作,保留帐户和报告。 有一个中级办公室,负责决策和评估风险,评估信用风险并打击欺诈者。 还有一个前台办公室,他们在这里为客户提供服务,并负责通过各种渠道与银行互动。



Sberbank有数百个具有不同可用性和可靠性的系统。 它具有自己的开发以及具有不同程度的定制,不同的SLA的盒装解决方案。 所有系统都以多种方式相互集成。 在这篇文章中,我们将向您介绍整个前端蚂蚁山的建造方式,以提供持续的客户服务。

让我们从理论开始。 可以从潜艇借鉴构建故障安全系统的关键原理:

  1. 潜艇分为独立的舱室。 如果一个隔间被淹没,其余的仍然生存。
  2. 保留所有关键组件。 发动机,氧气罐。 甲壳虫乐队还保留了带有舷窗的潜望镜。
  3. 潜水艇受到保护,免受水面中的严酷条件影响-如有必要,它可以更深入地工作,好像什么也没发生。

我们以实践为例来说明第一个原理。 我们有一个分布式缓存系统。 一旦加载,其中一个缓存数据节点就会发生故障。 没关系:为了维持正确的复制,控制器将数据重新分配给其余节点。 但是,由于重新分配,网络流量猛增,数据包开始丢失-包括缓存开销。 某个时刻,控制器决定另一个数据节点出现故障,再次重新分配数据,流量增加了……结果,在不到一分钟的时间内,系统完全瘫痪了。 幸运的是,这是一个负载电路,没有人受伤。 但是我们花了很多时间寻找原因。

可以说,集群数据库和高端服务器不会发生这种情况-在硬件级别内置了冗余。 引用亚马逊CTO Werner Vogels的话:“一切总是失败。” 我们跌倒了数据库集群和高端服务器。 由于配置错误,由于管理软件中的问题而失败。 随着每个问题的解决,我们对此类解决方案的信心下降。 结果,我们得出的结论是:只有那些被划分为彼此独立的部分(主要是在管理方面独立)的系统才不会拒绝。

多块架构


解决我们问题的方法是多块体系结构。 在其中,所有硬件组件(包括数据库)都分为松散耦合的,几乎独立的块。 每个块都作为客户端的一部分,就像在数据库中分片时一样。 每个块内的节点都在所有级别(包括地理冗余)上保留。 一个区块中的任何问题都不会影响其他区块。 随着客户数量的增加,我们可以轻松添加新模块并继续正常工作。


通用块架构。 所有块均根据2N方案保留。 每个数据中心都有一个功能强大的硬件负载平衡器。 数据中心通过2-3个独立的通信通道连接。

服务器按五种类型的块分布:

  • 路由器-将客户端分发到其余单元的控制单元
  • 客户区-服务多达1000万客户的主要区
  • 试点-我们在这里测试忠实客户的新版本应用程序(大约30万人,主要是Sberbank员工)
  • 来宾单元-通过它来为未经身份验证的用户提供服务; 例如,那些通过网站访问的人
  • 备用块-一个足以立即替换两个客户端块的安全块

在每个块内,应用程序服务器和Web服务器由服务通道分隔开,但是数据库是公用的。 因此,我们可以隔离最常见的故障情况,以使它们不会超出我们的渠道范围。

如何运作?


首先,用户进入路由器单元。 该块检查该人所属的客户端块,并将其发送到该客户端块(或发送给来宾块)。 此外,一个人在自己的街区内冷静地工作。 如果本机单元发生故障,该人员将返回路由器并自动接收到备用单元的指导以进行进一步的工作。

操作期间数据会怎样? 有关客户与银行互动的信息会不断从客户区复制到存档数据库。 遇到用户后,备份单元会从存档数据库中提取有关他的必要信息,并在必要时提供数据-因此,当我们遇到问题时,用户不会冻结。

在备份单元中执行的操作存储在其中。 恢复用户的本机客户端块后,它会返回。 备份块中累积的操作将异步传输到必要的客户端块。 当数据减少到一致性时,客户端会看到一条消息,指出已接受并保存了所有操作,但是由于技术工作,最新的操作可能不会显示。


系统总体方案

在某些情况下,预先计划切换到备份块-例如,在客户端块中进行更新时。 然后,备份单元不接听客户端会话,但是在某个时刻,它只是开始所有新操作。 如果紧急需要切换到备份单元,管理员可以禁用所有会话。 在这种情况下,用户会话将被中断,他将在备用设备上启动一个新会话。 顺便说一下,路由器单元有自己的专用备份单元。 因此,没有人没有备用轮胎。

系统更新


新软件版本首先部署在试验块上,并显示给有限的听众。 然后逐渐在客户端块上,并且已经在最后-在备用块上。 因此,如果新版本的软件在客户端块中存在问题,我们可以将客户端从旧版本转移到备份块。

当新功能滚动到块上时,它不会自动打开。 管理员使用复选框-功能切换来执行此操作。 您可以按组将客户切换到新版本-这是我们检查更新对受众增长的反应的方式。

自治权


我们的系统本身是可靠的,但仍取决于用于操作的后端。 如何保护自己免受问题困扰? 我们使用三种工具。

  1. 待处理的请求 。 客户端请求完成操作。 我们将其保存在数据库中,然后尝试在后端执行它。 如果后端没有响应,我们会向客户端显示一条消息,表明该操作已被接受并且正在处理中。 当后端上升时,一个单独的“码头工人”从数据库中读取未完成的操作,然后将其“推送”到后端系统中的批处理中。 为了不使主表过载具有大量低效率查询的操作,我们另外使用了所谓的令牌表-不完整操作的标识符列表。 为了不删除刚刚增加了数十万个操作的后端,我们使用批处理-我们删除200个操作并等待例如几秒钟。



    但是,如果用户的请求和后端恢复之间发生了重要的变化该怎么办? 例如,汇率有变化吗? 在这种情况下,将触发双重验证。 这些操作在输入时被保存,然后在执行时进行验证。 如果没有收敛,则将调整或拒绝该操作。
  2. 数据缓存 。 例如,当用户输入Sberbank Online时,关于该用户的所有必要信息都已经可见-账单,卡,贷款等。 通过服务总线从十几个系统中请求此数据。 如果迅速收集了响应,则在几秒钟内,我们会将数据显示给客户端,并将其保存在数据库的系统缓存中。 如果不是,则我们在数据库中查找以前缓存的数据,并将其显示给客户端。 当然,为此,缓存必须不超过特定年龄。 但是,当服务总线按需收集必要的数据时,它将在数据库缓存中进行更新并发送给客户端,而不是发送给客户端。

    使用该应用程序时,这意味着一个人在输入后几秒钟会看到其帐户状态。 尽管数据可能有些过时。 如果发生这种情况,则通常在几秒钟后将数据替换为实际的数据-这意味着服务总线已收集了您所需的一切。

    此外,我们已经使用复制进行了预缓存。 主要用于不同的参考数据。 我们将此数据预加载到后端,客户端平静地发出操作请求,然后将其发送。 即使负责维护数据的系统无法正常工作,用户也不必再次等待。
  3. 技术中断 。 如果后端系统崩溃或正在维护,我们会对其进行标记。 然后,拒绝通过它会立即执行通过它的操作。 因此,我们可以避免应用程序服务器因请求等待超时而溢出请求。 在这种模式下,可以使用我们前面介绍的操作和数据缓存。 由管理员手动或自动根据请求数为每个集成方案设置技术中断。




在任何情况下,我们都试图将用户的期望降到最低-如果出现问题,他会立即收到有关无法操作的消息。 我们尝试将此类消息的数量减至最少,因此,我们增加了某些缓存数据的寿命-这使我们能够扩展与银行服务的正常交互。

在某些情况下,不应取消缓存-例如,在发行现金时。 客户可能会欺诈。 ATM和分支上的此类操作不会被缓存。 在网上银行,这更容易-我们接受该应用程序,然后对其进行处理或拒绝它。

如此一来,遵守本文中描述的原理,您可以获得的系统的可用性为99.99%或更高。

我们的计划


现在,计划是在考虑到渠道的技术和业务特征的情况下,最大程度地缩短单个系统的上市时间,以确保全渠道性。 并且还可以迁移旧系统,同时在迁移过程中保持其可操作性。

我们感谢罗曼·谢霍夫佐夫(Roman Shekhovtsov)在职位准备方面的积极协助

Source: https://habr.com/ru/post/zh-CN419815/


All Articles