当前位置: 首页 > news >正文

架构设计衡量标准

1. 高内聚低耦合 (High Cohesion, Low Coupling)

  • 原理:

    • 高内聚: 指一个模块(类、组件、服务、子系统)内部的各个元素(函数、数据)彼此紧密相关,共同完成一个单一的、明确的职责。模块内部联系紧密,对外提供清晰、有限的接口。就像一本书的章节,每章都聚焦一个主题。

    • 低耦合: 指不同模块之间的依赖关系尽可能少、尽可能弱、尽可能简单清晰。一个模块的变化,尽可能少地或不影响其他模块。模块之间通过定义良好的接口(契约)进行交互,而不是深入到对方的内部实现细节。就像积木,通过标准接口连接,而不是粘在一起。

  • 为什么重要:

    • 可维护性: 修改一个内聚模块内部,影响范围小;修改一个模块,对低耦合的其他模块影响小。更容易理解、修改、测试、重构。

    • 可复用性: 高内聚、职责单一的模块更容易被复用到其他场景。

    • 可测试性: 模块独立性强,更容易进行单元测试和集成测试。

    • 可扩展性: 添加新功能或修改现有功能时,影响范围可控,更容易实现。

    • 降低复杂度: 系统被分解为相对独立的单元,降低了整体认知复杂度。

  • 建议:

    • 遵循单一职责原则(SRP): 确保每个类/模块只做一件事,并把它做好。

    • 定义清晰的接口/契约: 模块间通过明确定义的接口(API、消息格式、事件)进行交互,隐藏内部实现。

    • 依赖倒置原则(DIP): 高层模块不应该依赖低层模块,两者都应该依赖于抽象(接口或抽象类)。使用依赖注入(DI)。

    • 接口隔离原则(ISP): 客户端不应该被迫依赖它不使用的接口。尽量设计小而专一的接口,而不是大而全的接口。

    • 迪米特法则/最少知识原则(LoD): 一个对象应该对其他对象有最少的了解。只与直接的朋友通信。避免链式调用穿透多个层级(如 a.getB().getC().doSomething())。

    • 模块化/服务化: 将系统划分为界限上下文清晰的模块或微服务,每个模块/服务高度自治。

    • 使用消息队列/事件驱动: 解耦生产者和消费者,实现异步通信。

    • 避免全局变量和单例滥用: 它们会隐式地增加耦合度。


2. 高性能实现方案三板斧 - 缓存、异步、分布式

  • 原理:

    • 缓存 (Caching):

      • 原理: 将计算结果或数据副本存储在访问速度更快的介质(如内存)中,避免重复执行昂贵的计算(如复杂查询)或访问慢速数据源(如数据库、远程API)。核心是利用空间换时间局部性原理(数据访问在时间和空间上往往集中)。

      • 目标: 减少延迟、提高吞吐量、降低后端压力。

    • 异步 (Asynchrony):

      • 原理: 将非实时必需耗时的操作(如发送邮件、处理图片、写入日志、调用外部服务)从主请求处理路径中剥离出来,放入队列或后台线程处理。主线程快速响应用户,提升响应速度。核心是时间换资源利用率解耦

      • 目标: 提高响应速度、系统吞吐量、资源利用率;削峰填谷。

    • 分布式 (Distribution):

      • 原理: 将单体应用或单一数据库拆分成多个可以部署在不同物理机器(节点)上的独立部分(服务、数据库分片),利用多台机器的计算、存储、网络资源并行处理任务。核心是并行处理水平扩展

      • 目标: 突破单机性能瓶颈(CPU、内存、IO、网络),处理海量数据/请求,提高系统容量和可用性。

  • 为什么重要: 它们是解决性能瓶颈最常用、最有效、经过实践检验的核心手段。能显著提升用户体验(响应快)和系统处理能力(支持更多用户/数据)。

  • 建议:

    • 缓存:

      • 分层缓存: 结合浏览器缓存、CDN、反向代理缓存、应用本地缓存、分布式缓存(如Redis, Memcached)。

      • 缓存策略: 理解并合理选择缓存失效/更新策略(TTL、主动失效、写穿透/写回)。

      • 缓存穿透: 解决查询不存在数据的攻击(布隆过滤器、缓存空值)。

      • 缓存击穿: 解决热点Key突然失效导致大量请求压到后端(互斥锁、永不过期+异步更新)。

      • 缓存雪崩: 解决大量Key同时失效(随机TTL、高可用缓存集群)。

      • 一致性考虑: 明确缓存数据一致性要求(强一致、最终一致?),设计更新机制。

    • 异步:

      • 消息队列: 核心工具(如Kafka, RabbitMQ, RocketMQ, Pulsar)。解耦生产者消费者,缓冲流量,保证消息可靠传递。

      • 后台任务/线程池: 处理非实时任务。

      • 事件驱动架构: 基于事件通知进行解耦和异步处理。

      • 流处理: 处理连续的数据流(如Flink, Spark Streaming)。

      • 超时与重试: 设计合理的超时和重试机制处理异步调用失败。

      • 补偿事务: 处理异步操作失败后的数据一致性(如Saga模式)。

    • 分布式:

      • 服务拆分(微服务/SOA): 按业务领域拆分服务,独立部署扩展。

      • 读写分离: 数据库主库写,多个从库读。

      • 分库分表: 水平拆分数据库(按范围、哈希、一致性哈希),解决单库存储和性能瓶颈。引入分布式数据库(如TiDB, CockroachDB, Cassandra)。

      • 分布式缓存: 如Redis Cluster。

      • 负载均衡: 将请求分发到多个服务实例(如Nginx, HAProxy, 云LB)。

      • 分布式计算: 处理海量数据(如Hadoop, Spark)。

      • 复杂性问题: 认识到分布式带来的挑战(网络延迟/分区、数据一致性、分布式事务、服务发现、配置管理、监控调试),并采用相应解决方案(如CAP权衡、BASE理论、分布式锁、Raft/Paxos共识算法)。


3. 扩展性 (Scalability) - 代码扩展/应用扩展/数据扩展

  • 原理:

    • 扩展性 (Scalability): 指系统能够通过增加资源(通常是廉价的、标准化的资源,如服务器)来平滑地提升其处理能力(如吞吐量、用户数、数据量)的能力。分为:

      • 垂直扩展 (Scale Up): 升级单台服务器的硬件(更强的CPU、更多内存、更大磁盘、更快网卡)。上限明显,成本高昂。

      • 水平扩展 (Scale Out): 增加更多相同或相似的服务器节点,通过负载均衡将请求分发到这些节点上处理。理论上无限扩展,成本线性增长,是主流方式。

    • 代码扩展性: 指代码设计本身易于修改、添加新功能、适应变化的能力。是高内聚低耦合的直接结果。

    • 应用扩展性: 指应用服务(通常是运行在服务器上的进程)能够方便地进行水平扩展的能力。通常要求应用是无状态的(或状态外部化)。

    • 数据扩展性: 指数据存储系统(数据库、文件存储等)能够处理不断增长的数据量和访问量的能力。通常通过分片、读写分离、使用分布式数据库等技术实现。

  • 为什么重要: 业务是发展的,流量和数据量是增长的。良好的扩展性确保系统能够支撑业务增长,避免推倒重来。

  • 建议:

    • 代码扩展性:

      • 遵循SOLID原则: 尤其是开闭原则(OCP - 对扩展开放,对修改关闭)。

      • 面向接口编程: 依赖抽象。

      • 模块化设计: 清晰的边界。

      • 使用设计模式: 策略模式、工厂模式、模板方法等提高灵活性。

      • 配置化: 将易变部分提取到配置文件中。

    • 应用扩展性:

      • 无状态设计: 会话状态存储在外部(如Redis),应用本身无状态,任何实例都能处理任何请求。

      • 容器化: 使用Docker打包应用,便于部署和复制。

      • 编排调度: 使用Kubernetes等平台自动化部署、伸缩、管理容器。

      • 自动化部署: CI/CD流水线实现快速、可靠的应用部署和回滚。

      • 服务发现与注册: 动态管理服务实例(如Consul, Nacos, Eureka, Kubernetes Service)。

      • 配置中心: 统一管理应用配置(如Spring Cloud Config, Apollo, Nacos)。

    • 数据扩展性:

      • 读写分离: 缓解读压力。

      • 分库分表: 解决单库容量和性能瓶颈。难点在分片策略(均匀性、避免热点)、跨分片查询/事务、扩容(数据迁移)。

      • 选择合适的分布式数据库: 根据业务需求(强一致?最终一致?OLTP? OLAP?)选择NewSQL(TiDB, CockroachDB)或NoSQL(Cassandra, MongoDB分片集群, HBase)。

      • 数据分区: 在文件存储、消息队列等系统中也广泛应用分区概念提升并行能力。

      • 冷热数据分离/归档: 将访问频率低的历史数据迁移到成本更低的存储介质。

      • 缓存: 缓解数据库压力(见高性能部分)。


4. 高可用 (High Availability - HA)

  • 原理:

    • 高可用性: 指系统能够提供持续可用的服务的能力,通常用可用性百分比(如99.9% - “三个九”, 99.99% - “四个九”)或年度停机时间来衡量。核心是冗余故障自动转移

    • 关键概念:

      • 冗余 (Redundancy): 消除单点故障(SPOF)。关键组件(服务器、网络、磁盘、电源、数据中心)都有备份。

      • 故障检测 (Failure Detection): 快速发现故障(如心跳检测、健康检查)。

      • 故障转移 (Failover): 当主节点故障时,能自动或半自动地将流量/服务切换到备用节点。

      • 恢复 (Recovery): 故障节点修复后能重新加入系统。

  • 为什么重要: 系统宕机意味着业务中断、用户流失、收入损失、声誉受损。高可用是核心业务系统的必备要求。

  • 建议:

    • 消除单点故障(SPOF):

      • 应用层: 无状态设计 + 多实例部署 + 负载均衡(LB自身也需HA)。

      • 数据层:

        • 主从复制: 主库故障,从库提升为主(手动或自动)。

        • 多副本/集群: 分布式数据库(如Redis Sentinel/Cluster, MongoDB Replica Set, MySQL Group Replication/InnoDB Cluster, PG流复制+Patroni, 分布式NewSQL/NoSQL)。

        • 共享存储(谨慎): 如SAN,但存储本身可能成为SPOF。

      • 网络层: 多网卡绑定、多交换机、多ISP线路。

      • 基础设施层: UPS、备用发电机、异地多机房/可用区部署。

    • 负载均衡(HA): 使用高可用的负载均衡器(如Keepalived+VIP for Nginx/HAProxy, 云厂商的托管LB)。

    • 自动故障转移:

      • 应用层: LB健康检查自动剔除故障节点。

      • 数据层: 数据库集群的自动选主机制(如Raft, Paxos)。

    • 熔断与降级:

      • 熔断 (Circuit Breaker): 当依赖的服务故障达到阈值,快速失败(直接返回错误或默认值),避免资源耗尽和级联故障(如Hystrix, Sentinel, Resilience4j)。

      • 降级 (Degradation): 在系统压力过大或部分故障时,暂时关闭非核心功能或提供简化版服务,保障核心功能的可用性。

    • 限流 (Rate Limiting): 控制请求速率,防止突发流量压垮系统(如令牌桶、漏桶算法)。

    • 异地多活 (Multi-Site Active/Active): 在多个地理位置的机房部署独立可用的系统单元,任何一个机房故障,其他机房能接管全部或部分流量。这是最高级别的可用性方案,但复杂度也最高(涉及数据同步延迟、一致性、流量调度)。

    • 备份与恢复: 定期备份数据并验证可恢复性。制定详细的灾难恢复计划(DRP)并演练。

    • 监控与告警: 全面的监控(基础设施、应用性能、业务指标)和及时的告警是发现和快速响应故障的前提。

    • 混沌工程: 主动在生产环境中注入故障(如关闭节点、增加延迟、模拟网络分区),验证系统的容错能力,提前发现弱点。

http://www.xdnf.cn/news/1163125.html

相关文章:

  • 系统分析师-计算机系统-操作系统-存储器管理设备管理
  • 【每日算法】专题四_前缀和
  • 【算法基础】二分查找
  • 选择排序 冒泡排序
  • TPS61194PWPRQ1适用于汽车照明低 EMI、高性能 4 通道 LED 驱动器TPS61194
  • Java 二叉树
  • 【Java学习|黑马笔记|Day19】方法引用、异常(try...catch、自定义异常)及其练习
  • 洛谷 P1480 A/B Problem
  • Apache Ignite Binary Object 调优
  • Js进阶案例合集
  • 《使用Qt Quick从零构建AI螺丝瑕疵检测系统》——1. 启航:你的第一个工业视觉应用
  • 原型设计模式
  • GaussDB alter table的用法
  • 有关Mysql数据库的总结
  • 45.sentinel自定义异常
  • QGIS、ArcMap、ArcGIS Pro中的书签功能、场景裁剪
  • Vue过度与动画效果
  • 如何用 Z.ai 生成PPT,一句话生成整套演示文档
  • 用 STM32 的 SYSTICK 定时器与端口复用重映射玩转嵌入式开发
  • 用Java 代码实现一个简单的负载均衡逻辑
  • redis 如何优雅地进行键设计?
  • 数据结构之克鲁斯卡尔算法
  • 编译支持cuda硬件加速的ffmpeg
  • Vue 3 响应式原理详细解读【一】—— Proxy 如何突破 defineProperty 的局限
  • BEVformer个人理解与解读
  • LLaMA-Factory 微调可配置的模型基本参数
  • ASP .NET Core 8高效集成Redis缓存实战
  • 相机标定(非ROS相机)
  • Linux的相关指令
  • 中文分词模拟器 - 华为OD统一考试(Java 题解)