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

本文涉及的产品
Serverless 应用引擎 SAE,800核*时 1600GiB*时
云原生网关 MSE Higress,422元/月
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 支撑 “千万设备日活” 的创米数联 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搭建和管理企业级网站应用
相关文章
|
10天前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
10天前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
12天前
|
JSON 监控 安全
探索微服务架构中的API网关模式
【9月更文挑战第22天】在微服务架构的海洋中,API网关如同一位智慧的守门人,不仅管理着服务的进出,还维护着整个系统的秩序。本文将带你一探究竟,看看这位守门人是如何工作的,以及它为何成为现代云原生应用不可或缺的一部分。从流量控制到安全防护,再到服务聚合,我们将一起解锁API网关的秘密。
|
22天前
|
运维 Cloud Native Devops
云原生架构的崛起与实践云原生架构是一种通过容器化、微服务和DevOps等技术手段,帮助应用系统实现敏捷部署、弹性扩展和高效运维的技术理念。本文将探讨云原生的概念、核心技术以及其在企业中的应用实践,揭示云原生如何成为现代软件开发和运营的主流方式。##
云原生架构是现代IT领域的一场革命,它依托于容器化、微服务和DevOps等核心技术,旨在解决传统架构在应对复杂业务需求时的不足。通过采用云原生方法,企业可以实现敏捷部署、弹性扩展和高效运维,从而大幅提升开发效率和系统可靠性。本文详细阐述了云原生的核心概念、主要技术和实际应用案例,并探讨了企业在实施云原生过程中的挑战与解决方案。无论是正在转型的传统企业,还是寻求创新的互联网企业,云原生都提供了一条实现高效能、高灵活性和高可靠性的技术路径。 ##
29 3
|
26天前
|
监控 负载均衡 应用服务中间件
探索微服务架构下的API网关设计与实践
在数字化浪潮中,微服务架构以其灵活性和可扩展性成为企业IT架构的宠儿。本文将深入浅出地介绍微服务架构下API网关的关键作用,探讨其设计原则与实践要点,旨在帮助读者更好地理解和应用API网关,优化微服务间的通信效率和安全性,实现服务的高可用性和伸缩性。
38 3
|
1月前
|
存储 Java Maven
从零到微服务专家:用Micronaut框架轻松构建未来架构
【9月更文挑战第5天】在现代软件开发中,微服务架构因提升应用的可伸缩性和灵活性而广受欢迎。Micronaut 是一个轻量级的 Java 框架,适合构建微服务。本文介绍如何从零开始使用 Micronaut 搭建微服务架构,包括设置开发环境、创建 Maven 项目并添加 Micronaut 依赖,编写主类启动应用,以及添加控制器处理 HTTP 请求。通过示例代码展示如何实现简单的 “Hello, World!” 功能,并介绍如何通过添加更多依赖来扩展应用功能,如数据访问、验证和安全性等。Micronaut 的强大和灵活性使你能够快速构建复杂的微服务系统。
61 5
|
9天前
|
Kubernetes Go Docker
掌握微服务架构:从Go到容器化的旅程
摘要,通常简短概述文章内容,要求精炼。在本文中,我们将打破常规,采用一种故事化叙述的摘要,旨在激发读者的好奇心和探究欲: “从宁静的海滨小城出发,我们踏上了一场技术探险之旅,探索微服务架构的奥秘。我们将学习如何用Go编写微服务,以及如何通过Docker和Kubernetes将它们打包进小巧的容器中。在这场旅程中,我们将遇到挑战、收获知识,最终实现应用的快速部署与可扩展性。”
|
10天前
|
Cloud Native Java 对象存储
揭秘微服务架构之争:Spring Cloud与Netflix OSS巅峰对决,谁将称霸弹性云原生时代?
近年来,微服务架构成为企业应用的主流设计模式。本文对比了两大热门框架Spring Cloud和Netflix OSS,探讨其在构建弹性微服务方面的表现。Spring Cloud依托Spring Boot,提供全面的微服务解决方案,包括服务注册、配置管理和负载均衡等。Netflix OSS则由一系列可独立或组合使用的组件构成,如Eureka、Hystrix等。两者相比,Spring Cloud更易集成且功能完善,而Netflix OSS则需自行整合组件,但灵活性更高。实际上,两者也可结合使用以发挥各自优势。通过对两者的对比分析,希望为企业在微服务架构选型上提供参考。
30 0
|
18天前
|
缓存 负载均衡 数据管理
深入探索微服务架构的核心要素与实践策略在当今软件开发领域,微服务架构以其独特的优势和灵活性,已成为众多企业和开发者的首选。本文将深入探讨微服务架构的核心要素,包括服务拆分、通信机制、数据管理等,并结合实际案例分析其在不同场景下的应用策略,旨在为读者提供一套全面、深入的微服务架构实践指南。**
**微服务架构作为软件开发领域的热门话题,正引领着一场技术革新。本文从微服务架构的核心要素出发,详细阐述了服务拆分的原则与方法、通信机制的选择与优化、数据管理的策略与挑战等内容。同时,结合具体案例,分析了微服务架构在不同场景下的应用策略,为读者提供了实用的指导和建议。
|
2月前
|
数据库 Java 数据库连接
Hibernate 实体监听器竟如魔法精灵,在 CRUD 操作中掀起自动化风暴!
【8月更文挑战第31天】在软件开发中,效率与自动化至关重要。Hibernate 通过其强大的持久化框架提供了实体监听器这一利器,自动处理 CRUD 操作中的重复任务,如生成唯一标识符、记录更新时间和执行清理操作,从而大幅提升开发效率并减少错误。下面通过示例代码展示了如何定义监听器类,并在实体类中使用 `@EntityListeners` 注解来指定监听器,实现自动化任务。这不仅简化了开发流程,还能根据具体需求灵活应用,满足各种业务场景。
32 0
下一篇
无影云桌面