系统设计(技术分享)
基本走查:
-
编制技术列表图。列出系统中所使用的所有技术及相关版本,主页等,方便安全更新的跟踪。
-
确保配置库使用。全部上配置库:全部代码/全部文档/全部脚本(SQL建表,SQL基础数据,SHELL等)/全部配置(系统配置, 中间件配置)/与系统设计开发运行维护相关的一切。
-
编制系统部署图。包括测试环境部署和生产环境部署。识别:是否存在单点,是否为热数据准备缓存,是否有降级设置。
-
编制系统进程图。系统启动后,会有多少进程,进程之间的关系,内存CPU可能的占用情况。
-
编制系统维护表。包括但不限定于: a)业务健康状况如何体现?b)日志如何处理与归档?c)系统监控情况?d)数据库备份策略 e)常见问题处置方式等。
-
程序日志打印记录,包括但不限定于:
- 程序产生的异常
- 程序执行的SQL(绑定变量的SQL及绑定变量,及组合变量后的SQL)
- 日志中包含当前会话ID,以便于日志跟踪
- API调用的日志
- 重要业务的步骤日志
-
全新项目,除了在测试环境部署外,同时在生产环境部署联调(注意暂时关闭外部访问)。
代码走查:
-
编制代码模块/包划分说明。模块划分有原则可依(比如按不同业务划分,按业务与技术划分等)。数量控制在7个以内。
-
基本代码风格要统一。使用google format,统一格式化。
-
使用SonarQube来构建可视化的代码质量,消除严重的代码缺陷。
-
定期开展CodeReview活动,来在小组内推行代码的回顾与学习。
-
编制系统债务列表。列出当前存在的技术债务,包括但不限定于:
- 应当配置的,写死了
- 应当认真设计的,使用了权宜之计的
- 应当分离业务与技术,或者子业务A与子业务B,而当前夹杂在一起的,使得代码难以理解的。
- 依赖于某个具体技术人员的部分(只有他能改,别人不敢改)
-
编制系统输出。将一些公共的技术,剥离出公共组件和工具,对于一些好的范式,则形成最佳实践。为后续项目奠定基础。
表设计:
- 表ID字段,禁止使用UUID,使用BIGINT UNSIGNED类型(MySQL),同时采用Snowflake算法生成全局ID。
- 表枚举型字段,使用TinyInt来表示各种不同的状态。
- 建表时,表注释和字段注释要书写完整。对于枚举型的字段(例如状态),要说明各种不同取值的含义。
- 不同表中,相同含义的字段,必须在命名/类型/注释上保持一致。
- 识别大表(持续增长的表),审查大表的索引设置。
- 敏感信息在库加密存储。包括但不限定于:身份证号码、用户密码、信用卡、住址等。
- 不使用外键。
SQL执行:
-
SQL执行时,严格限定拼接变量取值(容易造成SQL注入),尽量使用绑定变量的方式。
-
不允许在SQL中,使用类似于
where 1=1
的写法,防止在动态条件下,条件全部丢失(500万数据全部查出,即使内存不爆满,业务系统界面也要挂掉了)。 -
操作主要/核心业务流程,在日志中捕获执行的SQL语句(包括原始SQL,绑定变量列表,及替换变量后的SQL),逐条审核SQL的写法,分析潜在的问题。
-
对于预期业务增长规模的表,制造一定规模的测试数据量(比如500万),检查系统运行情况,特别是核心业务流程的响应。
-
审查大表关键的查询SQL。
-
其它注意事项:
- 单条查询时尽量使用ID,或者唯一索引
- 多条查询时,必须携带limit限定返回条数,同时限定查询条件,避免全量查询
- 更新,必须单表单条更新,或者单表批量更新
- 避免硬删除,使用软删除(deleted_at字段)
系统安全:
-
网络请求参数传递,是否在后端进行了强度合适的校验,包括但不限于:
- 基本校验:非空、最大/小长度、类型、范围、最大/小值、正规等
- 业务校验:是否符合业务要求,比如:订单号,就要求订单是存在的,是状态正常的,是属于当前登录人的等。
-
前端(Web端)存储数据原则
- 尽量存储乱序的KEY,具体数据则存储在后端缓存中;
- 存储进行加密,并且添加失效期,避免篡改。
-
授权采用白名单原则。如菜单链接,默认(没有显式授权)是401 Unauthorized。
-
采用无状态设计。 避免使用Session保存会话。
系统优化:
-
是否有需要批量操作。大量类似操作的地方,可以转化为批量操作。
-
是否有需要异步操作。慢逻辑避免放在客户请求线程中。业务高峰时,可以采用队列模式,削峰填谷。
-
业务服务是否可以划分不同的优先级。在忙时,低优先级的可以降级。
-
识别过度设计,特别是为
夸夸其谈的可能未来业务
的设计。保持KISS原则。 -
避免过度优化。在清晰性和可读性原则的前提下,适度优化。优化必须有实际数据对比作为支撑。如果优化效果不明显,但是复杂性上升了,清晰性和可读性下降了,则放弃优化。
-
系统是否存在不必要的依赖。包括静态代码库依赖和动态环境依赖等。
-
应用在相应环境运行时,调整XMX以合理利用内存,尽量不浪费。
- 是否存在绝对目录的依赖。
- 是否存在特定时间的依赖。
-
在Chrome浏览器中,打开DevTools跟踪请求,查看数据交互及耗时,分析合理性以及可能的问题。
系统风险:
-
调用外部API(非本系统内部调用)的风险。
- 制定外部依赖列表,列表项目包括:依赖名称、调用频率、合理响应时间、出错处理(立即重试、延时重试、忽略)等
- 设置超时与重试机制
- 详细的调用日志留存备查
-
慢SQL监控。
-
慢操作监控。
-
其它可能存在的风险。