架构原则

高内聚、低耦合

  1. 是所有人其他设计原则的原则,其他原则都是基于这个原则基础上扩展的;
  2. 高内聚:每个对象职责尽可能保持聚焦和单一,易于管理和理解
  3. 低耦合:对象之间的耦合度极可能低
  • 场景
  1. 服务之间通过 HTTP/JSON等轻量机制通信,服务之间不强耦合。

控制器

  1. 把职责赋予系统、设备或者子系统的表示类 (门面控制器),或者某个用例的表示类 (用例控制器),让控制器接收事件并协调整个系统的运作。
  2. 例如编写调度器,调度器控制服务启动、运行、暂停等。微服务设计时候,也可采用类似设计思想

间接

  1. 在两个或者多个对象间有交互的情况下,为避免直接耦合,提高重用性,创建中间类并赋予职责,对象的交互交由中间类或服务协调。
  • 场景
  1. 网关在外面的客户端和内部的服务之间增加了一层间接,使两者不强耦合,可以相互独立演化。

信息专家

  1. 当不确定哪个团队应该负责某个微服务时,一般原则也是谁拥有数据谁负责,基于有界上下文 BoundedContext(一般是边界比较清晰的领域数据源)构建微服务。
  2. 这种情况经常出现,发下你某个服务或者接口放在哪里都合适,此时就要从数据维度来管理;
  3. 还有一个维度是表放到那个系统,此处除了要参考表本身的业务之外,还要考虑表里面字段属性和那个业务系统关联最紧密,然后放到那个业务系统。例如TMS司机表,一部分数据是来源HR一部分是来源TMS,考虑到司机有用户名、密码、以及其他TMS独有属性,最终判断,此表放到TMS比较合适

设计时至少要有两步前瞻性

  1. 在扩展性问题发生前考虑好下一步的行动计划。架构师的价值就体现在这里,架构设计对于流量的增长要有提前量。
  2. 这个很重要,一倍数据量和多倍数据量,系统设计完全是不同的,如果不考虑这个问题,当数据量真的达到几倍时候,完全没有办法,当然,可以到时候再优化,但是作为一个架构师不能这样考虑;

受保护的变化

  1. 简单讲就是封装变化。识别系统中可能的不稳定或者变化,在不稳定组件上创建稳定的抽象接口,将可能的变化封装在接口之后,使得系统内部的不稳定或者变化不会对系统的其它部分产生不良影响。
  • 场景
  1. 服务之间值依赖抽象接口,实现可能随时变化

N+1原则

永远不要少于两个,通常为三个。比方说无状态的 Web/API 一般部署至少>=2 个。

简单原则

系统流程尽量设计的简单,新的业务需求考虑目前已有的业务流程是否能满足,若不能满足,则尽量设计的简单,如减少与其他系统的交互,即便交互,也尽量和目前已有的流程并靠。流程越简单系统稳定性越好;

过度设计

不要去搞一些不需要的东西,需要的时候再搞吧。因为我们无法预估后续业务怎么发展,前期不要为此投入巨大的资源来做可能不会发生的事情

稳步推进

  1. 爬,走,跑。换句话说就是先保证跑通,然后再优化变得更好,然后继续优化让其变得伟大。迭代着去做事情,敏捷开发的思路。对于每个功能点,创建里程碑(最大两周),然后去迭代。
  2. 小构建、小发布和快试错。不要期望一步到位,因为不实际使用,各种想法完全是拍脑门的
  • 场景
  1. 例如结算系统初期设计时候,设计了结算额度表,想着数据准确,其实当时根本无法准确,而且对后期数据修复造成很大困扰。另外上线时候出现问题远远比之前预想的要多。

自动化测试

创建稳定、高质量的产品的唯一方法就是自动化测试。所有的都可以自动化,当你设计时,不妨想想这一点。例如结算系统经常不稳定,就是自动化测试没有做好,造成开发很大的精力浪费。t同时,任何功能的修改必须有测试验证,那么再简单的功能,也需要测试,不要太相信自己的代码,事实证明,凡是报侥幸心理,感觉修改简单直接上线的,为此都要付出代价。一个成熟程序员一定求得试稳。

性价比

时刻要想投入产出比(ROI)。就是划得来不。产品没做一些需求,要考虑投入这么大的资源,是否划得来。同事技术方案选择,也考虑此种方式投入产出比是否很大,这次做了,是否对以后带来好的效率;

禁止双向依赖

同一个逻辑系统之间依赖不要双向依赖。例如云采平台和集团系统对同一个订单支付动作。云采系统可以支付成功,同时同步支付状态到集团系统;系统系统也可以对此订单支付,同步支付状态到云采系统。这样会造成系统后期逻辑处理复杂,例如两系统同时支付怎么处理等。避免做法就是两系统只支持一个系统的支付动作,然后单向依赖;

减少依赖

同一个系统要减少依赖,保证版本顺利,设计和测试一个功能得尽可能的独立。当你做设计时,应该想想这一条。从长远来看这能给你解决很多问题,否则你的功能只能等待系统其他所有的功能都就绪了才能测试,这显然很不好。有了这个原则, 你的版本将会更加的顺畅

无状态系统

  1. 尽可能无状态,只有当业务确实需要,才使用状态。无状态系统易于扩展,有状态系统不易扩展且状态复杂时更易出错。
  • 场景
  1. 例如用户登陆存储用户信息,有状态系统就是存储到session里面,但是当集群越来越多时候,服务之间session同步就会很麻烦;无状态系统:把这些信息存储到redis就保障服务是无状态的

系统边界

明确系统应该承担什么样的工作,那些是需要放到此系统,该拆分的就要拆分;

异步设计

能异步尽量用异步,只有当绝对必要或者无法异步时,才使用同步调用

隔离故障(断路器)

实现故障隔离设计,通过断路保护避免故障传播和交叉影响。通过舱壁泳道等机制隔离失败单元 (Failure Unit),一个单元的失败不至影响其它单元的正常工作。

谨慎使用事务

单个系统内逻辑处理,不要使用数据库事务,事务是很耗性能的;例如交易订单生成,需要插入事件,代码里面要不在一个事务处理,有可能交易单生成、但是事件插入失败;解决方案:第一:写个全量检查作业,轮询交易表和事件表,发现事件表没有,就插入事件。此时有可能插入两条(业务系统还未插入事件,全量作业已经插入 ),此时就需要下游系统,对同一个订单号保障幂等性操作了;

事件使用场景

跨系统的消息传输,解决系统之间的耦合;单个系统内部就不需要事件驱动了,因为事件驱动涉及事件表和其他表同时操作,引发事务问题,但是又不允许使用事务,会带来一定的工作量;

单一职责原则

  1. 修改某个类的理由应该只有一个,如果超过一个,说明类承担不止一个职责,要视情况拆分;
  2. 一个微服务,一个接口,都尽量只做一件事情,不能承担过多的职责
  • 场景
  1. 一个业务需要两步完成,那我们可以设计两个作业,第一个作业处理完了,把数据放到一个表里面,然后第二个作业来处理;这样后期排查问题,可以直接从数据库表数据看出来,处理到第几步了,而不是从日志里面来看;再此理解到,职责单一的深刻含义;
  2. 云采平台,查询商品信息接口,目前返回商品所有信息,其实调用此接口的上下游服务只是需要各自部分的信息,例如交易平台。若按照此原则,随业务发展,此接口会越来越臃肿,而且很容易出问题,不太好维护,同时返回数据越来越多;

接口分离原则

  1. 不要强迫用户去依赖它们不使用的接口。换句话说,使用多个专门的接口比使用单一的大而全接口要好。

回滚设计

  1. 确保系统可以回滚到以前发布过的任何版本。可以通过发布系统保留历史版本,或者代码中引入动态开关切换机制 (Feature Switch)。
  2. 任何系统或者功能设计,都要考虑此功能失败了,我们是否可以有挽救的方法,以便提前考虑进来,否则倒是出问题了,自己根本没有办法解决,那就十分尴尬
  • 场景
  1. 结算系统获取用户应收额度,最初方案是查询所有应收和预收,上线之后,发现响应时间很慢,但是当时没有针对核心业务场景做备选方案或者回滚设计,倒是综合开票一直无法开票,非常被动;

禁用设计(服务降级)

  1. 能够关闭任何发布的功能。新功能隐藏在动态开关机制 (Feature Switch) 后面,可以按需一键打开,如发现问题随时关闭禁用
  2. 其实就是服务降级,例如云彩优惠券系统出问题,因为没有降级机制,导致服务不可用

监控设计

  1. 在设计阶段就必须考虑监控,而不是在实施完毕之后补充。例如在需求阶段就要考虑关键指标监控项,这就是度量驱动开发 (Metrics Driven Development) 的理念。
  2. 这个常常是我们比较缺失的地方,系统开发只知道开发,从未考虑过监控的方案,都是等到出问题了,才做监控;

严格把控关键设计

无论是大的系统还是小的模块,一定都有最关键的功能。要在最关键功能上投入大量设计时间,才能规避开发过程中的各种坑。例如设计IM功能来说,一个IM系统最重要的核心模块,一定是通信部分。将通信部分的各种设计搞定,其他锦上添花的方面都可以后续慢慢补充,例如客户端交互、好友关系等 其他的可以不用太关注。即80%精力解决20%问题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值