
本文作者 | 闲鱼技术-兰林
背景
在互联网行业,线上服务的升级更新可谓家常便饭。据统计,在过去的一个季度中闲鱼工程师们执行了千余次发布,总计更新的代码数量超过百万行。
这些发布中,有一些可能只更新了几行代码,而有一些可能执行了整个集群的迁移升级。而无论这些变更的影响面有多大,我们都必须保证线上服务的可用性,用户无感知。本文将以闲鱼搜索服务的迁移升级为例,向大家介绍其背后的技术方案。
闲鱼搜索服务基本架构
闲鱼的底层搜索服务由查询规划服务 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 而不是直接移除。 -
使用参数时,区分缺省值和缺失值。 -
如果接口无法保持兼容,则创建新接口代替旧接口。不要破坏旧接口的兼容性。
无状态服务升级
-
根据服务最小可用度决定分批数。 -
选取一批待更新的容器,停止服务。 -
批量升级容器、更新镜像。 -
等待这一批容器全部恢复服务后,继续更新下一批容器。
有状态服务升级
-
接入层网关提供热更新的能力(例如 Nginx),把状态的保持隔离在接入层内部。适合需要长时间保持状态的场景。 -
渐进更新,新请求逐步切换到新服务上处理,旧服务处理完存量请求后销毁。适合短时间保持状态的场景(例如游戏服务、实时音视频通讯服务)。 -
创建全新的服务副本,通过数据双写保持新旧服务状态一致,逐步用新服务取代旧服务。
-
使用新版本镜像创建一个完全独立的新引擎。 -
新旧引擎全量数据同步。 -
增量数据同时向新旧引擎发送。 -
新引擎上线,逐步扩大承接流量的比例。 -
旧引擎不再承接流量后下线。
服务发现
-
保证分布式一致性 -
服务优雅上下线 -
负载均衡 -
流量调控与请求降级 -
同机房优先调度 -
跨机房容灾调度
风险防控
-
可监控
重要链路的重要指标均提前保证监控覆盖。例如请求总量,请求成功率,请求响应时长等等。确保重大问题可以通过监控指标及时发现。 -
可灰度
任何变更都不允许未经灰度直接全量发布到线上。对于无状态服务,我们一般通过调整服务发现中的权重或者调整机器比例来完成灰度放量。对于部分不能随机灰度的情形,我们设计了按用户分批放量的机制。 -
可回滚
变更系统提供了通用的一键回滚能力,但并非是最快的方式。在很多情况下,我们在执行变更前就做好了把待更新的机器或集群在服务发现上重新挂载或移除的准备,从问题发现到恢复的时间基本是秒级的。
总结
-
服务间解耦与隔离,确保单次升级的范围和影响可控。 -
根据兼容性和依赖关系决定服务的升级顺序。 -
根据服务是否无状态决定升级方式。 -
提前准备好监控和回滚方案,灰度升级。
更多精彩

识别二维码立即体验
阿里CTO鲁肃:技术的想象力不应设限,未来所有应用的核心都离不开数据和智能
云栖大会第一天,我们生了头“驴”和“无影”!


点此阅读作者更多好文!



