编辑推荐: |
文章主要介绍了大平台角色之间的松耦合原则、服务生产方依赖原则、服务生产方自身的设计原则、服务生产方提供的接口能力的设计原则、服务生产之间依赖原则等相关方面。
来自于技术琐话,由火龙果软件Anna编辑、推荐。 |
|
业务中台是一个充满生命力的个体,
它承载业务逻辑、
沉淀业务数据、
产生业务价值,并随着业务不断发展进化。
它的设计遵循如下图所示的若个原则:
业务中台设计原则
中台架构中,有服务的调用方和生产方,按角色关系划分,共有以下四类关系:
1,服务生产方与服务生产方的关系
2,服务生产方与服务消费方之间的关系
3,服务生产方的管理者与服务生产方之间的关系
4,服务生产方与自己之间的关系
这每种关系之间都有对应的设计原则,稍后便看到。
按生产方与消费方之间的调用方式,分三种:
A、基于 HTTP/HTTPS 协议的 RESTFul API 调用(最大应用范围)
B、基于 Socket/WebSocket 调用
C、基于 SDK 引入调用(受限于技术栈)
其中,A 与 B 的方式是跨语言、跨平台的,应用范围最多;C 的方式受限于系统、语言等因素,B 的应用范围小于
A,但研发成本一般又高于 A。所以 A 这种方式,基于 HTTP/HTTPS 协议的 RESTFul
API 规范,应用范围是最广的。
按三种方式能够覆盖的通讯能力表示,如下图所示:
A 的通用性最大,B 次之,C 最小。稍后便会看到,基于 A 方式的接口的设计原则。
目录
01 平台角色之间的松耦合原则
02 服务生产方依赖原则
03 服务生产方自身的设计原则
04 服务生产方提供的接口能力的设计原则
05 服务生产之间依赖原则
01 松耦合原则(平台角色之间的设计关系)
(1)面向接口实现(服务生产方与服务消费方之间的调用关系)
这是服务松耦合的基本要求,即每一个服务都按 RESTFul API 进行提供。服务的消费方不需要依赖某个特定的服务代码的实现,避免服务提供方的内部变更影响到消费方。在服务提供方切换到其他系统时,不影响服务消费方的正常运行。
RESTFul API 定义的接口具有资源唯一性、无状态性、和固定性。接口后面的逻辑可以由 Java、.Net、Python
或其它任何语言及框架实现,随时亦可根据实际需要进行重构升级,但其接口的消费者,即接口的调用者,调用方式、地址、参数是不变的。
(2)异步事件解耦(服务生产方相互之间的调用)
服务间的事件通信采用异步消息队列来实现。由于有消息队列这个中介,因此生产者和消费者不必在同一时间都保持实时处理能力,而且消费生产者也不需要马上等到回复。
什么是异步模式?
举个例子:用户去快餐店吃饭,一个一个排队点餐、取餐,这是同步模式;相反,在家通过App点餐,然后去忙别的事,外卖小哥送餐到卖,听到铃响,开门取餐,这就是异步模式。
(3)服务提供者位置解耦(服务生产方之间的关系)
服务消费者不需要直接了解服务提供者的具体位置信息,例如IP地址、端口。典型解决方法是服务注册中心,服务提供者启动时将自己注册到服务注册中心,服务消费者通过服务注册中心查找具体服务提供者来访问。同时,服务注册中心可以提供负载均衡及fail-over的能力。
这相当于是提供了一个服务生产方的管理者。
举个例子:用户想发快递,打电话到快递网点,由网点安排快递员A、B或C去用户家里取件,至于具体是派
A 还是 B,还是 C 去?无所谓。看谁近,看谁有空。快递员将自己登记到网点,网点通过固定的电话向外提供服务。
(4)版本松耦合(服务生产方当前的自己与过去的自己之间的关系)
消费端不需要依赖服务契约的某个特定版本来工作,这就要求服务契约在升级时尽可能提供向下兼容性。
02 服务生产方依赖原则(服务生产方相互之间的关系)
(1)有价值的领域模型(什么样的业务对象应当抽离为独立服务?)
确保业务中心的服务,都与企业的商业理想保持一致,业务逻辑和流程设计避免复杂化,紧贴业务的核心目的,从业务原则指导业务逻辑的设计。
(2)服务间最小依赖(横向之间服务生产方之间的关系)
高内聚:同一类服务应归在一起。
低耦合:服务间保持最小联系。
能力与接口:业务流程和业务逻辑的操作都作为中心服务实现,而提供给外部调用的接口数据模型都会转化为服务。
识别通用性:识别出每个通用能力的可扩展的类型,从设计上支持它不断扩展,并在接口定义上满足其不断升级的需求。
(3)能力实体具有层次性(纵向之间服务生产方之间的关系)
能力与接口:分离接口实体与能力实体。
接口实体与限定元素:将接口实体核心元素与接口操作的限定元素分离。
接口实体的层次结构:建设接口实体和上下文限定元素的层次结构。
(4)延迟对技术组件的依赖(服务生产方之间依赖作用的时机)
捆绑依赖:避免在无关的组件技术之间引入新的依赖。
延迟绑定:在使用时才捆绑依赖关系。
03 服务生产方自身的设计原则
(1)使用异步模式,优化远程调用(调用方式)
服务间的远程调用分为同步调用和异步调用两种模式。应当分析服务调用场景,选择较优的调用模式。
(2)去掉冗余数据(接口如何定义)
尽量去掉接口实体中客户端不需要的冗余字段,既能减少网络开销,又能避免给前端解析带去复杂性。
(3)设计粗粒度的服务接口(接口如何定义)
服务接口若能与前端一个用例或一个业务场景相对应(粒度较粗)则既能减少远程调用次数,又能降低学习成本。
(4)识别并设计通用的服务接口(接口如何定义)
由于中心服务不限定应用范围,因此一般要支持不同的应用。但不同应用在功能丰富性上有很大差异,这就决定了服务接口需要尽可能保证广泛兼容性。譬如,服务接口的参数和返回值必须是被广泛支持的较简单的数据类型。
(5)隔离服务内部的变化(封装)
避免服务内部的领域模型直接传导给客户端。如未能提供合理的隔离措施,则当服务进行内部重构时,势必导致客户端频繁变化。
(6)服务接口先行(先行定义接口规范)
详细规定服务与客户端双方对接的内容与形式等,对双方形成强有力的约束和保障。
(7)服务接口向下兼容(对扩展开放,对修改关闭)
由于应用的广泛性,在服务公开发布之后就要保证相当的稳定性,不能随便重构,即使升级也要尽可能考虑向下兼容性。
(8)服务命名原则
强烈建议使用服务使用者专业领域内有意义的名称,优先选用业务概念而不是技术概念。
使用名词命名服务,使用动词命名操作。
(9)服务颗粒度原则
服务应是内聚而完整的,能够独立完成一个职责。在服务内部可以是由多个逻辑上密切相关的代码块共同组成。
(10)服务的无状态性原则
微服务体系的基本要求是服务无状态。无状态的服务是可伸缩、高可用性的基础。
04 服务生产方提供的接口能力的设计原则
操作表示业务动作,应当使用具体的业务含义而不是泛型操作来定义操作。相关的最佳实践如下:
重要的服务不能依赖非重要服务。
任何服务调用都要设定超时时间。
任何服务的调用结果只有三种可能:成功、失败或未知。
能异步调用的服务尽量使用异步调用,从而提高系统响应速度,降低系统之间的耦合性。
系统拆分时,粒度大小以一个系统3~8个开发人员维护为宜。
系统拆分时,往往先拆分数据服务层,因为数据服务层通常是复用性高的一层。
服务的实现不能有单点。
线上遵循fast-fail原则,避免服务调用时间过长,导致性能下降。fast-fail原则是只要发生错误,则调用立即返回。
需要对高压场景下的服务调用链路进行特殊处理,可采用将链路缩短、预热等方式。
服务设计过程中,要避免同类服务由不同服务单元提供。
服务要做到向后兼容,如果无法做到,则需要采取管控机制确保服务消费者升级服务。
服务化架构的变化要使组织的架构能适应这种变化。
在部署服务单元时,要将读服务和写服务分离,将核心服务和非核心服务分离,以保证整个服务单元的稳定性和可靠性。
服务化时,要同时考虑安全。
静态资源也可以实现服务化,实现静态资源与动态资源分离,从而提高性能。
通过在外层系统埋点,可以实现面向终端用户服务的精细管理,比如服务的容量、服务的性能等。
需要将每个业务领域的通用规则沉淀成服务。
05 服务生产之间依赖原则(服务生产方之间的约束关系)
上可依赖下;
下不可依赖上;
上可跨级依赖下;
平级可允许单向调用,坚决禁止循环依赖;
高级别不可依赖低级别;
重要的服务不能依赖非重要服务。
|