关于闲鱼:复杂系统如何在不停机升级同时保持稳定你必须考虑以下几个点

5次阅读

共计 3027 个字符,预计需要花费 8 分钟才能阅读完成。

简介: 千门万户闲鱼日,总把新桃换旧符

作者:闲鱼技术 - 兰林

背景

在互联网行业,线上服务的降级更新堪称粗茶淡饭。据统计,在过来的一个季度中闲鱼工程师们执行了千余次公布,总计更新的代码数量超过百万行。

这些公布中,有一些可能只更新了几行代码,而有一些可能执行了整个集群的迁徙降级。而无论这些变更的影响面有多大,咱们都必须保障线上服务的可用性,用户无感知。本文将以闲鱼搜寻服务的迁徙降级为例,向大家介绍其背地的技术计划。

闲鱼搜寻服务根本架构

闲鱼的底层搜寻服务由查问布局服务 Search Planner、查问了解服务 Query Planner、打分排序服务 Rank Service 以及搜索引擎 Heaven Ask 3 所组成。它们之间的互相调用关系如下图所示:

能够看到,整个搜寻服务是由多个互相独立的微服务所形成的。不同的微服务之间互相隔离,通过事后向外裸露的接口提供服务。所有的微服务最终通过 Search Planner 收口,对外提供对立、残缺的搜寻能力。

在底层搜寻服务之上,还有业务逻辑层和接入网关层,具体架构在此不再赘述。用户的搜寻申请先通过网关层转发给逻辑层解决,再向底层搜寻服务发动搜寻申请。这条申请链上蕴含数十个集群,调用深度达到两位数,整个过程中提供服务的服务器数量可能有成千盈百。

对于这样一个简单的零碎,降级过程显然无奈欲速不达。好消息是各个微服务之间正当的解耦合给降级工作带来了很大的便当,无效防止牵一动员全身而导致无从下手,使咱们能够分门别类地解决降级问题。

  • 注 1:Search Planner 是一个基于函数式、服务化、可视化、并行化开发框架所构建的搜寻服务网关层。
  • 注 2:Query Planner 的次要作用是了解用户输出,而后对搜索词进行算法优化。最终取得更好的搜寻召回后果。
  • 注 3:Rank Service 是实时打分排序服务,它的作用是依据多维度的特色对搜素引擎召回的海选后果进行算法打分。分数越高的商品就越有机会呈现在搜寻后果的前列。
  • 注 4:Heaven Ask 3(问天 3)是阿里巴巴研发的一款稳固高效、功能强大的搜索引擎。为阿里团体包含淘宝、天猫在内的外围业务提供搜寻服务反对。

放弃兼容

开始降级之前,咱们首先须要确认被降级的服务是否放弃了向前与向后兼容性。放弃兼容不仅缩小了工作量,也缩小了降级所导致的故障危险。

为了尽量避免降级导致的不兼容,咱们能够总结一些开发准则:

  • 近程过程调用(RPC)须要可能疏忽未知参数,并且容许缺失参数。
  • 如果须要删除已有参数,须要与所有依赖方确认。能够先将参数标记为 Deprecated 而不是间接移除。
  • 应用参数时,辨别缺省值和缺失值。
  • 如果接口无奈放弃兼容,则创立新接口代替旧接口。不要毁坏旧接口的兼容性。

在降级时,先降级那些没有内部依赖的服务。等到被依赖方降级结束之后,再去降级依赖方。确定了每一个服务的降级程序之后,咱们再依据服务的理论状况确定降级计划。

无状态服务降级

正式进入降级流程,咱们首先关注搜寻链路中的被设计成无状态服务的局部,例如用于解决业务逻辑的 Java 微服务、用于解决查问逻辑的 Search Planner 等。它们的独特特点是,每个申请处理完毕之后,对于该次申请的资源即被开释。不同的申请之间没有相互依赖和时序要求。同一个无状态服务内不同的机器节点是齐全等价的。

无状态服务的特点使得它们很容易通过程度扩大来动静扩缩容。因而在保障兼容的前提下,它们的降级流程绝对通用并且简略:

  1. 依据服务最小可用度决定分批数。
  2. 选取一批待更新的容器,进行服务。
  3. 批量降级容器、更新镜像。
  4. 期待这一批容器全副复原服务后,持续更新下一批容器。

一般来说咱们能够通过把状态存储在音讯队列、缓存、数据库或者其它内部中间件中来达成服务的无状态。把服务设计成无状态的益处不言而喻:降级时不须要调配额定的机器资源,降级速度快,变更代价小,因此能够反对频繁的迭代更新。然而,这种设计也给状态拜访和更新带来了额定的开销,在某些性能敏感的场合可能是不实用的。

有状态服务降级

咱们持续关注有状态的局部。有状态服务降级的麻烦之处在于,状态的存储、复原、转移往往由服务依据理论状况独自设计(或者基本没有设计),因此降级较为艰难。咱们能够简略列举一些绝对通用的有状态服务降级可选计划。

  • 接入层网关提供热更新的能力(例如 Nginx),把状态的放弃隔离在接入层外部。适宜须要长时间放弃状态的场景。
  • 渐进更新,新申请逐渐切换到新服务上解决,旧服务解决完存量申请后销毁。适宜短时间放弃状态的场景(例如游戏服务、实时音视频通信服务)。
  • 创立全新的服务正本,通过数据双写放弃新旧服务状态统一,逐渐用新服务取代旧服务。

在闲鱼搜寻的架构中,搜索引擎自身提供的尽管是无状态服务,然而引擎外部保留了用于解决索引分区,增量进度的各种状态。最终应用的降级计划如下:

  1. 应用新版本镜像创立一个齐全独立的新引擎。
  2. 新旧引擎全量数据同步。
  3. 增量数据同时向新旧引擎发送。
  4. 新引擎上线,逐渐扩充承接流量的比例。
  5. 旧引擎不再承接流量后下线。

和无状态服务的降级相比,这种形式不仅额定应用了一倍的机器资源,而且每次降级都须要做一次简单而繁琐的服务配置。如果服务自身不是无状态的,还须要自行编码实现切流逻辑,保障同一个用户的申请可能落到同一个集群上。整体降级老本较为低廉,只适宜更新频率非常低的服务。如果服务的更新频率较高,则应该依据服务的理论状况设计实现降级老本更低的计划。

服务发现

在降级过程中,服务发现机制承当着重要作用。它为咱们提供了以下性能:

  • 保障分布式一致性
  • 服务优雅高低线
  • 负载平衡
  • 流量调控与申请降级
  • 同机房优先调度
  • 跨机房容灾调度

服务发现是流量调控的总阀门。一个成熟稳固的服务发现机制不仅能够无效防止公布导致的申请成功率抖动,也为产生异样时疾速回滚止血提供了保障。

危险防控

对搜寻链路的每一个集群依照依赖程序进行服务降级、挂载、切流无疑是高危操作,稍有不慎就可能引起线上故障。因而,咱们依照阿里巴巴平安生产三板斧准则对降级流程进行了梳理:

  • 可监控
    重要链路的重要指标均提前保障监控笼罩。例如申请总量,申请成功率,申请响应时长等等。确保重大问题能够通过监控指标及时发现。
  • 可灰度
    任何变更都不容许未经灰度间接全量公布到线上。对于无状态服务,咱们个别通过调整服务发现中的权重或者调整机器比例来实现灰度放量。对于局部不能随机灰度的情景,咱们设计了按用户分批放量的机制。
  • 可回滚
    变更零碎提供了通用的一键回滚能力,但并非是最快的形式。在很多状况下,咱们在执行变更前就做好了把待更新的机器或集群在服务发现上从新挂载或移除的筹备,从问题发现到复原的工夫根本是秒级的。

总结

综上所述,简单零碎不停机降级的准则和流程能够概括如下:

  1. 服务间解耦与隔离,确保单次降级的范畴和影响可控。
  2. 依据兼容性和依赖关系决定服务的降级程序。
  3. 依据服务是否无状态决定降级形式。
  4. 提前准备好监控和回滚计划,灰度降级。

闲鱼搜寻服务降级的整个执行过程经验了两个月的工夫。这其中咱们既保证了用户无感知,线上服务稳固运行,也保障了与咱们合作开发的算法团队以及其余工程团队的失常开发不受影响。

在理论执行的过程中,咱们还遇到了很多细节上的问题。例如创立新服务时未能提前正当预估估算需要,导致降级过程中一直挪借估算,拆东墙补西墙。又比方异地多活部署带来的提早问题迫使服务放弃单元化,给降级过程中的流量调控工作带来了很多挑战。这些裸露的问题也为咱们持续欠缺架构和计划提供了指引。

心愿本次的分享可能给大家带来一些帮忙和启发。

正文完
 0