支撑 “千万设备日活” 的创米数联 7 年微服务架构演进之路

本文涉及的产品
性能测试 PTS,5000VUM额度
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 支撑 “千万设备日活” 的创米数联 7 年微服务架构演进之路

作者:金兆旭 上海创米数联智能科技发展股份有限公司云服务开发及 SRE 工程师 负责公司云端基础设施构建及消息网关等研发工作;十眠


创米数联是小米生态链首批亿元俱乐部成员,主营业务为智能家居产品的研发、设计、生产和销售,致力于成为以居家安全为核心的产品和服务提供商,提供多品类的全屋智能家居产品及服务。公司以居家安全为核心,洞察用户在居住环境下的智能化需求,建立物理安全、环境安全、系统安全三类场景及服务体系,主要产品包括智能摄像机、智慧门、智能猫眼、智能门铃、智能插座等。公司旨在实现“看得见的全屋智能”,以智能家庭安全为切入点,提供多品类覆盖的智能家居解决方案。截至 2021 年 12 月 31 日,创米数联已经在全世界 150 多个国家,销售了超过 5500 万台设备,拥有了 1600 万设备和 500 万设备用户日活。


作为小米生态链的一员,创米采用微服务架构支撑其千万日活的 IOT 设备。随着智能家居市场的快速迭代,创米面临着发布和迭代的稳定性挑战,同时需要解决多方 IOT 接入面临的性能和安全挑战。本文将为您一一道来创米是如何应对这些挑战的。


云计算时代的蹒跚学步


创米云服务从 2016 年创始之初就选择了云计算+微服务的技术路线,以应对面临的大量线上用户和设备带来的流量挑战。构建微服务之初,市面上可选用的解决方案并不多,我们自主实现了一些微服务组件,如 frontend 业务网关和配置中心,并在小米生态云上部署容器服务来处理设备消息、设备插件 API 和微信公众号等相关业务,并利用 HPA 及 CronHPA 等容器弹性伸缩策略来应对动态的海量线上流量。


image.png


自此创米数联在云计算时代踏上了探索服务容器化的第一步。


新业务及新挑战

从 2019 年伊始,创米数联提出了研发自有 APP 和适配自有 APP 的智能家居设备的发展战略。云服务部将研发重心转向自有 APP 云端业务,并逐步接入自有品牌设备。为了实现全球业务,创米云服务部将相关服务部署在阿里云的 4 个 Region 的 ACK Pro 专有版 Kubernetes 集群上。阿里云 ACK 为创米云提供了可靠稳定的基础设施,向下封装好的数十款云产品,降低了云端运维人员的运维压力,快速对接其他云产品的能力也对开发人员十分友好,能够让创米云服务在极短的时间内搭建一套线上可用的环境。


在自有业务研发开始阶段,我们选择了 Spring Cloud、Eureka 和 Apollo 等技术栈来搭建我们的微服务基础架构。然而,经过一年半的摸索,我们发现当前的混合架构存在着不稳定、上线部署风险大以及高人力维护成本等问题。


因此,从 2021 年开始,创米云服务决定改变现有的微服务架构,逐步拥抱云原生。我们的目标是在满足稳定性和低维护成本等需求的基础上,实现所有组件的可观测性、全链路的流量治理以及更加便捷高效的 DevOps 流程。


云原生体系探索

首先我们将当前的 Spring Cloud 体系全面转向 Spring Cloud Alibaba,使用 Nacos 替换 Eureka,以解决 Eureka 服务端压力过大的问题,并满足单注册中心多环境分组的需求。由于 Apollo 在某些情况下存在容器磁盘压力大的问题,我们逐步将配置中心从 Apollo 替换为 Nacos。针对之前定制化的 Apollo 配置同步和本地特殊配置缓存,同样我们也对 Nacos 客户端进行了部分定制化改造。


image.png


初版上线时,考虑到注册中心和配置中心的高可用性、热升级、成本、可观测配套等因素,我们没有选择自建有状态的开源 Nacos 服务,而是直接使用了阿里云 MSE Nacos 专业版服务。至今,该服务一直稳定运行,没有出现可用性问题。


全链路流量治理

针对全链路的流量治理,由于创米云服务所处的 AIoT 行业不同于传统互联网行业,我们在南北向流量时不仅需要治理下游用户手机端 APP 及 Web 端的 HTTP 请求,还需要处理来自设备端的 MQTT、第三方 AMQP 和 HTTP 2 长连接 Push 消息的流量治理。这些消息通常经由统一的上游消息网关(消息总线)监听,经过多级过滤器,如消息来源、消息限流和产品或特定设备级别的白名单等,对消息进行分类和打标签,然后对消息 Topic 正则路由并进行 HTTP 异步或 rpc 请求。只有经过这些请求后,我们才能对其进行流量治理。



因此,创米云服务的流量治理整体较为复杂。我们曾考虑过采用侵入式代码和自定义负载均衡器,并开发控制台来实现高度自定义的流量方案。我们还考虑过使用 Istio Service Mesh 的方案治理流量。然而,前者在当前百万级别设备消息的情况下性能严重受限,后者由于设备消息链路较长、打标较多,导致实现全链路灰度时配置文件实现较为复杂,而且 Envoy 代理无法完整拦截消息总线请求等问题,因此我们否定了这两种方案。之后在选型过程中,我们采用了 MSE 微服务治理。


我们传统的 API 业务流量治理选用了多域名、多租户环境、节点隔离加多业务网关的方案配合 MSE 微服务治理来实现多个环境服务的测试开发及线上灰度部署。我们使用多域名加 DNS 流量划分的方式对服务重构后的业务网关新路由进行测试,保证服务重构后的安全上线。我们利用多个 K8s 集群、K8s namespace 以及多个 namespace 的注册配置中心的隔离构建了不同的线上环境,分别用来线上开发、线上测试、灰度以及基线环境部署。对于同一集群不同 namespace 的应用 pod 使用多集群隔离、应用节点亲和性、反亲和性以及节点污点等集群调度手段保证环境的安全性,避免不同环境间出现的资源异常导致基线环境不可用的情况。基线环境和灰度环境同属不同命名空间的相同节点池内,测试和开发环境应用 pod 部署在不同的 K8s 集群或节点池中。我们的整体流程通常是在 feature 及 bug 修复后涉及的服务在开发环境联调完毕,在每次测试流程前将 feature 服务部署至测试环境,通过蓝绿测试将测试人员的流量导向测试环境,在多轮的覆盖及回归测试完成后,将服务部署至灰度环境,再将测试人员及 Beta 测试用户的流量导向灰度环境,经过一定时间的检验后,逐步将线上基线流量导向灰度环境,灰度环境流量完成 100% 灰度后,替换基线环境镜像,最后逐步将灰度流量倒流至基线环境。



在核心业务接入 MSE 微服务治理之后,创米云服务对部分多云部署及老项目通过 DNS 流量切分+全链路灰度的方式进行灰度,逐渐将自有 APP 及自有设备的所有业务重构迁移至新项目中并全部接入 MSE 微服务,实现了云上 API 业务的 100% 安全发布。


在设备消息业务的流量治理的推进过程中,为了解决无法拦截消息请求的问题,我们首先将消息总线拆分为控制器和路由器两部分。控制器监听各个通道的消息后仅对消息进行打标签和分类,然后通过异步 HTTP 请求经由统一的路由器转发到各个服务中。我们将路由器服务定义为流量治理的入口,从而解决了消息无法治理的问题。然后,我们使用统一的全链路灰度对打标签后的 HTTP 请求进行蓝绿和灰度的流量治理,并将其分发到指定的命名空间的指定服务中进行消息处理。


MSE 微服务治理接入非常简单,只需要在 Helm 或组件中心安装 ack-onepilot 组件,重启服务便可自动注入服务,除此之外 MSE 提供了较为友好的全链路灰度配置界面,较 Istio 方案更加易于配置和上手。通过这样的流程,创米云服务成功实现了设备服务的更新、云云设备的对接以及固件 OTA 版本的迭代过程中的安全发布。


无损上下线解决发布扩缩容流量损失问题


无损下线逻辑图


在之前的服务发版部署或 pod 弹性伸缩过程中经常会有部分请求出现超时或不可用的情况,由于创米云服务承载了大量的用户设备请求,这些流量损失轻则导致设备消息重试,严重时会影响部分用户设备的可用性,后续我们了解了 MSE 微服务治理提供了无损上下线及服务预热功能,决定将相关服务全部接入了 MSE 微服务治理的无损上下线,并调整对应服务的就绪检查,在后续的服务上下线过程中经观察再未出现因为流量损失导致的请求不可用的情况,一定程度上避免了由部署发布和服务缩容引起的线上流量损失问题。

image.png

新启动 Pod 的预热流量分布


可观测体系

为了实现可观测性,我们早期就将阿里云 SLS 日志服务集成到自有业务框架中。然而,我们遇到了业务索引不规范、唯一 RequestId 索引异步丢失以及 Spring Cloud Gateway 等 Reactive 框架应用日志异步写入 Location 导致 CPU 占用过高等问题。因此,我们对当前的日志规范进行了改进,并在多个链路追踪方案中选择了 Skywalking。我们将 Skywalking 的 TraceId 写入 SLS 日志索引中,并通过对 ThreadLocal 的改造实现了异步线程的日志索引信息传递。我们的服务挂载了 Skywalking Agent,并自定义了可选插件,然后接入了阿里云链路追踪服务。相比自建 ElasticSearch 集群,阿里云链路追踪服务更经济实惠且免维护,链路追踪服务可以直接将项目关联到指定的 SLS logstore 中,更方便进行链路问题排查。在上线的第一个月里,链路追踪服务帮助我们解决了多个项目中的接口性能问题。


创米云服务的指标信息的观测主要依赖于 ARMS ACK、ARMS ACK Pro、ARMS 云服务等多个开箱可用的 Grafana Dashboard,它们提供了相当完善的集群、Node、Pod 等多个维度的指标信息,除此之外我们依然会使用阿里云云监控或自定义一些 Grafana Dashboard 用来关注其他部分指标。创米云服务为了快速预警,设置了云产品、SLS 日志、K8s 事件等多个维度的告警配置,对报警进行降噪调优,根据告警等级设置了电话、短信、邮件和飞书群多个通道的报警通知,建立了相当全面的服务告警体系,以便相关人员及时发现问题,避免线上损失。


CI/CD 提效

早些时候由于多云部署的问题,我们并没有统一的全自动 CI/CD 解决方案,为了解决云端 DevOps 构建部署和上线安全性等问题,我们将所有的 Devops 流程开始全面转向阿里云云效。首先,我们将云服务代码从自建的 Gitlab 完全同步到阿里云 CodeUp 代码库中,并将之前的 Gitlab CI/CD 和 Jenkins 的 CI/CD 方案全部迁移到阿里云云效流水线。我们建立了单 Region、多 Region、多云项目的多条流水线,实现了从代码提交、手动或自动触发构建,到自动部署到指定的 K8s 集群和命名空间的全流程。每次构建和部署完成后,我们会发送飞书通知并调用 Newman 自动化测试脚本的 WebHook,根据自动化测试结果报告,评估每次服务版本发布是否满足安全规范。


稳定性评估与演练

对于线上环境稳定性评估,创米云服务选用了混沌工程的方式来检验服务的可用性,创米云服务根据自身业务对 Java 应用 OOM、缓存击穿、网络延迟、K8s Pod 资源、K8s 系统组件、关键云服务等多个维度对自身环境的服务进行全方位的演练排查,并检验可观测性中告警配置的灵敏度。我们在没有造成线上损失的情况下发现并修复了部分漏洞、完善了多 AZ 的云服务资源的建设、调整了未触发告警的配置,使自身架构更加健壮。在一定程度上帮助创米云服务在及时弥补了在 HA 方面不足,并在后续的架构设计中提出了高可用优先的原则。


未来展望


未来创米云服务将业务网关逐渐转型为云原生网关+WASM 插件方案,代替繁重的 Spring Cloud Gateway 业务网关,进一步提升网关性能、灵活性和可扩展性,并接入现有可观测体系。我们将继续致力于创新和技术升级,为用户提供更优质的产品体验。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
6天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。
|
4天前
|
Cloud Native 安全 数据安全/隐私保护
云原生架构下的微服务治理与挑战####
随着云计算技术的飞速发展,云原生架构以其高效、灵活、可扩展的特性成为现代企业IT架构的首选。本文聚焦于云原生环境下的微服务治理问题,探讨其在促进业务敏捷性的同时所面临的挑战及应对策略。通过分析微服务拆分、服务间通信、故障隔离与恢复等关键环节,本文旨在为读者提供一个关于如何在云原生环境中有效实施微服务治理的全面视角,助力企业在数字化转型的道路上稳健前行。 ####
|
8天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
44 6
|
8天前
|
设计模式 Java API
微服务架构演变与架构设计深度解析
【11月更文挑战第14天】在当今的IT行业中,微服务架构已经成为构建大型、复杂系统的重要范式。本文将从微服务架构的背景、业务场景、功能点、底层原理、实战、设计模式等多个方面进行深度解析,并结合京东电商的案例,探讨微服务架构在实际应用中的实施与效果。
25 1
|
15天前
|
弹性计算 Kubernetes Cloud Native
云原生架构下的微服务设计原则与实践####
本文深入探讨了在云原生环境中,微服务架构的设计原则、关键技术及实践案例。通过剖析传统单体架构面临的挑战,引出微服务作为解决方案的优势,并详细阐述了微服务设计的几大核心原则:单一职责、独立部署、弹性伸缩和服务自治。文章还介绍了容器化技术、Kubernetes等云原生工具如何助力微服务的高效实施,并通过一个实际项目案例,展示了从服务拆分到持续集成/持续部署(CI/CD)流程的完整实现路径,为读者提供了宝贵的实践经验和启发。 ####
|
4天前
|
Dubbo Java 应用服务中间件
服务架构的演进:从单体到微服务的探索之旅
随着企业业务的不断拓展和复杂度的提升,对软件系统架构的要求也日益严苛。传统的架构模式在应对现代业务场景时逐渐暴露出诸多局限性,于是服务架构开启了持续演变之路。从单体架构的简易便捷,到分布式架构的模块化解耦,再到微服务架构的精细化管理,企业对技术的选择变得至关重要,尤其是 Spring Cloud 和 Dubbo 等微服务技术的对比和应用,直接影响着项目的成败。 本篇文章会从服务架构的演进开始分析,探索从单体项目到微服务项目的演变过程。然后也会对目前常见的微服务技术进行对比,找到目前市面上所常用的技术给大家进行讲解。
15 1
服务架构的演进:从单体到微服务的探索之旅
|
3天前
|
Cloud Native 安全 API
云原生架构下的微服务治理策略与实践####
—透过云原生的棱镜,探索微服务架构下的挑战与应对之道 本文旨在探讨云原生环境下,微服务架构所面临的关键挑战及有效的治理策略。随着云计算技术的深入发展,越来越多的企业选择采用云原生架构来构建和部署其应用程序,以期获得更高的灵活性、可扩展性和效率。然而,微服务架构的复杂性也带来了服务发现、负载均衡、故障恢复等一系列治理难题。本文将深入分析这些问题,并提出一套基于云原生技术栈的微服务治理框架,包括服务网格的应用、API网关的集成、以及动态配置管理等关键方面,旨在为企业实现高效、稳定的微服务架构提供参考路径。 ####
23 5
|
6天前
|
监控 API 微服务
后端技术演进:从单体架构到微服务的转变
随着互联网应用的快速增长和用户需求的不断演化,传统单体架构已难以满足现代软件开发的需求。本文深入探讨了后端技术在面对复杂系统挑战时的演进路径,重点分析了从单体架构向微服务架构转变的过程、原因及优势。通过对比分析,揭示了微服务架构如何提高系统的可扩展性、灵活性和维护效率,同时指出了实施微服务时面临的挑战和最佳实践。
25 7
|
5天前
|
Kubernetes 负载均衡 Cloud Native
云原生架构下的微服务治理策略
随着云原生技术的不断成熟,微服务架构已成为现代应用开发的主流选择。本文探讨了在云原生环境下实施微服务治理的策略和方法,重点分析了服务发现、负载均衡、故障恢复和配置管理等关键技术点,以及如何利用Kubernetes等容器编排工具来优化微服务的部署和管理。文章旨在为开发者提供一套实用的微服务治理框架,帮助其在复杂的云环境中构建高效、可靠的分布式系统。
19 5
|
5天前
|
负载均衡 监控 Cloud Native
云原生架构下的微服务治理策略与实践####
在数字化转型浪潮中,企业纷纷拥抱云计算,而云原生架构作为其核心技术支撑,正引领着一场深刻的技术变革。本文聚焦于云原生环境下微服务架构的治理策略与实践,探讨如何通过精细化的服务管理、动态的流量调度、高效的故障恢复机制以及持续的监控优化,构建弹性、可靠且易于维护的分布式系统。我们将深入剖析微服务治理的核心要素,结合具体案例,揭示其在提升系统稳定性、扩展性和敏捷性方面的关键作用,为读者提供一套切实可行的云原生微服务治理指南。 ####