写点什么

架构师训练营第 10 周课后作业

用户头像
万有引力
关注
发布于: 2021 年 01 月 31 日

根据微服务框架 Dubbo 的架构图,画出 Dubbo 进行一次微服务调用的时序图



关于微服务架构(中台架构、领域驱动设计、组件设计原则),你有什么样的思考和认识

巨无霸单体应用带来的问题

体验:

编译、部署困难

整个软件的体积很大,可能修改很小,但编译和部署的过程非常缓慢,一旦出错会更加耗时;

分支管理困难

代码合并过程中总会发生冲突,不同团队负责不同的业务,合并和发布的问题纠结在一起,顾此失彼;

技术:

数据库连接耗尽

因为应用包含所有的业务,每个业务可能都会连接各相关的数据库,建立连接池。随着集群规模的提升,数据库创建和维护连接的资源也逐渐成为负担;

新增业务困难

多年堆积出来的软件,依赖错综复杂,很难有人能清楚所有的细节。如果在这种状态下新增或者变更业务,可能会引起其他意外的 bug。故障率高,难以维护。

解决方案

拆分,将模块独立部署,降低系统耦合性。职责更加清晰。

  • 纵向拆分。共用组件下沉,作为可复用的能力

  • 横向拆分。不同领域横向拆分

最重要的服务设计,按照业务领域进行服务划分 微服务框架

为什么 WebService/SOA 没有足够成功?(不够简单) WebService 虽然有着成熟的技术规范和产品实现,以及在企业应用领域有许多成功的案例,但是也具有一些固有的缺点:

  • 臃肿的注册与发现机制

  • 低效的 XML 序列化手段

  • 开销相对较高的 HTTP 远程通信

  • 复杂的部署与维护手段

这些问题导致 WebService 难以满足互联网业务对系统高性能、高可用、易部署、易维护的要求。

微服务架构是如何解决这些问题的?

  • 对应用最小侵入,可更换框架、可快速合并为单体状态(演变整合)

  • 高效的远程通信,基于长连接的、二进制序列化的高效通信协议

  • 框架层面提供服务发现和负载均衡,失效转移

  • 版本管理,对外提供的接口向后兼容

dubbo

技术是手段,而不是目的

微服务落地实践策略和思路

微服务架构落地

  • 业务先行,先理顺业务边界和依赖,技术是手段而不是目的

  • 先有独立的模块,后有分布式的服务

  • 业务耦合严重,逻辑复杂多变的系统进行服务重构要谨慎

  • 搞清楚实施微服务的目的是什么?业务复用?开发边界清晰?分布式集群提升性能?

命令与查询职责隔离(CQRS)

在服务接口层面,将查询(读操作)与命令(写操作)隔离,实现服务层的读写分离

  • 更清晰的领域模型

  • 针对读写分别优化,实现更好的性能

  • 查询服务不会修改数据,更好地保护数据

案例:拆分 UserCommend 服务/UserQuery 服务

事件溯源 将用户请求处理过程中的每次状态变化都记录在事件日志中,并按时间序列进行持久化存储

  • 利用事件溯源,可以精确复现任何用户状态,进行复核审计

  • 利用事件溯源,可以有效监控用户状态变化,并在此基础上实现分布式事务

断路器

当某个服务出现故障,可以使用断路器针对这种不稳定的情况进行规避。当检测到服务异常可以打开断路器,客户端的请求将不再发送至异常的实例,直到故障恢复。 主要的实现的方式如下:

  • 通过错误计数器判定服务是否足够稳定

  • 如果错误计数器的阈值超出稳定范围,断路器打开。与此同时,启用超时 timer

  • 当超时 timer 过期时,进入半开状态,启动成功计数器,接入部分请求

  • 当成功计数器进入稳定范围,则关闭断路器,否则打开断路器

三种状态:

  • 关闭

  • 打开

  • 半开

重试和超时

上游调用者超时时间要大于下游调用者超时时间之和

最重要的是需求,解决业务目标,遵循商业逻辑 落地过程方法论 目标 -> 价值 -> 原则 -> 最佳实践 -> 有哪些工具

微服务网关

网关是一个服务的消费者,通过服务注册和发现调用服务提供者

网关的作用

  • 统一接入。统一认证。高性能、高并发、高可靠、负载均衡

  • 安全防护。防刷、黑白名单

  • 容量管控与容错。限流、降级、熔断

  • 协议适配。http、dubbo、jsf

网关管道技术

实现管道技术可以使用责任链设计模式

开放平台网关

开放给合作者的网关,关注的重点有:

  • API 接口。暴露给合作者的一组 API

  • 协议转换。将各种 API 输入转换成内部服务可以识别的形式

  • 安全。身份识别、权限控制。带宽、请求限流等保护措施;

  • 审计。记录调用情况,用于监控、审计复核、计费等。

  • 路由。将开放平台中的各种访问路由映射到内部服务。

  • 流程。将一组离散的服务组织称一个上下文相关的新服务,隐藏细节,统一提供给开发者调用。

开放授权协议 OAuth2.0

确保第三方的服务合法的使用开放平台内的资源

领域驱动设计 DDD

贫血模型 VS 充血模型

也称:事务脚本 VS 领域模型

贫血模型

只有骨架,没有逻辑。逻辑在特定的业务逻辑层实现(在各种 Service 中)。当前的主流,思路简单,容易被接受。

充血模型

包含了对象的数据和计算逻辑。挑战更高,复杂度较高。

领域驱动设计 DDD

领域是一个组织所做的事情,以及包含的一切。通俗的说,就是组织的业务范围和做事的方式,也是软件开发的目标范围。 领域驱动设计就是从领域出发,分析领域内模型及其关系,进而设计软件系统的方法。

可以认为是简化充血模型的实现。

通过战略设计,划分模块和服务的边界及依赖关系,对微服务架构的设计至关重要。

DDD 战略设计

高层的,业务架构层面的实现。

子域

领域是一个组织所做的事情以及其包含的一切。这个范围太大,不知该如何下手。通常的做法是把整个领域拆分为多个子域,比如用户、商品、订单、库存、物流、发票等。

如何划分子域? 分析清楚某功能背后的业务真正属于哪个子域。 案例:卖家提现功能属于用户子域?订单子域?财务子域?还是直接涉及一个提现子域?

限界上下文

限界上下文是子域的物理实现,通常对应一个特定的模块、子系统或微服务。 限界上下文和子域具有一对一的关系,用来控制子域边界,保证子域内的概念统一性。

上下文映射图

不同的限界上下文,也就是不同的子系统或者模块之间会有各种的交互合作。 DDD 使用上下文映射图来设计这种关联和交互。

DDD 战术设计

编码层面的实现。

实体

领域模型对象也被称为实体,每个实体都有唯一,具有唯一的标识,一个订单对象是一个实体,一个产品对象也是一个实体。 在领域设计时要识别出实体,并根据业务确定其关键属性,这一点很重要。

值对象

并不是领域内的对象都应该设计为实体,DDD 推荐尽可能将对象设计为值对象。

值对象的一个特点是不变性,一个值对象创建以后就不能再改变了。而实体可能会经历各种状态的变迁。

聚合

聚合是一个关联对象的集合,我们将其作为一个单元来处理数据更改。每个集合都有一个根和一个边界。边界定义了聚合内部的内容。 聚合跟:将多个实体和值对象聚合在一起的实体。

案例:Product(聚合根)

  • 1:n BackLogItem(实体)

  • 1:n Release(实体)

  • 1:n Sprint(实体)

一个微服务可以包含一个或多个聚合,而一个聚合不能被拆到不同的微服务中。

DDD 其它设计工具

DDD 分层架构

用户接口层 -> 应用层/服务层(很薄) -> 领域层

DDD 六边形架构

同样的领域模型,由不同的应用包装使用不同的适配器,提供给不同的调用者

界面驱动设计 vs 领域驱动设计


发布于: 2021 年 01 月 31 日阅读数: 18
用户头像

万有引力

关注

还未添加个人签名 2018.05.30 加入

还未添加个人简介

评论

发布
暂无评论
架构师训练营第10周课后作业