云原生架构常用模式解析:服务化、Service Mesh、Serverless等

探讨云原生架构中的服务化、Service Mesh、Serverless等常用模式,助力构建弹性、可扩展的云原生应用。

原文标题:云原生架构中几种常用架构模式

原文作者:牧羊人的方向

冷月清谈:

本文介绍了云原生架构中几种常用的架构模式,包括服务化架构、服务网格(Service Mesh)、Serverless架构、存储计算分离架构、可观测架构、分布式事务模式和CQRS读写分离模式以及EDA事件驱动架构。服务化架构通过接口契约和微服务实现系统解耦和弹性伸缩;服务网格将微服务通信逻辑下沉到基础设施层,实现业务逻辑与网络治理解耦;Serverless架构以事件驱动函数为核心单元,实现全托管式自动弹性伸缩;存储计算分离架构通过解耦计算节点和存储节点,提升资源利用率;可观测架构通过整合指标、日志、追踪三大支柱构建深度系统洞察力;分布式事务模式解决微服务架构中数据一致性问题;CQRS读写分离模式分离读写操作,优化读写性能;EDA事件驱动架构通过事件实现服务间的松耦合和异步通信。这些架构模式共同构成了云原生应用的基础,帮助开发者构建弹性、可扩展、易于管理的云原生应用。

怜星夜思:

1、文章提到了服务网格降低了分布式系统的复杂度,那么在实际应用中,引入服务网格会带来哪些新的挑战?比如运维、性能等方面。
2、Serverless架构虽然看起来很美好,但它的冷启动问题一直被人诟病。除了文章提到的Redis缓存外,还有哪些方法可以缓解冷启动带来的性能影响?
3、文章提到了CAP理论,在分布式事务中需要在一致性、可用性和分区容错性之间做出权衡。那么,在实际业务场景中,我们应该如何选择合适的分布式事务模式?有没有一些通用的原则或者经验?

原文内容

基于服务化、弹性扩缩容、可观测和自动化等设计原则的引入,传统的应用架构由单体应用逐步向云原生架构发展。云原生技术架构迭代逐步演化为服务化架构、服务网格Mesh、Serverless架构、EDA事件驱动和可观测等架构模式。本文对这几种主要的架构模式进行简要的介绍。

1、云原生架构模式
1.1 服务化架构

服务化架构的核心在于通过接口契约定义服务单元的功能,实现服务间的高效通信。例如,通过服务接口定义、IDL(接口定义语言)和OpenAPI等技术规范服务接口,确保服务间的互操作性。服务化通常是通过微服务化技术实现,通过将单体应用拆分为独立部署的小型服务实现系统解耦,每个服务聚焦单一业务能力并拥有专属技术栈和数据库,支持异构技术选型(如Java/Go/Python等)。服务间通过轻量级API(REST/gRPC)通信,摒弃传统ESB中心化治理,实现去中心化协作。该架构赋予服务独立演进能力,支持按需扩缩容和持续交付,显著提升系统弹性(单点故障隔离)和迭代效率。不过微服务化架构也引入了分布式事务一致性、跨服务监控等复杂性,需配合服务网格、容器化等技术降低运维成本。

1.2 服务网格(Service Mesh)

服务网格以基础设施层形式抽象微服务通信逻辑,通过Sidecar代理(如Envoy)接管流量管理,使业务代码无需嵌入网络策略。其核心在于分离数据平面(处理流量路由、负载均衡、TLS加密)和控制平面(如Istio统一配置熔断、重试策略)。该架构提供透明的可观测性,自动生成服务依赖拓扑和实时指标(延迟/错误率),并基于mTLS实现零信任安全。服务网格彻底解耦业务逻辑与网络治理,大幅降低分布式系统复杂度,是规模化微服务架构的基石。

通过Service Mesh技术,实现了业务逻辑和非业务逻辑的分离,为应用的轻量化和云原生化提供可能;并通过将非业务逻辑的各种功能下沉到基础设施和云,极大地增强了基础设施和云的能力,为云原生的落地提供了极大助力。

1.3 Serverless架构

Serverless架构以事件驱动函数为核心单元,由HTTP请求、消息队列等事件触发执行,执行完毕后立即释放资源。其核心价值在于全托管式自动弹性伸缩能力,可根据并发量毫秒级扩容实例,空闲时缩容至零,实现按实际资源消耗计费(而非预留资源)。开发者无需直接管理服务器、操作系统、网络配置等底层资源,而是由云服务提供商负责基础设施的配置、维护和扩展。Serverless架构采用按需付费的模式,提升了成本效益,同时简化了运维并提升了开发效率。

Serverless架构存在一定的局限性,比如冷启动问题,函数初始化时的延迟可能会影响性能;另外Serverless不擅长处理有状态应用,需结合其他技术(如Redis缓存)解决上下文丢失问题。

1.4 存储计算分离架构

存储计算分离架构通过解耦计算节点(无状态)与存储节点(持久化),打破传统单体架构的资源绑定限制。数据集中存储于存储系统,计算层通过网络访问共享数据池,实现独立扩展:计算层快速弹性伸缩不影响数据一致性,存储层可独立提升吞吐能力。

在云原生架构中,将各类暂态数据(如 session会话信息)、结构化和非结构化持久数据都采用持久化存储来保存,从而实现存储和计算分离。通过存算分离的解耦,提升了资源的利用率,减少了存储和技术资源的耦合,避免资源的争用并提升了性能。
1.5 可观测架构

可观测架构通过整合指标(Metrics)、日志(Logging)、追踪(Tracing)三大支柱构建深度系统洞察力,其中 Logging 提供多个级别的详细信息跟踪,由应用开发者主动提供;Tracing 提供一个请求从前端到后端的完整调用链路跟踪,对于分布式场景尤其有用;Metrics则提供对系统量化的多维度度量。指标实时监控性能数据(CPU/QPS)并通过Prometheus可视化;日志聚合工具(EFK栈)实现跨节点检索与关联分析;分布式追踪(Jaeger/Zipkin)还原请求全链路因果关系。可观测架构结合持续剖析(Profiling)定位代码瓶颈,关联多源数据(告警/日志/追踪)快速溯源根因,为复杂分布式系统提供运维确定性。

1.6 分布式事务模式

分布式事务模式用于解决微服务架构中跨服务、跨数据库的数据一致性问题,常见模式包括2PC、TCC、Saga等。在分布式系统中根据CAP理论,无法同时满足一致性、可用性和分区容错性,实际应用场景中根据业务的数据一致性要求,在性能和一致性上权衡选择合适的算法。

》中已对常见的分布式事务实现算法进行了介绍。

1.7 CQRS读写分离模式

CQRS模式分离命令(写操作)与查询(读操作)模型:命令端处理业务逻辑并更新写数据库,查询端通过视图等结构优化读取性能。通过将写操作和读操作独立设计,降低耦合度,优化了读写业务的数据模型,读模型简化了查询逻辑、写模型则专注于业务逻辑。CQRS低些分离架构可以有效解决读写负载冲突,支持读服务水平扩展,但需容忍数据同步延迟以及可能的最终一致性问题,并增加架构复杂度。

1.8 EDA事件驱动架构

EDA架构以事件为通信核心:生产者服务发布状态变更事件至消息中间件,消费者服务订阅事件并异步触发业务逻辑。其核心优势在于生产者与消费者松耦合和最终一致性,支持通过事件溯源重建系统状态。

在云原生架构中,微服务通过事件进行解耦,同时也可以通过事件来触发自动化任务减少人工干预,也可以通过流式ETL(如实时分析用户行为)和事件溯源(Event Sourcing)结合,支持复杂业务逻辑。

参考资料:

  1. 云原生架构,阿里云
  2. https://www.cnblogs.com/IT-Evan/p/18033135
  3. Service Mesh发展趋势:云原生中流砥柱

服务网格确实简化了微服务治理,但也引入了一些新问题。首先是运维复杂性增加,需要维护额外的Sidecar容器和控制平面。其次,Sidecar代理会增加请求延迟,对性能敏感的应用需要仔细评估。另外,服务网格的配置管理也比较复杂,需要统一管理路由规则、熔断策略等。总的来说,需要在收益和成本之间做好权衡。

关于Serverless冷启动,其实有很多优化方法。除了预热(保持warm状态)之外,还可以通过优化代码结构、减少依赖包大小、使用更快的启动语言等手段来加速启动过程。另外,选择合适的Serverless平台也很重要,有些平台在冷启动优化方面做得更好。

同意楼上的观点,服务网格的引入肯定不是银弹。从运维角度看,你需要监控和管理更多的组件,例如Envoy的健康状况、控制平面的稳定性等等。从性能角度看,虽然服务网格在不断优化,但Sidecar终究会增加一定的CPU和内存开销。还有一点,服务网格的学习曲线比较陡峭,团队需要掌握新的技术栈,例如Istio的配置语法、流量管理策略等等。

抖个机灵,实在不行,可以考虑换个角度解决问题。既然冷启动不可避免,那就优化用户体验,比如在冷启动期间显示一个Loading动画或者一条友好的提示信息,让用户感觉等待是值得的。当然,这只是权宜之计,根本上还是要解决冷启动问题。

我分享一个我之前项目的经验。我们当时做的是一个电商平台,涉及到订单、库存、支付等多个微服务。由于业务量很大,我们需要保证高性能和高可用性。最终,我们选择了基于消息队列的最终一致性方案。当订单创建成功后,发送一个消息到消息队列,库存服务和支付服务订阅该消息并执行相应的操作。如果执行失败,会进行重试或者人工干预。这种方案虽然不能保证强一致性,但可以满足大部分业务场景的需求。

我之前做过一些Serverless相关的项目,发现预热是最有效的。可以定期触发函数,保持容器处于运行状态。当然,预热也会带来一定的成本,需要在性能和成本之间做权衡。另外,可以使用更轻量级的编程语言,比如Go或者Rust,它们的启动速度通常比Java快很多。

作为一个“过来人”,我补充一点。服务网格的初期部署确实比较痛苦,配置稍微出错就会导致服务间通信异常。而且,早期的服务网格版本稳定性不高,经常会出现莫名其妙的问题。不过,随着服务网格技术的发展,这些问题已经得到了很大改善。现在很多云厂商都提供了托管式的服务网格,大大降低了运维成本。所以,如果你的团队规模不大,或者对服务网格不熟悉,不妨考虑使用托管服务。

个人觉得,选择分布式事务模式时,可以遵循以下几个原则:1. 尽可能选择最终一致性方案,避免引入过多的复杂性。2. 优先考虑基于消息队列的解决方案,可以解耦服务,提高系统的可扩展性。3. 对于强一致性要求的场景,可以考虑使用分布式数据库或者两阶段提交等技术,但要注意其性能影响。4. 监控分布式事务的执行情况,及时发现和解决问题。

选择分布式事务模式要结合具体的业务场景。对于金融支付等强一致性要求的场景,可以考虑2PC或者TCC。对于电商订单等最终一致性要求的场景,可以考虑Saga模式。另外,还要考虑系统的性能要求、数据规模、团队的技术栈等因素。总的来说,没有一种万能的解决方案,需要根据实际情况做出权衡。