概述
服务就是代表特定功能的软件实体, 是不依赖于任何上下文或外部服务的自治构件.微服务设计就是软件设计的一个子范畴, 它主要是指如何设计这样的服务来满足需求, 而这个服务是微小且自治的, 满足微服务的若干特征.
先让我们看看传统软件设计的流程: 需求分析--概要设计--详细设计
软件设计
需求分析和整理
对需要做详细的分析, 一是功能性需求
功能性需求:
- 用例
- 场景
- 验收测试用例
非功能性需求:
- 高可用性
- 高性能
- 伸缩性
- 扩展性
- 伸缩性
- 安全性
- 稳定性
- 健壮性
- 可测试性
以用户登录与注册为例, 我们来分析其用例 Use case 和用户故事 User Story
用例 Use case
除了使用绘图工具和画用例图, 还有几种方法通过脚本来生成用例图
一是使用在线网站 yuml.me
use caseUML 生成脚本如下
[User]-(Sign In)
[User]-(Sign Out)
[User]-(Sign Up)
[User]-(Forget Password)
[User]-(Change Password)
(Sign In)>(Remember Me)
(Sign Up)>(Send Verification Email)
(Forget Password)>(Send Reset Password Email)
(Change Password)<(Send Reset Password Email)
[Admin]^[User]
[Admin]-(Add User)
[Admin]-(Delete User)
[Admin]-(Lock User)
[Admin]-(Change Password Policy)
二是使用是通过 plantuml 来生成
到 http://plantuml.com/ 上下载 plantuml.jar , 然后用如下命令生成用例图
java -jar plantuml.jar usecase.txt
示例UML 生成脚本如下
@startuml
User -> (Sign In)
User --> (Sign Out)
User --> (Sign Up)
User --> (activate)
User --> (forget/reset password)
:Admin: ---> (lock user)
:Admin: ---> (add user)
:Admin: ---> (delete user)
@enduml
三是使用graphviz
先安装graphviz, 再运行如下命令
dot usecase1.gv -Tpng -o usecase1.png
示例UML生成脚本如下
digraph G {
rankdir=LR;
subgraph clusterUser {label="User"; labelloc="b"; peripheries=0; user};
user [shapefile="stick.png", peripheries=0];
signin [label="Sign In", shape=ellipse];
signout [label="Sign Out", shape=ellipse];
signup [label="Sign Up", shape=ellipse];
user->signin [arrowhead=none];
user->signout [arrowhead=none];
user->signup [arrowhead=none];
}
用户故事 User Story
User Story 讲究 INVEST 原则
- "I" ndependent (of all others) 独立的
- "N" egotiable (not a specific contract for features) 可协商的
- "V" aluable (or vertical) 有价值的
- "E" stimable (to a good approximation) 可估量的
- "S" mall (so as to fit within an iteration) 足够小的
- "T" estable (in principle, even if there isn't a test for it yet) 可测试的
以用户注册 Sign Up 为例, 可以拆分为如下子用户故事
- 作为一个未注册用户, 我想输入我的电子邮件地址和密码,注册到站点
1.1 我必须输入合法和邮件地址,符合密码策略的密码以及一致的验证码进行注册
默认的密码策略是最低8个字符, 必须包含大小写字母和至少一个数字
# | Story | Priority | Estimation | Deadline | Comments |
---|---|---|---|---|---|
1.1.1 | 生成验证码 | P3 | 2 MD | 2018-10-15 | 防光学识别 |
1.1.2 | 显示注册表单 | P1 | 1 MD | 2018-10-10 | |
1.1.3 | 邮件地址格式验证 | P1 | 1 MD | 2018-10-10 | 客户端和服务端都要验证 |
1.1.4 | 比较两次输入的密码是否相同 | P1 | 2 M | ||
H | 2018-10-10 | ||||
1.1.5 | 验证密码是否符合密码策略 | P2 | 1 MD | 2018-10-10 | |
1.1.6 | 验证输入的验证码 | P3 | 2 MD | 2018-10-12 | |
1.1.7 | 检查是否已有相同的邮件地址存在 | P1 | 1 MD | 2018-10-12 | |
1.1.8 | 输入验证无误后存入数据库,状态为pending | P2 | 2 MD | 2018-10-13 | |
1.1.9 | 生成此用户的激活链接 | P2 | 2 MD | 2018-10-15 | |
1.1.10 | 向注册邮箱发送一封确认邮件 | P2 | 2 MD | 2018-10-15 |
1.2 我的注册邮箱会收到一封验证邮件, 提示我点击注册连接, 从而激活我的注册帐户
1.3 当我完成激活后会自动跳到站点的首页, 提示我进行登录
概要设计
基于上面所定义的验收测试用例, 进行软件服务的总体设计,
先划分模块,以及模块之间的关系和交互.
先让我们来看看微服务的典型架构 -- 六边形架构(Hexagonal Architecture),又称为端口和适配器架构风格
传统的分层架构我们非常熟悉
- 表现层
- 业务层
- 数据层
而六边形架构更加强调对外提供服务的接口适配
- 领域层(Domain Layer):位于最内层的核心层,纯粹的核心业务逻辑,一般不包含任何技术实现或引用。
- 端口层(Ports Layer):领域层之外,负责接收与用例相关的所有请求,这些请求负责在领域层中协调工作。端口层在端口内部作为领域层的边界,在端口外部则扮演了外部实体的角色。
- 适配器层(Adapters Layer):端口层之外,负责以某种格式接收输入、及产生输出。
详细设计
详细设计就是把总体设计落到实处, 一般我们会绘制如下的 4+1 视图
- 逻辑视图(Logical View),设计的对象模型。
- 进程视图(Process View),捕捉设计的并发和同步特征。
- 部署视图(Deployment View),描述了软件到硬件的映射,反映了分布式特性。
- 实现视图(Implementation View),描述了在开发环境中软件的静态组织结构。
四加一的一是指我们之前提到的用例视图
- 用例视图(Use-Case View),该视图是其他视图的依据
领域驱动服务设计
软件的领域有多广, 微服务的领域就有多广. 基本上我们可分为两大类
- 非功能领域的通用服务
它指对应于非功能需求的, 通用的, 可重用的服务类型, 比如系统认证服务, 缓存服务, 数据存储服务, 以及在云平台上常用的注册服务, 分布式锁服务, 消息队列服务等等
微服务构建有其自身特点, 尤其是相比单体服务, 分布式系统使得我们在容错和高可用方面必须考虑周详, 有些共通的原则, 模式和实践, 我们在系统设计需要熟练掌握, 并在实践中不断根据度量数据进行演进和调优.
这些和具体的业务关系不大, 无论你是做电商的 还是做网络会议的, 基本上都会用到.
- 服务注册和发现
- 服务网关和编排
- 服务度量和基于度量的自动化运维
- 服务安全,跟踪和审计
- 服务可用性相关模式: 分流, 限流, 断流
- 等等
这些通用模块之后再展开来讲
- 业务功能领域的专用服务
技术经常更新换代,语言层出不穷,这些都会过时, 淘汰和更新换代, 可以业务逻辑及商业模型不会轻易废弃,因为它是企业安身立命,生存和赚钱的根本,需要小心维护,应用户的需求,企业未来的发展而增强和改进。
而商业模型和业务逻辑如何能映射到软件系统中呢?答案就是领域模型,它是软件设计的核心,指导着我们如何实现,如何编码。
所谓领域主要就是指业务逻辑,规则和流程所对应的的软件设计模型,对于那些重要的,复杂的业务模型称为核心域,相对次要的模型称为支撑子域,这些领域都有一个边界上下文,使用一种通用语言来描述, 而领域的边界,彼此之间的关系以及集成方式使用上下文映射图来表示.
领域驱动设计概述
领域驱动设计采用的架构不一而足,视具体案例情况而定。比如分层架构,端口和适配器,SOA,REST,CQRS,事件驱动(管道和过滤器,长时间处理过程,事件源)
领域模型的基础是实体和值对象,而对于它们的处理以及流程控制更适合用领域服务来表示,而领域事件在不同的服务和系统之间用于集成和交互很有用。以模块来划分领域对象,以聚合来整合相关的对象,以工厂来创建对象,以资源库来存取对象,这些都是领域驱动设计中的核心。
每个领域都有其专有的知识体系和业务场景, 服务必然是针对某个业务场景, 直接或者间接地为业务提供服务
-
使用通用语言
在领域专家和技术人员之间使用统一的语言来描述业务逻辑, 使用规范统一的术语,协议,各种文档和图表 -
做好领域的划分和建模
领域可分为
- 核心子域:核心的业务逻辑和流程
- 支撑子域:支持核心业务的运转
*通用子域: 基础设施和通用的工具或管理系统, 比如安全验证, 用户管理等
- 对领域对象进行细分
- 分析聚合根实体
- 识别根实体和范围和边界
- 定义限界上下文
- 根据业务场景,领域的划分来定义系统和边界和上下文
微服务与上下游服务的交互与依赖关系
微服务设计模板
1. 总体介绍
1.1 需求
1.1.1 业务需求和目标
需求分析, 用户场景及用例图
1.1.2 技术需求: 容量需求,高可用性,安全性,伸缩性
1.2 背景
1.2.1 业务背景
1.2.2 技术背景: 当前架构, 容量, 局限和性能瓶颈
2. 设计
2.1 总体架构
总体框图
2.2 备选方案
2.3 领域设计
主要的领域对象, 流程以及实体关系图
2.4 范围与影响
所影响的范围以及对于其他上下游组件的影响
2.5 详细设计
2.5.1 接口描述
2.5.2 逻辑描述
2.5.3 数据结构
2.5.4 局限与限制
2.5.5 性能问题
2.5.6 设计约束
2.5.7 意外情况处理
3. 依赖条件
3.1 平台
3.2 数据库
3.3 其他服务及其 SDK
4. 部署
4.1 配置
4.2 安装
4.3 部署及验证
5. 度量
5.1 关键因素 KPI
5.2 度量设计
5.3 度量工具
6. 测试方案
6.1 测试用例
6.2 API 测试方案
6.3 集成测试和端到端测试方案
6.4 性能测试方案
7. 问题与风险
当前存在的问题与可能存在的风险
网友评论