如何进行系统设计

news2025/1/18 11:38:52

文章目录

    • 1. 理解需求
      • 1.1 功能性需求
      • 1.2 非功能性需求
    • 2. 系统设计
    • 3. Api设计
    • 4. 数据模型设计
    • 5. 高可用、高性能、可监控等

  • 数据密集型应用设计
  • 凤凰架构

重点:自己整理的非权威,不具代表性,自己去取舍哈。

1. 理解需求

1.1 功能性需求

  • 解决什么问题,达到什么目的,有什么场景

    为什么要搞这个功能,可能是无价值功能。

  • 系统的输入和输出?

  • 提供的服务或功能是什么?

  • 界面和边界是什么?

  • 有哪些角色,有哪些模块,有哪些功能,哪些角色使用哪些模块、功能。

    可以用表格或者用例图来更好的阐述。

    管理员

    • 人员管理
      • 新增员工
      • 员工离职
    • 请假管理
      • 请假审批
      • 发起请假

    普通员工

    • 请假管理
      • 发起请假

    用例图示例:

1.2 非功能性需求

  • SLA - 可用性目标是什么?99%?99.999%?

  • 总体用户数,多少活跃用户(DAU日活跃用户数)。

  • 总PV数。

  • 数据存储多久,数据保留策略,例如一般3年。

  • 接口响应时长的要求。

    网上看到过,一般是P99.99 1s,P95 200ms,具体要根据业务场景来定。

  • 读写比例是多少

根据日活跃用户数和总PV数能大概算出来系统的OPS和并发量。

原理:按二八定律来看,如果每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间 。

这里应该根据业务场景来定,例如这个时间 * 20%

针对一些政企机关单位这个时间不是 24h而是8h,应灵活运用。

  • 峰值QPS:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
  • 需要的机器:峰值时间每秒QPS / 单台机器的QPS = 需要的机器

:每天100w PV 的在单台机器上,这台机器峰值是多少QPS

:( 1000000 * 0.8 ) / (86400 * 0.2 ) = 46 (QPS)

:如果一台机器的QPS是18,需要几台机器来支持?

:46/ 18 = 3

2. 系统设计

这里把上面的需求整理出系统的概要设计。用C4模型来帮助梳理业务,架构软件。

  • C4模型

    用4类图来阐述。

    • 1.context 上下文 ,涉及系统边界【系统层面,涉及的所有系统
      • 梳理本系统与其他系统的关系,重点是大层面,系统间的关系
      • 用颜色区分 哪些已有系统和哪些 代建系统。
    • 2.container 容器 显示组成该软件系统的容器(应用程序中间件数据存储微服务等 【中间件层面,对上面进一步下钻放大 我们自己的服务】
      • 梳理本系统内部的组件划分,组件将关系,聚焦系统内部组件。
    • 3.component 组件 将单个容器放大,以显示其中的组件。这些组件映射到代码库中的真实抽象(例如一组代码)【代码层面 组件
      • 权限组件,通知组件,xx业务组件
    • 4.Code 代码层面 约等于类图,一般不需要。

    总结

    一般画出以下几种图即可。

    • 系统间上下文架构图。
    • **系统内部容器(组件)**间关系图。
    • 各内部组件时序图、流程图
    • 时序图,一般不要包含 if else 分支,否则会显得比较复杂。
    • 流程图,针对复杂的逻辑,建议用流程图更容易理解。
  • 抽象 找出共同点和不同点,找出稳定点和变化点。

  • 把大问题拆解成小问题。

  • 聚焦核心业务,一口吃不成胖子。

3. Api设计

api设计和数据模型设计一起做,不分什么先后顺序。

符合Restful设计

  • REST 的做法是把不同业务需求抽象为对资源的增加、修改、删除等操作

  • 使用 HTTP 协议的 Status Code,可以涵盖大多数资源操作可能出现的异常,而且 Status Code 可以自定义扩展,

  • 依靠 HTTP Header 中携带的额外认证、授权信息

  • 服务的 Endpoint 应该是一个名词而不是动词

  • 每次请求中都应包含资源的 ID,所有操作均通过资源 ID 来进行

  • 重复请求 425 Too Early

  • 429 Too Many Requests

  • 201 Created

  • 409 Conflict 如果发生冲突。

方法描述幂等
GET用于查询操作,对应于数据库的 select 操作✔︎
PUT用于所有的信息更新,对应于数据库的 update 操作✔︎︎
DELETE用于更新操作,对应于数据库的 delete 操作✔︎︎
POST用于新增操作,对应于数据库的 insert 操作
HEAD用于返回一个资源对象的“元数据”,或是用于探测API是否健康✔︎
PATCH用于局部信息的更新,对应于数据库的 update 操作
OPTIONS获取API的相关的信息。✔︎

其中,PUTPACTH 都是更新业务资源信息,如果资源对象不存在则可以新建一个,但他们两者的区别是,PUT 用于更新一个业务对象的所有完整信息,就像是我们通过表单提交所有的数据,而 PACTH 则对更为API化的数据更新操作,只需要更需要更新的字段(参看 RFC 5789 )。

不要机械地通过数据库的CRUD来对应这些动词,很多时候,还是要分析一下业务语义。

  • PATCH用于局部更新,比如,更新某个字段 cnt = cnt+1,明显不可能是幂等操作。

一般来说,对于查询类的API,主要就是要完成四种操作:排序,过滤,搜索,分页。下面是一些相关的规范。参考于两个我觉得写的最好的Restful API的规范文档,Microsoft REST API Guidelines,Paypal API Design Guidelines。

  • 排序。对于结果集的排序,使用 sort 关键字,以及 {field_name}|{asc|desc},{field_name}|{asc|desc} 的相关语法。比如,某API需要返回公司的列表,并按照某些字段排序,如:GET /admin/companies?sort=rank|asc 或是 GET /admin/companies?sort=rank|asc,zip_code|desc

  • 过滤。对于结果集的过滤,使用 filter 关键字,以及 {field_name} op{value} 的语法。比如: GET /companies?category=banking&location=china 。但是,有些时候,我们需要更为灵活的表达式,我们就需要在URL上构造我们的表达式。这里需要定义六个比较操作:=<><=>=,以及三个逻辑操作:andornot。(表达式中的一些特殊字符需要做一定的转义,比如:>= 转成 ge)于是,我们就会有如下的查询表达式:GET /products?$filter=name eq 'Milk' and price lt 2.55 查找所有的价柗小于2.55的牛奶。

  • 搜索。对于相关的搜索,使用 search 关键字,以及关键词。如:GET /books/search?description=algorithm 或是直接就是全文搜索 GET /books/search?key=algorithm

  • 分页。对于结果集进行分页处理,分页必需是一个默认行为,这样不会产生大量的返回数据。

    • 使用pageper_page代表页码和每页数据量,比如:GET /books?page=3&per_page=20
    • 可选。上面提到的page方式为使用相对位置来获取数据,可能会存在两个问题:性能(大数据量)与数据偏差(高频更新)。此时可以使用绝对位置来获取数据:事先记录下当前已获取数据里最后一条数据的ID时间等信息,以此获取 “该ID之前的数据” 或 “该时刻之前的数据”。示例:GET /news?max_id=23454345&per_page=20GET /news?published_before=2011-01-01T00:00:00Z&per_page=20
  • 要携带版本号和服务名属性

    /xxxservice/api/v1/users

  • id不要携带业务属性

    /xxxservice/api/v1/users/{id}

    不要这样定义/xxxservice/api/v1/users/{userId}

    因为冲path中已经知道是user可,不需要再用userId定义。

  • 设计返回对象时,不建议直接是数组,因为不方便扩展,建议如下。

    {

    ​ “total”: 10

    ​ “record” []

    }

  • api设计聚合 和 拆解根据情况定

    • 为了性能可以拆。
    • 为了业务或者前端不能太多的call(太多call会导致请求排队) 可以聚合。
  • 幂等性

    GET/ PUT/ DELETE 一定要保证幂等

    • PATCH 对资源执行部分更新。 请求正文包含要应用到资源的一组更改。

    POST尽量保证幂等

  • 接口是否有并发问题

    • 同时多种例如 insert delete update
  • 认证鉴权

    • 每个接口都要认证 鉴权,什么接口 什么角色能调用,什么数据 什么人能查询 能删 能改。
  • 安全

    • 动态查询 动态排序要主要防止sql注入问题

    动态排序 利用枚举字段限定。

    用户输入的 SQL 参数严格使用参数绑定或者 METADATA 字段值限定,防止 SQL 注入,禁止字 符串拼接 SQL 访问数据库。

    • PII UGC 要加密传输,输入 和输出都是密文

    • 用户请求传入的任何参数必须做有效性验证。

      页面 page size 过大导致内存溢出

      恶意 order by 导致数据库慢查询

  • 限流规则

处理 429 错误

如果您的应用程序达到 API 速率限制,Webex API 网关将返回429 Too Many Requests响应。响应包含一个Retry-After标头,指示您的应用程序在向同一端点发出另一个请求之前必须等待多长时间。例如,以下是一个 429 响应示例,指示应用程序在重试请求之前应等待 3600 秒。

HTTP/1.1 429 Too Many Requests\
Content-Type: text/html\
Retry-After: 3600
  • 注意 是否有并发事务安全问题。(并发事务 操作多对象)
    • 幂等 insert insert
    • insert update delete

4. 数据模型设计

  • 对应核心数据的增删改,尤其是改,要有DB log表 方便追踪。

  • 数据库设计

    • 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint(1 表示 是,0 表示否)。 注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀,所以,需要在设置从 is_xxx 到 Xxx 的映射关 系。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的命名方式是为了明确其取值含义与取值范围。 说明:任何字段如果为非负数,必须是 unsigned。 正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。

    • 表名不使用复数名词。

    • 禁用保留字,如 desc、range、match、delayed 等,请参考 MySQL 官方保留字。

    • 主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。 说明:pk_即 primary key;uk_即 unique key;idx_即 index 的简称。

    • varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此 值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引率。

    • 表必备三字段:id,create_time,update_time。 说明:其中 id 必为主键,类型为 bigint unsigned、单表时自增、步长为 1。create_time,update_time 的类型均为 datetime 类型,前者现在时表示主动式创建,后者过去分词表示被动式更新。

    • 在数据库中不能使用物理删除操作,要使用逻辑删除。 说明:逻辑删除在数据删除后可以追溯到行为操作。不过会使得一些情况下的唯一主键变得不唯一,需要根据情况来酌情解决。

      可以有个删除表跟原始表结构一模一样,删除后把数据迁移到删除表,例如order,order_delete.

    • 表的命名最好是遵循“业务名称_表的作用”。 正例:alipay_task / force_project / trade_config / tes_question

    • 库名与应用名称尽量一致

    • 字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:

      • 1)不是频繁修改的字段。
      • 2)不是唯一索引的字段。
      • 3)不是 varchar 超长字段,更不能是 text 字段。
    • 超过三个表禁止 join。需要 join 的字段,数据类型保持绝对一致;多表关联查询时,保证被关联 的字段需要有索引

    • 业务上具有唯一特性的字段,即使是组合字段,也必须建成唯一索引。

    • 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据实际文本区 分度决定索引长度。

    • 页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。

    • 如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合索引的一部 分,并且放在索引组合顺序的最后,避免出现 filesort 的情况,影响查询性能。 where a = ? and b = ? order by c;索引:a_b_c

    • 利用覆盖索引来进行查询操作,避免回表。

    • 代码中写分页查询逻辑时,若 count 为 0 应直接返回,避免执行后面的分页语句。

    • 数据订正(特别是删除或修改记录操作)时,要先 select,避免出现误删除的情况,确认无误才 能执行更新语句。

    • in 操作能避免则避免,若实在避免不了,需要仔细评估 in 后边的集合元素数量,控制在 1000 个之内。

    • 更新数据表记录时,必须同时更新记录对应的 update_time 字段值为当前时间。

    • @Transactional 事务不要滥用。事务会影响数据库的 QPS,另外使用事务的地方需要考虑各 方面的回滚方案,包括缓存回滚、搜索引擎回滚、消息补偿、统计修正,第三方回滚等。

5. 高可用、高性能、可监控等

  • 超时控制
  • 重试控制
  • 降级策略
  • 熔断策略
  • 负载均衡
  • LMA

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

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

相关文章

Python -- 流程控制语句

目录 1、条件判断语句 1.1 if语句的使用 1.2 if...else语句的使用 1.3 if...elif...else语句的使用 2、循环语句 2.1 while语句 2.2 for语句 3、break和continue 4、循环中else的使用 1、条件判断语句 1.1 if语句的使用 if语句是用来进行判断的&#xff0c;其使用格式…

大一学生《基于HTML+CSS制作体育篮球网页》期末网页制作

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

如何在 PDF 中搜索并准确找到您要查找的文本内容

您是否需要在冗长的 PDF 文档中快速查找单词或短语&#xff1f; 没有什么比打开一个只有文本墙的大型 PDF 文档更令人沮丧的了。或者必须在很长的文本中找到特定的单词或短语。或者很长的 PDF。 它不方便、耗时&#xff0c;如果时间紧迫则更糟。 幸运的是&#xff0c;大多…

tensorflower delegate介绍

为什么要使用delegate delegate是什么意思&#xff1f; 性能优化的方法&#xff1a; 量化剪枝权重聚集利用硬件加速器 其中&#xff0c;当我们使用硬件加速器的时候&#xff0c;可以获得相应硬件的特性&#xff0c;提高性能&#xff0c;降低功耗。但是硬件加速器有很多种&am…

【外汇天眼】外汇市场交易基本面分析:什么是利率平价(IRP)?

利率平价&#xff08;平价Interest RateParity&#xff0c;也称为IRP利息率&#xff0c;是指外汇市场在所有可自由兑换货币的预期回报率相同时所能提供的平衡条件。 利率平价规定&#xff0c;一种货币对另一种货币的升值&#xff08;贬值&#xff09;必须由利率差异的变化抵销…

音乐推荐系统设计

文章目录问题描述如何解决系统设计评测指标推荐系统的用户画像运动音乐场景用户行为分析睡眠音乐场景用户行为分析治愈音乐场景用户行为分析其他音乐场景用户行为分析问题描述 移动网络和数字多媒体技术的飞速发展促进了数字音乐产业的共享与广泛传播&#xff0e;对用户而言&a…

TensorRT框架解析

简介&#xff1a; 官网网址&#xff1a; Installation Guide :: NVIDIA Deep Learning TensorRT Documentation NVIDIA TensorRT 的核心是一个C库。 这有助于在 NVIDIA 图形处理单元 &#xff08;GPU&#xff09; 上进行高性能推理。 TensorRT 采用经过训练的网络&#xff0…

计算机毕设Python+Vue校园失物招领平台(程序+LW+部署)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【2023程序员必看】人工智能行业分析

IT行业薪资高已成为大家的共识&#xff0c;但你知道哪个岗位薪资在IT行业中也是“高高在上”吗&#xff1f; IT届薪资天花板&#xff0c;人工智能当仁不让&#xff01; 当下人工智能就业行情怎么样 22年毕业生春招就业情况 根据《2022年春招市场行情周报》显示&#xff0c;人…

【Git】拉取远程仓库的指定目录,图文详细步骤

Git概述 Git&#xff08;读音为/gɪt/&#xff09;是一个开源的分布式版本控制系统&#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 也是Linus Torvalds为了帮助管理Linux内核开发而开发的一个开放源码的版本控制软件。 分布式相比于集中式的最大区别在于开发…

[附源码]Python计算机毕业设计个人博客Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

零碎知识点

零碎知识&#xff1a; 1.**在Python中表示乘方运算&#xff0c;**2即为求平方&#xff0c;**3表示3次方&#xff1b; 2.为赋值运算符&#xff0c;表示把右侧的数据赋值给左边的变量&#xff0c;例如&#xff1a;a 10&#xff1b; 3.变量名的命名规则&#xff1a; 变量名由数字…

【论文阅读】(2018)The Meet-in-the-Middle Principle for Cutting and Packing Problems

文章目录一、摘要二、介绍三、Normal Patterns 正常模式四、Meet-in-the-Middle Principle4.1 MIM Patterns4.2 MIM 的性质4.2.1 性质14.2.2 性质24.2.3 性质34.2.4 性质4五、Evaluation六、Conclusions论文来源&#xff1a;&#xff08;2018&#xff09;The Meet-in-the-Middl…

Odoo 16 企业版手册 - 采购之三向匹配采购收货和账单

三向匹配采购收货和账单的方式 Odoo 16采购模块中的3向方式匹配采购收货和账单功能将帮助您确保您仅为交付到您地址的产品支付供应商账单。在收到采购订单中订购的产品之前&#xff0c;您可能会收到供应商的供应商账单。但是&#xff0c;您可能希望推迟付款&#xff0c;直到产品…

tkinter: 基本+Button+Layout

简介 简介 Tcl 动态解释型编程语言可独立执行&#xff0c;多嵌入C程序中作为脚本引擎&#xff0c;或者作为使用Tk工具包的接口Tcl库可以创建一个或多个Tcl解释器实例&#xff0c;然后在这些实例上运行C或Tcl命令和脚本每个解释器有一个事件队列&#xff0c;接受事件并处理他们…

未来5年,Python发展前景如何?什么方向最吃香?

有同学提问——请问就未来3到5年来讲&#xff0c;python的发展趋势如何&#xff1f;我要不要深学下去&#xff1f;如果学建议从事python的哪个方向&#xff1f; 今天我们就来看一下一线技术人员的分析与解答。 因为一直在开发一线工作&#xff0c;经历了好些环节&#xff0c;…

PyTorch可视化工具Visdom教程

文章目录什么是visdom安装和启动安装启动可视化折线图Line什么是visdom visdom是Facebook为PyTorch开发可视化工具,支持numpy和tensor&#xff0c;功能和Tensorboard差不多&#xff0c;在三维空间数据展示十分出色&#xff0c;其次可以远程访问&#xff0c;随时随地观察训练效…

Linux 网络流量监控工具

Linux 网络流量监控 Linux 网络流量监控是捕获和分析企业的 Linux 网络流量的过程。 为什么要监控 Linux 网络流量 深入了解网络流量对于测量和管理带宽使用情况非常重要。分析 Linux 网络流量有助于识别带宽瓶颈、最高用量者和其他可能影响网络性能的网络问题。 Linux 网络…

Java+MySQL基于SSM的物流公司物流订单管理系统 毕业设计

随着我国经济的高速增长,物流快递的数量也在不断的增加,同时面临的就是如何更加方便快捷和高效的管理物流订单的问题,传统模式的物流订单管理模式明显已经不能够满足当下的需求,于是我们提出了基于B/S的贴心物流公司物流订单管理系统的设计与开发。 用户登录界面 本课题是一个…

vue框架甘特图控件(dhtmlxGantt)

官网JavaScript UI Framework - HTML5 Controls Library - DHTMLXJavaScript UI framework for high-speed web and mobile app development with customizable HTML5 UI controls. Free trial version available.https://dhtmlx.comGit及实例 GitHub - DHTMLX/gantt: GPL ver…