您现在的位置是:网站首页> 编程开发> 性能 编程开发
系统开发设计规范
2021-08-19【性能】 2159人已围观
简介1. 服务分层2. 设计规约共通设计文档类业务逻辑层数据访问层3. 安全规约接口层业务逻辑层4. 批处理5. MySQL 数据库建表规约索引规约1. 服务分层服务分层2. 设计规约共通1强制 服务间调用,不能出现同级调用,必须自上而下调用。(请参考服务分层)2强制 &
1. 服务分层
2. 设计规约
共通
设计文档类
业务逻辑层
数据访问层
3. 安全规约
接口层
业务逻辑层
4. 批处理
5. MySQL 数据库
建表规约
索引规约
1. 服务分层
服务分层
2. 设计规约
共通
1 | 强制 | 服务间调用,不能出现同级调用,必须自上而下调用。(请参考服务分层) |
2 | 强制 | 系统必须支持横向扩展
|
3 | 强制 | 服务接口必须符合幂等性要求。对于相同的请求,如果重复发送,其处理结果必须要保持一致。
|
4 | 强制 | 服务接口必须向下兼容。必须要保证新旧版本兼容。如果接口无法兼容的情况下,采取新建接口的方式。
|
5 | 强制 | 程序要有闭环。程序必须能够把一件事情做完,中途发生的程序歧路需要考虑到,比如一个订单有十个状态,出现异常时不能让订单夯在某个状态,有开始有结束,就像补偿超次后的闭环是发预警闭环到人。 |
6 | 强制 | 重要服务提供降级托底方案,例如返回给首页数据的接口,当运营未设置时,后台程序需要按照一定规则补充数据。 |
7 | 强制 | 接口超时时间控制:防止接口超时导致整体服务夯住 |
8 | 强制 | 方法入参检查:不能信任调用方遵守规则,要自己做好防备,接口文档中定义了某些字段和规则,调用方不按文档调用会造成程序处理异常。 |
9 | 推荐 | 接口重试机制:根据业务控制,不是所有接口都可以重试,主要是业务防重控制 |
10 | 推荐 | 异常数据的处理:数据和环境总会有异常的情况,考虑程序的抗异常能力,程序的异常要能自己捕获和处理,不能抛给调用方-----数据库的数据会有异常状况,比如两个关联订单,理论上不会出现一个有一个没有,如果数据有问题通过一个查询到另外一个不判断null直接使用会空指针,自己程序的异常应该自己捕获,自己处理,做到万无一失。 |
11 | 推荐 | 需求分析与系统设计在考虑主干功能的同时,需要充分评估异常流程与业务边界。
|
12 | 推荐 | 系统设计阶段,共性业务或公共行为抽取出来公共模块、公共配置、公共类、公共方法等,避免出现重复代码或重复配置的情况。
|
13 | 推荐 | 在保证缓存和DB一致性的基础上,提升时效性 |
14 | 推荐 | 关键节点(如外部接口调用)的入出参打印,解决日志定位困难可添加夸服务的全局流水号或者业务id串联线索 |
15 | 推荐 | 重要接口单独提供服务,减少别的接口因为资源占用对重要接口的影响 |
16 | 参考 | 系统设计主要目的是明确需求、理顺逻辑、后期维护,次要目的用于指导编码。
|
17 | 参考 | 设计的本质就是识别和表达系统难点,找到系统的变化点,并隔离变化点。
|
18 | 参考 | 系统架构设计的目的:
|
19 | 强制 | 所有服务和批处理,都必须接入钉钉报警,和服务CAT监控。 |
设计文档类
1 | 强制 | 存储方案和底层数据结构的设计获得评审一致通过,并沉淀成为文档。
|
2 | 强制 | 在需求分析阶段,如果与系统交互的 User 超过一类并且相关的 User Case 超过 5 个, 使用用例图来表达更加清晰的结构化需求。 |
3 | 强制 | 如果某个业务对象的状态超过 3 个,使用状态图来表达并且明确状态变化的各个触发 条件。
|
4 | 强制 | 如果系统中某个功能的调用链路上的涉及对象超过 3 个,使用时序图来表达并且明确 各调用环节的输入与输出。 说明:时序图反映了一系列对象间的交互与协作关系,清晰立体地反映系统的调用纵深链路。 |
5 | 推荐 | 如果系统中模型类超过 5 个,并且存在复杂的依赖关系,使用类图来表达并且明确类 之间的关系。
|
6 | 推荐 | 如果系统中超过 2 个对象之间存在协作关系,并且需要表示复杂的处理流程,使用活 动图来表示。
|
业务逻辑层
1 | 强制 | 减少跨系统的交互,一个系统尽量只能CURD自己业务域的数据库,不要跨域去操作其他应用的数据。(低耦合高内聚) |
2 | 强制 | 尽量减少IO以及网络的访问,将多次的调用整合在一次操作中完成,尽量减少IO资源的浪费。考虑提供批量处理接口(考虑异步处理,或流式处理) |
3 | 推荐 | 系统间调用最好是只读,系统间的修改用事件或者消息来实现比较靠谱。 |
4 | 推荐 | 强一致性在微服务架构下不合适,互联网公司一般采用的基于消息【本地消息或者消息微服务;开源的消息中间件只是投递工具】的最终一致性事务的解决方案。 |
5 | 推荐 | 系统需要有区分主次功能,对于主要功能需要加日志层面或者监控层面的告警逻辑;比如资金变动。 |
数据访问层
1 | 强制 | 获取信息列表,必须使用分页处理 (需考虑将来数据增长) 注: 可以更具实际使用情况对分页参数设置默认值(20,50,100),保证有效的返回参数 |
2 | 强制 | 禁止在操作数据库或者外部接口时候放在循环里面,尽量做成批量接口调用。 |
3 | 强制 | 底层数据库以及上层应用本身都需要支持扩展来满足未来业务的增长需求。 |
4 | 强制 | 更新处理只能使用主键或者唯一索引字段更新。 |
5 | 强制 | 禁止使用insert .... select.... |
6 | 强制 | 数据库字段长度和非空等在落库前校验; |
7 | 强制 | 避免因事务过大而导致锁表锁行 |
8 | 强制 | SQL必须要提供执行计划,防止全表扫描而导致查询效率低或数据库崩溃。 |
9 | 强制 | 数据库更新影响行数校验,防止因为缺少条件错误更新数据 |
10 | 推荐 | 对于数据库字段修改,或者其他显示复杂逻辑修改;尽量采用增加的操作;而少采用update的操作;update永远比insert成本大的很多。 |
3. 安全规约
接口层
1 | 强制 | 安全准则第一条,永远不要相信用户的输入是安全的!用户请求传入的任何参数必须做有效性验证。
|
2 | 强制 | 隶属于用户个人的页面或者功能必须进行权限控制校验。
请在查询或者修改数据的时候添加用户权限 示例:select/update... where addressID=#addressID# and ownerId=#userId# |
3 | 强制 | 用户敏感数据禁止直接展示,必须对展示数据进行脱敏。
注:此处最好是在服务端做数据处理 |
4 | 强制 | 用户输入的 SQL 参数严格使用参数绑定或者 METADATA 字段值限定,防止 SQL 注入, 禁止字符串拼接 SQL 访问数据库。 注:
|
5 | 强制 | 禁止向 HTML 页面输出未经安全过滤或未正确转义的用户数据。 注:
|
6 | 强制 | 表单、AJAX 提交必须执行 CSRF 安全验证(原站One Time Token校验)。
|
业务逻辑层
1 | 强制 | 在使用平台资源,譬如短信、邮件、电话、下单、支付,必须实现正确的防重放的机 制,如数量限制、疲劳度控制、验证码校验,避免被滥刷而导致资损。
|
2 | 推荐 | 发贴、评论、发送即时消息等用户生成内容的场景必须实现防刷、文本内容违禁词过 滤等风控策略。 |
4. 批处理
1 | 强制 | 任务调度由任务本身(或者主任务)来控制,不要依赖系统默认的时间调度机制 |
2 | 强制 | 需要支持多种触发机制(时间触发,事件触发,甚至API触发,指定对象主键触发强制处理等) |
3 | 强制 | 原则上要支持分布式并发处理,并且幂等(可以被反复执行) |
4 | 强制 | 要支持优雅结束(shutdown hooks) |
5 | 强制 | 要有死活监控(包括发现实际被挂起无响应的进程),报警以及主动恢复现场和断点续传的功能 |
6 | 强制 | 数据要做到分批处理。禁止加载所有数据在内存中处理,单个批次的数据量要有限制。 |
7 | 强制 | 日志中需记录处理件数(成功,失败) |
8 | 强制 | Job需建立单独服务,可独立部署,不能和其他API服务耦合在一起。包括Batch, MQ消费Worker。 |
5. MySQL 数据库
推荐MySQL红宝书必学资料:高性能mysql第三版(on the Sharepoint),详见附件
建表规约
1 | 强制 | 表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint (1 表示是,0 表示否)。
|
2 | 强制 | 表名、字段名必须使用小写字母或数字,禁止出现数字开头,禁止两个下划线中间只 出现数字。数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
|
3 | 强制 | 表名不使用复数名词。
|
4 | 强制 | 禁用保留字,如 desc、range、match、delayed 等,请参考 MySQL 官方保留字。 |
5 | 强制 | 主键索引名为 pk_字段名;唯一索引名为 uk_字段名;普通索引名则为 idx_字段名。
|
6 | 强制 | 小数类型为 decimal,禁止使用 float 和 double。
|
7 | 强制 | 如果存储的字符串长度几乎相等,使用 char 定长字符串类型。 |
8 | 强制 | varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长 度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索 引效率。 |
9 | 强制 | 表必备三字段:id, create_time, update_time。
注: update_time 默认值: CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6) create_time 默认值: CURRENT_TIMESTAMP(6) |
10 | 强制 | 单表索引不能超过5个。 |
11 | 推荐 | 表的命名最好是加上“业务名称_表的作用”。
|
12 | 推荐 | 库名与应用名称尽量一致。 |
13 | 推荐 | 如果修改字段含义或对字段表示的状态追加时,需要及时更新字段注释。 |
14 | 推荐 | 字段允许适当冗余,以提高查询性能,但必须考虑数据一致。冗余字段应遵循:
|
15 | 推荐 | 单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。
|
16 | 参考 | 合适的字符存储长度,不但节约数据库表空间、节约索引存储,更重要的是提升检 索速度。
对象年龄区间类型字节表示范围人150 岁之内tinyint unsigned1无符号值:0 到 255龟数百岁smallint unsigned2无符号值:0 到 65535恐龙化石数千万年int unsigned4无符号值:0 到约 42.9 亿太阳约 50 亿年bigint unsigned8无符号值:0 到约 10 的 19 次方 |
17 | 强制 | 所有数据表不可以物理删除,只能逻辑删除 |
18 | 强制 | 金额字段的类型定义。 无精度要求时,定义为decimal(14, 2) ; 有精度需求时,定义为decimal(21, 9) |
索引规约
注: explain type类型 ALL < index < range < ref < eq_ref < const < system < null
以下测试用表:
create table tbl_member (
id varchar(32),
a varchar(32),
b varchar(32),
c varchar(32),
d int(11),
primary key (id)
);
create table tbl_order (
id varchar(32),
a varchar(32),
b varchar(32),
c varchar(32),
d int(11),
primary key (id)
);
当where条件作用在非索引字段的时候,type=ALL(全表扫描),所以常用的查询尽量采用索引来提高查询效率
1 | 强制 | 业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引。
|
2 | 强制 | |
3 | 强制 | 在 varchar 字段上建立索引时,必须指定索引长度,没必要对全字段建立索引,根据 实际文本区分度决定索引长度即可。
|
4 | 强制 | 页面搜索严禁左模糊或者全模糊,如果需要请走搜索引擎来解决。
下面是使用like的几种方式对比
|
5 | 推荐 | 如果有 order by 的场景,请注意利用索引的有序性。order by 最后的字段是组合 索引的一部分,并且放在索引组合顺序的最后,避免出现 file_sort 的情况,影响查询性能。 正例:where a=? and b=? order by c; 索引:a_b_c
正确使用的案例: 下面是正确的使用顺序, 注意:组合索引在 where 处可以不考虑顺序, MySQL 已经做过优化,但是在 order by 必须是 索引的顺序,
字段顺序使用对比:
看一个常见的情况: 这里 使用条件 a='a' and b > 'b' order by c, 有常量相当, 有比较大小,还需要排序,通常是常量字段和排序字段组成索引,其他中组合都会产生 filesort
下面是个反例,还是使用 a 和 c 的 组合索引, 下面的例子会产生 filesort,而且like 还会产生 type=ALL
|
6 | 推荐 | 利用覆盖索引来进行查询操作,避免回表。
|
7 | 推荐 | 利用延迟关联或者子查询优化超多分页场景。
分页查询数据测试(字段数据少,返回条数少)随着数量的增多耗时在不断增加,
五十万数据的查询对比
一百五十万的数据查询对比
|
8 | 推荐 | SQL 性能优化的目标:至少要达到 range 级别,要求是 ref 级别,如果可以是 consts 最好。
|
9 | 推荐 | 建组合索引的时候,区分度最高的在最左边。
|
10 | 推荐 | 防止因字段类型不同造成的隐式转换,导致索引失效。
因为数据类型转变(int → varchar),导致索引失效
|
11 | 参考 | 创建索引时避免有如下极端误解:
|
很赞哦! (1)
上一篇:Linux服务端Nignx配置
下一篇:使用canal实现搜索引擎
文章评论
验证码: