系统设计(技术分享)

基本走查:

  1. 编制技术列表图。列出系统中所使用的所有技术及相关版本,主页等,方便安全更新的跟踪。

  2. 确保配置库使用。全部上配置库:全部代码/全部文档/全部脚本(SQL建表,SQL基础数据,SHELL等)/全部配置(系统配置, 中间件配置)/与系统设计开发运行维护相关的一切。

  3. 编制系统部署图。包括测试环境部署和生产环境部署。识别:是否存在单点,是否为热数据准备缓存,是否有降级设置。

  4. 编制系统进程图。系统启动后,会有多少进程,进程之间的关系,内存CPU可能的占用情况。

  5. 编制系统维护表。包括但不限定于: a)业务健康状况如何体现?b)日志如何处理与归档?c)系统监控情况?d)数据库备份策略 e)常见问题处置方式等。

  6. 程序日志打印记录,包括但不限定于:

    • 程序产生的异常
    • 程序执行的SQL(绑定变量的SQL及绑定变量,及组合变量后的SQL)
    • 日志中包含当前会话ID,以便于日志跟踪
    • API调用的日志
    • 重要业务的步骤日志
  7. 全新项目,除了在测试环境部署外,同时在生产环境部署联调(注意暂时关闭外部访问)。

代码走查:

  1. 编制代码模块/包划分说明。模块划分有原则可依(比如按不同业务划分,按业务与技术划分等)。数量控制在7个以内。

  2. 基本代码风格要统一。使用google format,统一格式化。

  3. 使用SonarQube来构建可视化的代码质量,消除严重的代码缺陷。

  4. 定期开展CodeReview活动,来在小组内推行代码的回顾与学习。

  5. 编制系统债务列表。列出当前存在的技术债务,包括但不限定于:

    • 应当配置的,写死了
    • 应当认真设计的,使用了权宜之计的
    • 应当分离业务与技术,或者子业务A与子业务B,而当前夹杂在一起的,使得代码难以理解的。
    • 依赖于某个具体技术人员的部分(只有他能改,别人不敢改)
  6. 编制系统输出。将一些公共的技术,剥离出公共组件和工具,对于一些好的范式,则形成最佳实践。为后续项目奠定基础。

表设计:

  1. 表ID字段,禁止使用UUID,使用BIGINT UNSIGNED类型(MySQL),同时采用Snowflake算法生成全局ID。
  2. 表枚举型字段,使用TinyInt来表示各种不同的状态。
  3. 建表时,表注释和字段注释要书写完整。对于枚举型的字段(例如状态),要说明各种不同取值的含义。
  4. 不同表中,相同含义的字段,必须在命名/类型/注释上保持一致。
  5. 识别大表(持续增长的表),审查大表的索引设置。
  6. 敏感信息在库加密存储。包括但不限定于:身份证号码、用户密码、信用卡、住址等。
  7. 不使用外键。

SQL执行:

  1. SQL执行时,严格限定拼接变量取值(容易造成SQL注入),尽量使用绑定变量的方式。

  2. 不允许在SQL中,使用类似于where 1=1的写法,防止在动态条件下,条件全部丢失(500万数据全部查出,即使内存不爆满,业务系统界面也要挂掉了)。

  3. 操作主要/核心业务流程,在日志中捕获执行的SQL语句(包括原始SQL,绑定变量列表,及替换变量后的SQL),逐条审核SQL的写法,分析潜在的问题。

  4. 对于预期业务增长规模的表,制造一定规模的测试数据量(比如500万),检查系统运行情况,特别是核心业务流程的响应。

  5. 审查大表关键的查询SQL。

  6. 其它注意事项:

    • 单条查询时尽量使用ID,或者唯一索引
    • 多条查询时,必须携带limit限定返回条数,同时限定查询条件,避免全量查询
    • 更新,必须单表单条更新,或者单表批量更新
    • 避免硬删除,使用软删除(deleted_at字段)

系统安全:

  1. 网络请求参数传递,是否在后端进行了强度合适的校验,包括但不限于:

    • 基本校验:非空、最大/小长度、类型、范围、最大/小值、正规等
    • 业务校验:是否符合业务要求,比如:订单号,就要求订单是存在的,是状态正常的,是属于当前登录人的等。
  2. 前端(Web端)存储数据原则

    • 尽量存储乱序的KEY,具体数据则存储在后端缓存中;
    • 存储进行加密,并且添加失效期,避免篡改。
  3. 授权采用白名单原则。如菜单链接,默认(没有显式授权)是401 Unauthorized。

  4. 采用无状态设计。 避免使用Session保存会话。

系统优化:

  1. 是否有需要批量操作。大量类似操作的地方,可以转化为批量操作。

  2. 是否有需要异步操作。慢逻辑避免放在客户请求线程中。业务高峰时,可以采用队列模式,削峰填谷。

  3. 业务服务是否可以划分不同的优先级。在忙时,低优先级的可以降级。

  4. 识别过度设计,特别是为夸夸其谈的可能未来业务的设计。保持KISS原则。

  5. 避免过度优化。在清晰性和可读性原则的前提下,适度优化。优化必须有实际数据对比作为支撑。如果优化效果不明显,但是复杂性上升了,清晰性和可读性下降了,则放弃优化。

  6. 系统是否存在不必要的依赖。包括静态代码库依赖和动态环境依赖等。

  7. 应用在相应环境运行时,调整XMX以合理利用内存,尽量不浪费。

    • 是否存在绝对目录的依赖。
    • 是否存在特定时间的依赖。
  8. 在Chrome浏览器中,打开DevTools跟踪请求,查看数据交互及耗时,分析合理性以及可能的问题。

系统风险:

  1. 调用外部API(非本系统内部调用)的风险。

    • 制定外部依赖列表,列表项目包括:依赖名称、调用频率、合理响应时间、出错处理(立即重试、延时重试、忽略)等
    • 设置超时与重试机制
    • 详细的调用日志留存备查
  2. 慢SQL监控。

  3. 慢操作监控。

  4. 其它可能存在的风险。