架构思维:通用系统设计方法论_从复杂度分析到技术实现指南

文章目录

  • Question
  • 订单履约
    • 原始架构
    • 痛点
    • 目标架构
    • 架构图说明
    • 关键设计点
    • 优点
  • 设计方法论
    • 复杂来源
    • 解决方案
    • 评估标准
      • 从设计原则出发
    • 技术实现 (以选型Redis为例)
      • Redis消息队列的实现细节
      • 高可用设计
  • 总结

在这里插入图片描述


Question

我们经常聊如何设计一个比较完善的系统(或子系统/模块/功能), 很多小伙伴往往忽略“系统设计思路”关键词,而是陷入某个技术点细节里,缺乏全局思维。

一般可以采用架构师的视角回答,即从全局技术视角阐述设计的过程

接下来通过一个案例,讲解如何从全局技术视角介绍技术方案。


订单履约

原始架构

在业务建设之初,考虑到快速开发与上线,用户下单后,订单系统通过 同步RPC 依次调用: 库存系统(扣减库存) → 支付系统(发起支付) → 物流系统(生成运单) → 营销系统(发放积分)。

在这里插入图片描述

但随着业务快速发展,通过 RPC 同步调用的问题逐渐暴露出来。由于过多地依赖其他系统,导致评论发布的接口性能很低,可用性也容易受到其他系统影响。而且每当点评系统需求上线时,其他系统都需要跟着进行联调测试,导致需求迭代速度缓慢。

痛点

  • 链路长、性能差(RT高);
  • 任一系统故障导致整个订单失败;
  • 联调测试成本高。

目标架构

通过 事件驱动架构 解耦,订单系统仅需发布订单事件,各子系统异步消费事件并处理。

在做系统架构升级改造时,如果有互联网设计理念,会很容易想到问题在于系统间的耦合度太高。解决办法就是采用异步化解耦,从而通过引入 MQ 消息管道,在架构上进行系统业务逻辑拆分,将原本强依赖的系统间的同步 RPC 调用变成异步消息触发

在这里插入图片描述

架构图说明

  1. 改造前架构(同步RPC):

    • 订单系统强依赖库存、支付、物流等子系统,形成链式调用。
    • 任一环节失败(如库存不足、支付超时)导致整个订单失败。
  2. 改造后架构(事件驱动):

    • 订单系统:仅负责发布订单事件(如 OrderCreatedEvent)到消息队列(Kafka)。
    • 消息队列:作为事件总线,解耦生产者和消费者。
    • 消费者系统
      • 库存系统消费事件并扣减库存;
      • 支付系统监听事件并触发支付;
      • 物流系统异步生成运单;
      • 营销系统发放积分。

关键设计点

  1. 事件驱动解耦

    • 订单系统无需等待下游系统响应,发布事件后即可返回用户。
    • 各子系统独立消费事件,故障隔离(如物流系统宕机不影响支付流程)。
  2. 消息队列选型

    • 选择 Kafka(高吞吐、持久化、分区顺序性)保障事件可靠传递。
  3. 消费者幂等设计

    • 通过事件唯一ID(如 event_id + 业务主键)避免重复处理。
  4. 补偿机制

    • 若库存扣减失败,触发事件回滚(如发送 OrderCanceledEvent)。

优点

通过事件驱动架构,系统间的强依赖被解耦为基于事件的异步协作。此方案适用于 长链路业务流程(如电商交易、保险理赔、物流配送),核心优势在于:

  • 提升系统吞吐量和可用性;
  • 降低跨系统联调成本;
  • 支持弹性扩展(消费者可独立扩容)。

设计方法论

对于上面的案例,如果我们直截了当地说“引入了 MQ 消息队列,做了系统解耦,采用异步消息通知的方式来触发系统调用” , 随便在网上搜一下都会有大量类似的解决方案。很难令人信服。

作为研发工程师,正确的思考方式是要拥有解决问题的思维。相比一上来就说用了什么技术,阐述解决思维更困难,因为解决技术问题的方法有很多,这是“术”,但解决技术问题的底层思维逻辑是一样的,这是“道”。

一般来说,都逃不过如下四个层面的:

  • 谈复杂来源;

  • 谈解决方案;

  • 谈评估标准;

  • 说技术实现。

接下里,再看个案例:当用户发表一条商品评论,后台的逻辑是点评系统会调用一系列的远程 API 接口,如调用风控系统、广告系统、消息系统……几个甚至十几个系统的接口

复杂来源

之所以要先分析系统的复杂度,是因为只有正确分析后才能明确设计原则,进而设计架构方案,整体项目才不会找错方向。

如果一个系统本来因业务逻辑复杂导致功能耦合严重,我们却设计了一个 TPS达到 10000/秒 的高性能架构,那么即使架构性能再优秀,也没有现实意义,因为技术设计没有解决主要问题的复杂度。这是很多研发工程师的通病,设计偏离了方向,只是为了设计而设计。

那么如何正确评估系统的复杂度呢? 通常分为功能性的复杂度和非功能性的复杂度两种。

在这里插入图片描述

从功能性复杂度方面来看, 产品业务发展快速、系统越来越多、协作效率越来越低。问题根源在架构上各业务子系统强耦合。于是引入消息队列解耦各系统,这是系统业务领域带来的本质上的复杂度,也就是功能性的复杂度,解决的是系统效率的问题。

此外, 还需要考虑非功能性的复杂度,例如高性能、高可用和扩展性等的复杂度的设计。

从非功能性复杂度方面来看,我们假设系统用户每天发送 100 万条消息,那么消息管道一天会产生 100 万条消息,再假设平均一条消息有 10 个子系统读取,那么每秒的处理数据,即点评消息队列系统的 TPS 和 QPS(Queries Per Second,每秒查询次数)就分别是 11(1000000/60*60*24)和 115(10000000/60*60*24)。

不过系统的读写不是完全平均的,设计的目标应该以峰值来计算,即取平均值的 4 倍。于是点评消息队列系统的 TPS 变成了 44,QPS 变成了 460,这个量级的数据意味着并不需要设计高性能架构方案。

接着还要考虑业务规模发展。架构设计的目标应该满足未来业务增长,我们把未来业务增长的预估峰值设定为目前峰值的 4 倍,这样最终的性能要求分别是:TPS 为 176,QPS 是 1840。这样的读写指标还达不到系统压测的性能基线,所以可以确定的是这个系统的复杂度并不在高性能问题上

对于点评系统来说,还需要考虑高可用的问题。假设消息队列挂掉,将导致用户评论发送失败,当然在用户体验层面,解决方式可以在页面端提示用户重新操作,但如果问题影响到了点评消息的读取,导致评论没有走风控策略,就会造成严重的影响。所以高可用性是点评系统的设计复杂度之一,包括点评写入、点评存储,以及点评消息的读取,都需要保证高可用性。

为了方便理解非功能性的复杂度,这里只分析了“高性能”和“高可用”这两点,在实际应用中,不同的公司或者团队可能还有其他方面的复杂度分析。例如有的公司会考虑安全性,有的公司会考虑成本等。

所以综合分析来看,点评系统改造的复杂度来源于两点。

  • 功能性复杂度:要解决业务发展带来的系统耦合、开发效率缓慢问题

  • 非功能性复杂度:要保证系统的高可用性


解决方案

在确定了系统面临的主要复杂度问题后,就有了明确的方案设计目标,这时就可以开始进行架构方案设计了。

方案核心思路优点缺点
MQ消息队列引入Kafka/RocketMQ解耦成熟、高吞吐运维复杂
Redis消息队列基于Redis List/PubSub实现轻量、低延迟需处理消息持久化
MySQL+内存队列异步写入MySQL,定时任务消费无新组件依赖扩展性差、单点风险

一般情况,至少要设计两到三套备选方案,考虑通过不同的技术方式来解决问题。方案设计不用过于详细,而是要确定技术的可行性和优缺点**。


评估标准

设计完三套解决方案之后,摆在眼前的问题就是需要选择最合适的一个。这就需要一套评估标准了。

在软件架构中,架构师常常会把一些通用的设计原则写到设计文档中,比如设计松耦合、系统可监控,这些原则似乎不常用,但好的架构师会通过设计原则来控制项目的技术风险。比如系统无单点,限制了系统技术方案不可出现单点服务的设计;再如系统可降级,限制了系统有具备降级的能力,进而约束了开发人员需要设计数据兜底的技术方案。

这些看似不重要的设计原则,其实是评估架构解决方案的重要手段。做系统架构,需要站在更高的层面考虑系统的全局性关注点,比如性能、可用性、IT 成本、投入资源、实现复杂度、安全性、后续扩展性等。这在不同场景的不同阶段会起到决定性作用。

那么针对案例中的点评系统来说,要如何评估方案呢?这要从点评系统的复杂度来源进行评估。

从设计原则出发

  1. 无单点原则:所有方案需支持集群部署。
  2. 可水平扩展:MQ和Redis天然支持,MySQL需分库分表。
  3. 可降级能力
    • MQ/Redis故障时降级到MySQL兜底。
    • 确保风控系统熔断后评论仍可发布(有损服务)。

常用手段主要有三种。

  • 限流,即抛弃超出预估流量外的用户。

  • 降级,即抛弃部分不重要的功能,让系统提供有损服务,如详情页不展示收藏的数量,以确保核心功能不受影响。

  • 熔断,即抛弃对故障系统的调用。一般情况下熔断会伴随着降级处理,比如展示兜底数据。

针对案例场景中三个解决方案的降级策略,在一般的情况下,我们默认数据库是不可降级的,MQ 和 Redis 都可以通过降级到数据库的方式做容灾处理。所以案例中的三个解决方案,MQ 和 Redis 要考虑降级到 MySQL 或其他方式,这里就还需要根据情况投入降级的开发成本。

最终决策

  • 选择Redis方案:团队熟悉Redis,且业务规模在Redis能力范围内。
  • 关键考量:降低运维成本,快速落地。

通常来说,方案没有优劣之分,而是要看哪个更适合当下的问题,只要架构满足一定时期内的业务发展就可以。


技术实现 (以选型Redis为例)

Redis消息队列的实现细节

方案1:List结构(LPUSH/BRPOP)


方案2:Streams(Redis 5.0+)


高可用设计

  • Redis Cluster:多分片+主从复制,容忍节点故障。
  • 哨兵监控:自动故障转移,VIP切换。
  • 降级策略
    • Redis不可用时,写入本地MySQL队列,异步重试。
    • 风控系统熔断后,评论正常发布,但标记为“待审核”。

总结

架构师思维的本质

  1. 全局视角:在空间维度关注系统边界,在时间维度预见业务发展。
  2. 问题驱动:技术方案必须解决主要矛盾(如案例中的高可用)。
  3. 权衡思维:没有完美方案,只有最适合当前场景的决策。
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/74462.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Excel(实战):INDEX函数和MATCH函数、INDEX函数实战题

目录 经典用法两者嵌套查值题目解题分析 INDEX巧妙用法让数组公式,自动填充所有、有数据的行/列INDEX函数和SEQUENCE函数 经典用法两者嵌套查值 题目 根据左表查询这三个人的所有数据 解题分析 INDEX函数的参数:第1个参数是选定查找范围&#xff0c…

ECharts仪表盘-仪表盘25,附视频讲解与代码下载

引言: ECharts仪表盘(Gauge Chart)是一种类似于速度表的数据可视化图表类型,用于展示单个或多个变量的指标和状态,特别适用于展示指标的实时变化和状态。本文将详细介绍如何使用ECharts库实现一个仪表盘,…

解决安卓so库异常无法打印堆栈的问题

解决方案&#xff1a; 设置 android:extractNativeLibs"true" 直接在 AndroidManifest.xml 里加上&#xff1a; <applicationandroid:extractNativeLibs"true"> </application>这样&#xff0c;so 文件会被解压&#xff0c;崩溃时可以正常打…

清华大学.智灵动力-《DeepSeek行业应用实践报告》附PPT下载方法

导 读INTRODUCTION 今天分享是由清华大学.智灵动力&#xff1a;《DeepSeek行业应用实践报告》&#xff0c;主要介绍了DeepSeek模型的概述、优势、使用技巧、与其他模型的对比&#xff0c;以及在多个行业中的应用和未来发展趋势。为理解DeepSeek模型的应用和未来发展提供了深入的…

屏幕刷新机制(一):机制

屏幕刷新机制&#xff08;一&#xff09;&#xff1a;机制 屏幕刷新机制&#xff08;二&#xff09;&#xff1a;Choreographer、SurfaceFlinger 综述 屏幕整体刷新机制&#xff1a;就是通过Choreographer、SurfaceFlinger&#xff0c;以垂直同步技术(VSYNC)加三重缓冲技术(T…

VSCODE上ckg_server_linux进程占用CPU过多

现象描述 每次一打开VSCODE&#xff0c;ckg_server_linux进程就启动了&#xff0c;并且一直运行&#xff0c;且占用CPU过高&#xff1b; 推测应该是某个插件的问题导致的&#xff1b; 问题处理 本地搜索了一下&#xff0c;发现是 marscode插件影响的&#xff1b; 禁用marsc…

【大模型理论篇】CogVLM:多模态预训练语言模型

1. 模型背景 前两天我们在《Skywork R1V: Pioneering Multimodal Reasoning with Chain-of-Thought》中介绍了将ViT与推理模型结合构造多模态推理模型的案例&#xff0c;其中提到了VLM的应用。追溯起来就是两篇前期工作&#xff1a;Vision LLM以及CogVLM。 今天准备回顾一下Cog…

Vue 项目编译错误:These dependencies were not found,To install them, you can run...

问题与处理策略 问题描述 运行一个 Vue 项目时&#xff0c;报如下错误 ERROR Failed to compile with 47 errors …

python 模拟登录

在Python中模拟登录通常涉及到发送HTTP请求到服务器&#xff0c;并处理响应。这可以通过多种方式实现&#xff0c;最常见的方法之一是使用requests库。下面是一个简单的示例&#xff0c;展示了如何使用requests库来模拟登录一个网站&#xff08;以一个假想的登录表单为例&#…

优化 Docker 镜像 技巧

优化 Docker 镜像可以提高构建速度、减少镜像大小、提高安全性和效率。以下是一些优化 Docker 镜像的方法&#xff1a; 使用适当的基础镜像 选择合适的基础镜像可以减小镜像大小&#xff0c;并确保基础镜像的安全性和更新性。Alpine、Ubuntu Minimal 等轻量级基础镜像是常用选…

2021年蓝桥杯第十二届CC++大学B组真题及代码

目录 1A&#xff1a;空间&#xff08;填空5分_单位转换&#xff09; 2B&#xff1a;卡片&#xff08;填空5分_模拟&#xff09; 3C&#xff1a;直线&#xff08;填空10分_数学排序&#xff09; 4D&#xff1a;货物摆放&#xff08;填空10分_质因数&#xff09; 5E&#xf…

Python入门基础

python基础类型转换 str()与int()类型转换 name 张三 age 20 print(type(name),type(age))print(我叫name 今年&#xff0c; str(age)岁 )a10 b198.8 cFalse print(type(a),type(b),type(c)) print(str(a),str(b),str(c))s1 128 f198.7 s276.77 ffTrue s3hello print(type(s…

HTTP/HTTPS 中 GET 请求和 POST 请求的区别与联系

一、基础概念 HTTP (HyperText Transfer Protocol, 超文本传输协议) 是一种用于浏览器与服务器之间进行数据交互的协议。HTTPS (加密的 HTTP) 则通过 SSL/TLS 协议实现通信加密与数据安全性。 二、GET 和 POST 概述 GET 请求: 用于从服务器获取资源。 POST 请求: 用于将数据…

OPENCV数字识别(非手写数字/采用模板匹配)

这篇文章的重点在于 模板匹配 的使用。模板匹配是计算机视觉中的一项基本技术&#xff0c;它通过比对输入图像与模板图像的相似度&#xff0c;来进行目标识别。对于数字识别&#xff0c;特别是标准数字的识别&#xff0c;模板匹配非常有效。 请看效果&#xff1a; 文章结构 …

在 Kubernetes 中部署 Trivy 漏洞扫描服务

创建专用 Namespace # trivy-ns.yaml apiVersion: v1 kind: Namespace metadata: name: trivy-system配置持久化存储&#xff08;缓存数据库&#xff09; apiVersion: v1 kind: PersistentVolumeClaim metadata: name: trivy-db-cache namespace: trivy-system spec: acc…

Cursor安装注册+基础配置+入门实操

一、安装注册 官网地址&#xff1a;https://www.cursor.com/ 下载按钮会根据电脑系统来匹配&#xff0c;点击对应「Download」按钮进行下载。完成后&#xff0c;按步骤安装即可。 安装完成后&#xff0c;即可点击图标打开软件。 基础设置完成后&#xff0c;就需要选择注册账号…

秒杀业务优化之从分布式锁到基于消息队列的异步秒杀

一、业务场景介绍 优惠券、门票等限时抢购常常出现在各类应用中&#xff0c;这样的业务一般为了引流宣传而降低利润&#xff0c;所以一旦出现问题将造成较大损失&#xff0c;那么在业务中就要求我们对这类型商品严格限时、限量、每位用户限一次、准确无误的创建订单&#xff0c…

MiniMax GenAI 可观测性分析:基于阿里云 SelectDB 构建 PB 级别日志系统

“阿里云SelectDB作为MiniMax日志存储服务的核心支撑&#xff0c;为在线和离线业务提供了高效、稳定的查询与聚合分析能力。其支持实时物化视图、租户资源隔离、冷热分离等企业级特性&#xff0c;不仅有效解决了日志场景下PB级别数据查询的性能瓶颈&#xff0c;还通过智能化的资…

【YOLO V3】目标检测 Darknet 训练自定义模型

【YOLO V3】目标检测 Darknet 训练自定义模型 前言整体思路环境检查与依赖配置克隆 YOLOv3 Darknet 并编译Clone Darknet 项目文件修改 Makefile 文件修改模型保存频率项目编译 准备数据集配置训练文件数据集&#xff1a;datasets &#xff08;自制&#xff09;权重文件 yolov3…

Kafka分区分配策略详解

Kafka分区分配策略详解 Kafka作为当前最流行的分布式消息队列系统&#xff0c;其分区分配策略直接影响着系统的性能、可靠性和可扩展性。合理的分区分配不仅能够提高数据处理的效率&#xff0c;还能确保系统负载的均衡。 Kafka提供了多种内置的分区分配策略&#xff0c;包括R…