系统设计原则

什么是原则

设计原则是构成任何优质产品基础的一系列考虑因素。

都有什么样的原则

SOLID: 面向对象的原则

函数编程原则: https://dev.to/jamesrweb/principles-of-functional-programming-4b7c

ACID/BASE/CAP: 数据库特性和原则

设计(UI)的原则: https://www.figma.com/community/file/817913152610525667

为什么要用设计原则

设计原则可帮助团队进行决策。一些简单的原则或建设性的问题将指导您的团队做出适当的决定。

原则:

可视性(Visibility)

可视性决定了 技术的人机交互能力。把任何有助于理解,开发的数据直接放到一个可视平台将大大提高工作效率。

  • 命名规范,统一命名
  • 状态可视化
    • 有效的错误包装
    • 状态机状态可视化
  • 中间变量/私有变量可视化
  • 轨迹可视化
    • 有效的log
    • 特有轨迹信息建设

可调试(Debuggability)

以下手段可以达到高可调式

  • 完备的可视化
  • 动态Config设计
    • 策略化参数,参数化所有用到常量
    • 参数可视化
  • 明确的log等级设计
  • 结合下边A/B test设计

可测试(Testability)

可以被快速调试

  • 策略化参数,参数化所有用到常量
  • 透明化

无状态(Stateless)

  • 无状态有利于水平扩展, 易于维护。
  • 状态可以转移给专门的状态管理者,如各种数据库,文件系统等。
  • 状态和逻辑的分离
    • 状态机使用

隔离(低耦合)

  • 低耦合的一个重点就是减少对外部状态的依赖
  • 拒绝直接访问其他微服务(模块)的数据库
  • 统一状态CURD的入口/Database的单一拥有者

冗余

  • 防止任何单点故障
  • 生产环境Loadblance后至少需要2个服务实例;
  • 冗余是防止机器/系统/服务单点故障;
  • 任何技术环节都需要一定的冗余,包括人。

一致性

  • 如果数据有多个入口/来源/储存/使用 位置,则永远有一致性问题。
    • Cache
    • Search engine
    • Web
  • 业务场景确定区分
    • 最终一致性
    • 强一致性
  • 异步同步保证一致
  • 提供Query/Validation验证一致

监控(Metrics)

  1. 任何重要的数字都可以是Metrics
  2. Metrics天然属性,是会随着时间变化
  3. 技术
    1. P95 速度,错误响应的比率
    2. FCP,FMP
    3. 容量,使用率
  4. 产品
    1. 用户在线时间,平均时长
    2. 特定用户群(profile)使用率
    3. 特定feature 使用率,时长
  5. 服务
    1. 在线Ticket响应时间,解决问题时间
    2. SLA
  6. 不一样的统计
    1. 环比/同比
    2. consolidation (roll-up), drill-down, and slicing and dicing.

线性算法O(n)

  • 业务代码时间复杂度必须是<=O(n)算法, 如果大于O(n) 的,超线性的算法会带来非常严重的性能和扩展瓶颈;
  • 也要尽量达到最小的Overhead,都是O(n),2n 永远比n浪费一倍的资源。

伸缩性(Scalability)

  • 当业务增加n倍,依靠简单加服务器数量解决问题。
  • 对于微服务,一般服务无状态就可以达到计算伸缩性
  • 对于有状态(DB),通过一下手段达到伸缩性
    • 分库分表 - sharding
    • DB代理 - DB proxy

异步调用(hollywood principle)

  1. 面向对象的IoC;
  2. 在银行排队等待,还是拿号码等着被叫。

自动化(Do not repeat yourself principle)

重复是效率的最大敌人, 尽量自动化所有机器可以搞定的步骤

  1. 自动化部署(deploy)
  2. 自动化测试(test)
  3. 自动化调研(investigation)
  4. 自动化解决问题(fixup)

小步迭代,快速迭代

大部分线上故障是由于变更(发布新功能或者改变功能)造成的, 不要做特别大的改动,小步快速迭代,增量发布,降低变更的风险

回滚设计

  1. 回滚相当于是系统的保险, 设计需要保证可以快速回滚,如果监控到有问题,马上回滚

兼容性设计(toleration/coexistence)

  • 新代码, 老数据
  • 老代码,新数据
  • 新接口,老接口

禁用设计 (A/B Test & Feature toggle)

  • A/B test 不只产品的思路,更是代码的思路。代码永远也可以做A/B test;
  • 产品/功能的设计也最好都使用Feature toggle。可以一键开关;
  • 开关可以单独为特定用户群体打开或者关闭。

幂等性(Idempotence)

  • f(f(x))=f(x)
  • 服务之间的ID的设计和依赖 - Transaction IDs

Links

关于中台的看法
这里将更多的会贴合我们的设计原则讨论中台: 1. 不管是产品中台,还是技术中台,都可以贴合 DRY法则(不重复轮子),以及低耦合法则(有专门的服务(群)来负责特定任务)。 2. 比如标准商品中台(标品是有国家具体规定的);标准书籍中台。再比如不同业务线用到的RBAC权限控制就可以做成中台,防止重复造轮子。用户体系中台可以提供各个语言的SDK给大家用。这本身就是一个platform了。 3. 技术的比如Cache中台。也都是很好的诠释了DRY法则。 4. 中台指的是台,也就是platform。从小到大我们有 Object-> micro-service -> platform,不同层次的设计。它们遵循一些公用,以及特有的设计法则,比如这里提到的DRY。再比如单一职责。还有低耦合。 5. 中台除了避免了重复造轮子,还会有其他优点,比如用户体系的中台单独把控系统设计特性(伸缩/可调/监控,等等),会直接把系统设计最佳实践直接带给每个利用中台的服务,直接提升服务的质量防止短板。

问题一:如何应对简单功能成长为复杂级功能?
1.简单功能设计之初,应该基于什么原则去设计?
2.简单功能没有好好设计,已然成长为复杂级功能(难以梳理,没有文档,不知道包含多少功能点),如何重构?

问题二:如何保持代码的清洁度?
1.主干分支中包含很多不用的代码,或者不确定有没有在用的代码;
2.引用了某个包,但是代码中没有相关的使用(无法真正确定,到底有没有什么地方在使用);
3.滥用全局变量,localStorage缓存等,但是要在原来的功能增加新的功能,只能在原有的设计体系中增加新的代码;
问题三:如何保证代码可读性?
1.复杂业务逻辑实现缺乏相应的设计/实现文档

这些问题都很好
1. 对于复杂的功能,这里我们稍后会添加可扩展性(Extendability)。我们最开始设计的时候要把控可扩展性,最好站在领域专家位置(Domain expert)进行建模。这样可以避免后期refactor。
2. 我们也随时保持Refactor的态度,和思路。不断的对系统重新审计这些设计原则。
3. 代码的可读性,这里我列到了Visibility里,我觉得确实应该独立强调下,所以会单独列出。
4. 重构的原则,依然是这些设计原则。
5. 任何设计都需要文档,对于知识库(kownlage base)的建设,我列在了冗余里,知识库不应该只在某一位的开发的大脑中,而是需要冗余到文档里。
6. 这里讨论更多的是系统设计的原则,我们同样可以建设js代码原则,比如应该怎么用全局变量,code style等,你很好的提出这些问题,那能不能进一步把你的想法和大家讨论好形成代码原则呢?
7. 设计文档是必须的,文档不会局限于文字,可以是图表,数据流图,时序图,ER图等。这个也可以单独列出来讨论,我们可以一起总结最佳的“技术文档原则”。

稳定性可以单独拿出来的,监控里 SLA很重要的就是可用性。 提到的代码review 也很重要,因为本文档主要是系统设计,对于review的原则可以参考代码的原则。 Coding Principle

推荐阅读更多精彩内容

  • 微服务相比传统的单体应用能够带来快速的响应,以小的系统产生大的影响。而随着网络加速、磁盘成本降低、RAM成本降低、...
    Java微服务阅读 1,087评论 0 29
  • 前端交易型系统设计原则 从毕业到现在已经快7年开发经验了,做过基础用户系统、积分商城、偷菜游戏、论坛、博客等等;也...
    meng_philip123阅读 457评论 0 11
  • 高并发原则 无状态:应用无状态,配置文件有状态 拆分:系统维度、功能维度、读写维度、AOP维度、模块维度 服务化:...
    ImClive阅读 1,570评论 1 7
  • 概述 我们进行系统和功能程序设计时,应该有封装,继承,多态的基础概念,拿到需求的时候,时间足够的话,我建议使用UM...
    杨斌_1024阅读 232评论 0 5
  • 设计系统:墨菲定律 1.任何事都没有表面看起来的那么简单 2.所有的事都会比你预期的时间长 3.可能出错的事总会出...
    谁在烽烟彼岸阅读 109评论 0 1
  • 今天主要学习了flex布局,学习笔记如下: 1.指定flex布局: display:flex(任意容器)...
    riku_lu阅读 1,887评论 2 3
  • 插打法原为少林六合门打法,一代宗师万籁声将少林六合门、罗汉门、自然门等内外家之所长融为一家,自然门本无固定招式,然...
    梁山的洛奇阅读 2,523评论 1 2
  • 董多娇第226天坚持分享,焦点相信,每个人在每一刻都会为自己做出一个决定与选择,是他们当时认为最合适自己的,所以任...
    良知良能良知良能阅读 1,823评论 1 1
  • 一、jQuery简介 JQ是JS的一个优秀的库,大型开发必备。在此,我想说的是,JQ里面很多函数使用和JS类似,所...
    Welkin_qing阅读 3,538评论 0 1