写点什么

「架构师训练营 4 期」 第十周 - 001&2

用户头像
凯迪
关注
发布于: 2021 年 03 月 14 日

作业一

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



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

作业二

  • 根据当周学习情况,完成一篇学习总结


答案一

题目一

进行服务调用的时序图,包括服务发现和调用过程。


题目二

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


从我认知的互联网发展和架构的演进来看,总结来看如下三点

第一 微服务很好,但是不是万能的,适合的才是最好的

第二 组件设计原则是原则,领域驱动设计是指导,能够从业务角度出发设计更好的微服务架构

第三 中台是一次微服务架构很优秀的实践,但是也有其弊端,要更清晰的认知中台不要盲目跟风


在当今的场景下,仍然有很多行业和解决方案并非是在微服务架构下设计,而且不乏许多小而美的公司和产品,为什么他们不用微服务呢?微服务本身是随着架构的发展过程中,复杂的逻辑/繁多的需求/超高的并发/越来越高的效率等诸多背景下发展宕产物,但是对于某些小行业和传统行业,并没有这么大的需求和要求,传统的架构和基础的开发方式是完全能够满足的,小而美足以,大而全是需要一次次的深耕/迭代和重构才逐步建立起来的。

对于需要按照领取驱动设计重构系统以支撑更大平台发展及需求的公司,我们要通过领域驱动设计进行业务域拆分,依赖于高内聚/低耦合的设计原则进行设计,从公司的业务出发,基于公司的组织架构和技术能力进行微服务的落地。

最后,提到中台来说是互联网公司在各个阶段的不同表现,天下大事合久必分,分久必合,用于这里也是很贴切的,为了避免重复造轮子提高公司资源统一调度等各个需求建立了中台,又因为中台的臃肿和创新缓慢要拆中台,这一次都是从公司和业务发展来看合情合理的。

最终一句话,重构常常有,合适最重要,架构设计不能追求完美,只能追求越来越好。

总结二


微服务:服务设计、维护和治理

微服务的核心并非是微服务框架,微服务框架和 rpc 调用还是在技术手段上的方案,更重要的点是微服务如何拆分和设计

阿里早起的微服务架构

在微服务之前的早起单体系统


image.png


巨无霸的单体系统带来的问题有哪些?

  • 编译部署困难,耗时大,包极大,效率极低

  • 代码分支困难,merge 冲突维护难度大

  • 集群规模过大,数据库连接池耗尽

  • 历史模块复杂,新增业务难度大


高内聚低耦合,讲服务进行拆分,模块独立降低耦合性

  • 纵向拆分:大应用拆分为小应用,小应用模块独立,新应用单独模块

  • 横向拆分:讲复用的业务拆分并提取,模块化独立提供对外调用接口,减少横向依赖


image.png


webservice 与企业级分布式服务

这里面的服务提供者通过注册中心提供服务,服务发现者通过服务注册中心获取服务的思路,是最基础的基于服务发现和远程调用实现的系统功能。


image.png


为什么没有推行起来呢?主要是下面几个点

  • 注册发信机制困难

  • xml 进行序列化和发序列化效率低下

  • http 协议远程通信开销大

  • 部署和维护复杂


微服务框架需求

  • 注册、发现、调用的基础能力的优化之外,还有什么呢?

  • 负载均衡:提供集群负载均衡能力,可以使用加权轮训等方式

  • 失效转移:远程服务异常的情况下可以实现请求重试 &切换

  • 远程通讯:高效调用通讯方式,高效的序列化和反序列化能力

  • 应用最少侵入:减少改造成本和试错成本,集群部署和分布式部署

  • 版本管理:能够实现服务升级、接口变更等情况调用方不受到影响能够平滑升级


dubbo 微服务框架


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

Service Mesh 服务网格


image.png


service mesh 的发布方式对于 k8s 的场景来说通常是通过 sidecar 伴生容器的方式来实现。


image.png


按照复杂程度按实际需要来进行引入。微服务架构落地要去

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

  • 现有独立模块,然后此案有分布式服务

  • 业务耦合严重,复杂逻辑多变的系统慎重引入

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

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

  • 更加清晰的领域模型

  • 针对于读写分别优化,提高性能

  • 避免读服务对于数据的修改,更好的保护数据

事件溯源

将用户的操作以及每次主管态变化记录到事件日志中,并且按照时间序列进行持久化

  • 🔲【任务】时序性数据库有哪些?

  • 利用事件能够复现任何用户的状态,进行复核审计

  • 可以监控用户状态变化,在此基础上可以实现分布式事务

  • 🔲【任务】分布式事务如何实现?例如 tcc

断路器

在微服务场景下,服务是不可信的,某个服务出现故障的情况下,响应延时或者失败率增加,在进行继续调用的情况下会导致调用者请求堵塞,资源消耗增加,进而出现服务级联时效,这种情况下使用断路器阻断对故障服务的调用。

断路器的状态:关闭、打开、半开

服务重试及调用超时

上游调用者超时时间大于下游超时之和,需要考虑重试


微服务网关的技术架构

微服务网关

如图所示,在当前的微服务情况下不会出现客户端连接多个服务的情况,通常是在网关服务器单一入口来进行服务的调用,这种情况下,我们网关作为核心入口非常重要,我们需要网关支持哪些能力呢?


  • 统一接入:高性能,高并发,高可靠,负载均衡

  • 安全防控:防控放刷,黑白名单

  • 协议适配:http、dubbo、jsf 多种协议

  • 限流及容错:限流、降级和熔断

网关管道技术

同步网关,管道的按照功能进行串行请求来实现整个链路的技术责任的落

flower 异步网关于与异步微服务框架

类似于阻塞 IO 和非阻塞 IO 的 epoll 的方式来实现异步实现。这里面每个容器不需要了解服务调用的下游,也不需要进行返回,只需要依赖于服务编排流程来通过流程进行处理。

针对于一次请求来说:

背景:通过注册中心 + 网关 +单体服务来实现整个调用

  1. 服务到网关,网关到流程编排获取流程 id 和请求流程

  2. 网关根据请求服务把请求转发给服务 A,并且根据流程 id 到注册中心检查下一个服务 B

  3. 把处理结果异步发送给下一个容器 B

  4. 反复上述的过程之后,由容器 N 最终把结果返回给网关

所有服务操作都是异步处理,提高性能。


image.png

开放授权协议 OAuth2.0

场景来说,如果账户拥有者授权第三方小程序使用微信或者支付宝的头像或者其他的资料信息,主要是针对于这种场景,通过授权服务器获取 token,依赖于 token 来访问资源。


授权码授权

授权码整个流程说明:

Resource Owner : 我本人

User-Agent :微信 app

Client : 网易云音乐

Authorization Server :微信授权服务


  1. 打开网易云音乐 Client,点击通过微信登录跳转到 User-Agent

  2. 点击登录 User-Agent 把用户信息登录到 Authorization Server 获取授权信息

  3. 返回授权业务,需要资源拥有着 Resource Owner  操作允许授权

  4. User-Agent 操作允许发送给 Authorization Server  ,Authorization Server 返回授权码

  5. 页面跳转回去 Client,然后根据授权 url 和 code 再次请求 Authorization Server,确定是授权完毕,返回令牌

  6. Client 能够根据令牌访问微信的资源服务器


领域驱动设计 DDD


领域模型是开发中要遵从的方法,领域驱动设计 DDD 是领域模型的方法和工具话的一种定义和拓展


为什么会有 DDD 的模型?不进行设计的情况是怎么样的?

  • 用户或者产品经理的需求,小需求不断变更

  • 工程师仅仅进行代码的修修补补

  • 没有进行需求分析和真正的设计,需求的拆分和细化

  • 会导致功能特征不是按照领域模型来设计实现,而是出现大量的小功能的聚合


事务脚本

从 controller 层注入,到 service 层提供服务,依赖 dao 层进行数据操作。

领域模型

面向业务领域设计对象,面向领域对象编程,创建对象的类,然后使用类里面的方法来实现。

贫血模型 VS 充血模型

  • 这里的贫血模型叫做事务脚本,这里面对象只有方法没有数值成员变量,依赖于调用传递参数

  • 领域模型的叫做充血模型,根据业务领域设计对象,对象包含了数据和计算逻辑


DDD 战略设计 &战术设计

领域

领域是一个组织所有的事情以及包含的一切,就是组织的业务范围和做事方式,也是软件开发的目标范围

领域驱动设计是从领域触发,分析领域内模型及其关系,进而设计软件系统的方法。


image.png


子域

领域拆分成为子域,最大的问题在于,如何划分子领?

举个例子,卖家提现功能,是用户子领域?订单子领域?财务子领域?还是单独设计的领域。

限界上下文

限界上下文跟子域一对一关系,用来控制子域的边界。

上下文映射图

在完成设计之后,可以理解为完成了微服务化,然后通过上下文映射图能够看到各个服务或者说子域之间的交互关系。

实体

对象被称为实体,实体都要有唯一标识来控制。

值对象

对象中的属性我理解就是值对象,这里他的属性是不变的,例如创建一个地址之后变化将会是新的地址。问题对象中的问题模板的值对象。

聚合

聚合是对象的集合,把实体和值对象聚合到一起。

DDD 分层架构

领域实体的组合调用和事务控制在应用层,可以理解领取层标识为我们设计的对象。

DDD 六边形架构

领域模型通过应用程序封装成一个相对比较独立的模块,而不同的外部系统通过不同的适配器和领域模型交互。例如 http 接口,webservice 接口,消息队列访问,只需要为不同的访问接口提供不同的适配器来处理。


image.png


软件组件设计原则

人们在很早很早之前就在用软件的组件进行编程,例如很久很久之前的打孔纸袋的时期,把重复打孔的纸袋和其他的纸带进行拼接设计。

软件的复杂度和他的规模成指数关系

一个复杂度为 100 的系统,如果能够拆分成两个会拆分成两个 25 复杂度的子系统而非两个 50 复杂度,所以会有说软件需要进行模块化和组件化设计。这种拆分能力,是架构师核心的能力之一

组件内聚原则

组件内聚原则主要是要明确哪些类应该是聚合在一个组件中,让组件既能够提供相对完整的功能,又不至于太过庞大。

  • 复用发布等同原则

  • 共同封闭原则

  • 共同复用原则

复用发布等同原则

组件的设计粒度应该等同于组件发布变更的最小粒度单元。

默认的版本约定:主版本号,此版本号,修订号

共同封闭原则

当我们设计一个微服务的时候,哪些东西应该放在一个微服务里面,这个功能修改的时候,若干个类都会出现修改的情况,这种情况应该放在一个组件里面。

共同复用原则

不要强迫组件依赖不需要的东西,可以简单理解为把依赖聚合,不依赖尽量拆分。

组件耦合原则

组件内聚原则是指组件应该包含哪些,偶尔原则是指组件之间的关系如何设计来降低耦合。

  • 无循环依赖原则

  • 稳定依赖原则

  • 稳定抽象原则

无循环依赖原则

组件依赖关系不应该出现循环依赖。

稳定依赖原则

组件依赖关系指向更稳定的方向,变更较少的组件,基础组件类稳定性要求极高。

稳定抽象原则

一个组件的抽象化程度和稳定程度一致,在组件设计期间要尽量抽象组件,或者提供一个稳定的接口。

发布于: 2021 年 03 月 14 日阅读数: 24
用户头像

凯迪

关注

还未添加个人签名 2020.06.01 加入

还未添加个人简介

评论

发布
暂无评论
「架构师训练营 4 期」 第十周 - 001&2