《架构设计模式》读书笔记
2022-04-23 11:18:47 1 举报
AI智能生成
架构设计模式
作者其他创作
大纲/内容
九天谓一为中天,二为羡天,三为从天,四为更天,五为晬天,六为廓天,七为减天,八为沈天,九为成天
什么是分层架构?
为什么要进行分层?
如何进行分层架构设计?
典型案例场景
理论概述
层是软件的逻辑单元
层的定义
每一层都有特定的功能
组件被分配到不同层
将系统按照职责拆分和组织
越往上不依赖于技术层,越往下依赖于技术
下层不可以依赖于上层
实战中是有争议的
跨层访问违反接口聚合原则
不可以跨层访问
上层依赖于直接下层
案例:家里装修就是分层
何为分层
HTTP、FTP、DNS、SNMP、Telnet
Application Layer
第七层应用层
SSL、TLS
Presentation Layer
第六层表示层
NetBIOS、PPTP
Session Layer
第五层会话层
TCP、UDP
Transport Layer
第四层传输层
IP、ARP、ICMP、IPSec
Network Layer
第三层网络层
PPP,ATM,Ethernet
Data Link Layer
第二层数据链路层
Ethernet,USB、Bluetooth、IEEE802.11
Physical Layer
第一层物理层
OSI(网络) 7层架构
两层架构
运行于Desktop的Native富客户端
Client
应用服务、业务逻辑和数据存储
server
通过网络交换信息
CS分层架构
运行于各种浏览器的瘦客户端
Browser
Server
BS分层架构(带来互联网风潮)
与用户交互和呈现信息
Presentation
业务逻辑
Domain
数据存储
Data
企业应用三层架构
经典分层架构应用
分层架构定义
组织
架构
设计系统的架构受制于产生这些设计的组织的沟通架构
康威定律
隔离业务复杂度和技术复杂度
解决不同层的问题可以采用不同技术栈
每层变化速度不一致
复杂度隔离
防止错误传播
降低错误影响
所有的共享通信都是不同线程池
Spring Cloud Netflix Hystrix
防水仓设计
本层功能内聚
自主决策
知道的越少,泄密的可能性越小
受影响的可能性越小
OAurh 2.0就是经典的层自治
只有本层的知识
层自治
缘何分层:Conway·s Law
每一层的任何变更更最多影响自身和上一层
专注自身功能,其他层的影响被屏蔽
Single Responsibility每一层都是相对单一单调的
高内聚
每一层只依赖于下一层
单向依赖
Interface Segregation
Dependency Inversion
通过接口交流部
分层架构的优点:低耦合
低耦合
功能扩展,影响仅限于本层
内聚性,易于横向扩展
独立步数宝,易于纵向扩展
每层定义了清洗的边界,扩展发生在不同的边界,符合Open-Close
易扩展
分工合作,开发者关注点集中
每一层可以依据接口并行开发
每一层功能单一,代码易于理解
可维护性好
每层对外提供固定接口,可以直接测试接口
分层测试
@DatajpaTest
@WebMvcTest
Spring Boot层次接口测试比较好
可测试性高
分层架构的优点
分层必定引入新的通信开销
层信息不能泄露,导致每层都有数据转化发生
不能跨层访问,无法通过减少调用链路
性能下降
Full stack少且难以培养
跨组织沟通成本
任何变更可能都需要多层参与
开发成本上升
分层架构的缺点
越向外越具体,越朝内越抽象
外圈是软件,内圈事规则
依赖关系只能从外向内
依赖规则
高层标识规则,底层实现细节
逻辑内聚自治分组
在每个层次划分对应职责
在组织层次划分上理解
依据组织职责分工
定义职责
根据每层的需求个子选定
借鉴成功案例
部署方式
定义技术栈
如何设计分层架构
层对外暴露的接口,隐藏实现细节
实现依赖抽象,抽象不可依赖实现细节
代码不能跨层调用,只依赖于直接的下一层
代码抽象与分层
集成前做单元测试
根据接口和技术栈确定集成方式
集成联调
集成
Domain model和业务逻辑
Model
展示数据和用户交互
View
接收输入并转化为对Model的操作
将Model转化为View能展示的数据
Controller
MVC
MVC的派生变种,Model和View是隔离的变化不会相互影响,缺点是View层和Model层耦合度很高
通过Presenter获得数据而非Model
充当桥梁双向绑定
Presenter
MVP
除了Domain model和业务逻辑,也包含部分Controller功能
Model层
View的模型、映射、显示逻辑和绑定器
ViewModel层
将ViewModel展示在特定的界面
MVVM
将后台功能聚合到一起,提供给前段
Backend for frontend
避免将终端和多个服务的交流
GraphQL
层比较薄,几乎没有业务逻辑;可能一般公司做的时候结合GraphQL;如果不采用不微服务架构没必要使用这个
BFF
案例分析
讲讲层与层之间依赖关系,如何进行链接的HTTP在TCPIP中得到什么东西如何进行操作的?
题目1:HTTP和底层TCPIP链接的关系
MVC看重的是基本功力
ssh可以说说思想是相通的
可以阅读源码或者相关书籍
题目2:什么是MVC架构?采用何种技术实现MVC?
Hystrix的出现原因:业务场景中有N多个服务串起来的,任何服务都被Domain支配的,很难找到错误原因。当你调用别人也可能被调用会产生雪崩效应
就相当于家里的短路,断路器
防止雪崩效应,资源隔离也就是防水层设计
Hystrix的线程模型,错误隔离,线程分开
通过窗口实现的,判断窗口期内错误次数?切面检查熔断器状态,查看线程池状态(超时、Error会出现降级服务);
题目3:Spring Cloud Hystrix 断路器的工作原理
体现你的思想和方法论
分层架构回答
大概知道提供啥服务,提供什么功能
功能之间的依赖,内部的和外部的
理清系统功能,以及依赖关系
系统的重要核心和非核心
找打可以舍弃的功能
按照不同功能和特征划分产品
上下的兼容性
利用新的技术架构如何保证?
保证重要东西不缺失
利用新的分层定义接口规范、重写部分规范
单元测试
功能验收
项目集成
上线功能
优化新系统
还有测试方法论
技术分层思想
题目4:如何完成legacy(雷达)的系统重构
面试题目
分层架构Layered Arch
身无彩凤双飞翼,心有灵犀一点通
什么是EDA
EDA解决了什么问题
EDA的优缺点
一些典型的应用场景
EDA事件驱动架构
源系统发送消息通知其他系统状态改变
接收方响应非必须
发送Event逻辑和处理Event逻辑无依赖,独立变化
解耦,各自扩展
Notification(通知)
依赖着会生成信息副本
远系统推送信息及变化
源系统不可用时,依赖着可以使用副本
容错(Fault Tolerance)
数据的冗余
数据一致性
依赖着维护信息副本和变化
依赖者直接使用信息副本
提高整体性能
Carried State Transfer(通知状态转移)
EDA类别
事件驱动架构模式是一种异步分发事件的架构模式
用于高扩展且低耦合的系统
事件为核心,一系列解耦的、单一功能的事件处理器
针对不同的IO event分配不同的Handler
Selector:监控哪些Channel有IO event
SelectionKey:维护IO event的状和绑定的Handler
经典应用NIO
Nginx的工作进程一直监听端口并等待Event
Event是由新建立的连接所触发的
所有的连接都会被分配到一个对应状态的状态机
Non-blocking
经典应用NGINX
经典案例
何为EDA
中介
流程
存在业务流程
多步骤
统一协调,居中调度
事件分层次
简介
源系统将Event发送到Queue
Event处理系统从Queue中消费Event
源系统和事件处理系统的连接点
Queue只关心事件的传输
Event Queue
中介从Queue中消费原始事件,并分配、协调各个执行步骤
对应业务处理的每个步骤,产生待处理事件(业务事件)
将待处理事件异步分发到不同的通道(Channel)
无具体业务逻辑,只知道有哪些步骤
Event Mediator
Mediator向Channel发送消息,Processor从Channel读取
某种业务事件(消息)的聚合
多个Processor可以监听同一个Channel
Event Channel
监听Channel的Event
一个Processor尽量只做一件事
具体的、单一功能的业务逻辑单元
处理器之间无关联性
所有处理器合作形成完整业务流程
Evenet Processor
发送邮件
Email Send
Email Processor
记录请求日志
History Record
History Processor
修改次数检查
Quota Check
Quota Processor
风险检查
Risk Check
Risk Processor
密码变更Event
修改密码
系统密码修改场景
Mediator中介模式
Mediactor
无中心
无流程
无中心控制器
轻量的消息代理将消息串联成链状
分发至事件处理器组件
事件处理器独立运作
轻量级的代理
无业务逻辑的简单消息分发
源系统将Evenet发送至代理(通道)提供Processor消费
事件通道可以是Queue、Topic或者两者组合
案例说明:学校通知学生事情,学生可以自己去选择看不看,信息透明化,学校只负责通知看不看在于你
Broker
监听Channel的Event,判断是否处理
处理一个事件,并发送一个事件,标明其行为
事件处理器,单一业务逻辑
处理器之间无关联性,不构成业务逻辑链
Event Processor
订单状态变化作为一个事件,每次状态变化都是一个事件
使用代理模式更符合,主流程为主,支线流程不用管
订单状态日志记录
Broker代理模式
EDA的两种Topology
架构能否在不断的改变的使用场景下快速响应
事件处理器组件目的单一、高度解耦,可以独立变化
事件中介与事件处理器是耦合的
代理模式完全解耦
代理拓扑结构比中介拓扑结构调度会更容易
整体灵活性
高度解耦,独立变化
不同组件的运行节点数均可自行调整
组件本身可以进行自行决定是否再拆分实现
横向扩展
计算密集型还是内存密集型,按需调整
纵向扩展
可扩展性Scalability
细粒度的事件处理器有利于提高性能
整体架构是异步并行有利于提高性能
性能
高度解耦的事件处理器组件荣整体部署相对容易
易于部署
EDA模式优点
单元测试无差异
组件众多
异步
集成测试难
可测试性
分布式部署
异常处理难
代码可读性比较复杂
可维护性
分布式消息(事件)传递会降低性能
EDA模式缺点
发送验证码
网站验证功能
用户
Processor1->Processor2->Processor3
验证服务
验证码网关接收验证码
发送消息
编辑消息
短信验证码
Purchased Mediator
订单状态变化事件监听器
Purchased
Approved Mediator
Approved
Confirmed Mediator
Confirmed
Delivered Mediator
Delivered
Closed Mediator
Closed
电商订单声明周期管理
Processor1
->Processor2-
Processor2
Processor3
Data Sync Event Bus(使用Broker方法触发)
数据同步
发送数据
数据同步消息广播
简单了解Listener底层原理
事件驱动架构讲解体系
题目1:Servlet规范中Listener的工作原理
你是不是在讲解中体现你的优势
把所有问题转化成事件,广播出去。
尽可能多的通知到更多人,客服介入的话就是一个简单问题,每个都经过客服比较麻烦
发现将来可能会发生的变化,只要各个模块需要可以自己去监控事件,不要让客服成为唯一通知方式。
题目2:电商系统下单成功,如果有风控问题,需要客服介入,如何设计?
新系统发生字段变更,发送Event给老系统让其变化
把任何一次数据库改写,都做成一个广播,让依赖系统监控服务
事件修改的源头消息发送的出去吗?
发过去之后是否发送成功?
接收方是否能够Listener接收,处理出错或者挂掉等
可能存在问题
在架构方面实现双写
在实现方面如何保证双写
使用锁实现
题目3:淘汰老系统,如何实现双写?
事件驱动架构模式(EventdrivenArch)
海纳百川,有容乃大
什么是内核架构
微内核架构的作用
如何应用微内核架构
弧形反应堆
盔甲
Iron Man(钢铁侠)
按键触发功能键
外观多样
KeyBoard Man(键盘侠)
机器人反应能量-火种
各种汽车
Transformers(变形金刚)
典型应用场景
本章概述
核心功能
资源封装
微内核
可插拔
可扩展性
插件
定义原理
硬件接口
系统资源访问接口
环境/上下文(context)访问接口
系统事件接口
使用场景
规则或者规范
条件
插件规范
支持系统运作的最小功能集
通用流程有核心系统定义
核心定义规范,插件具体实现
职责分离
系统核心
遵循核心系统规范
实现其逻辑外延和业务逻辑
核心系统能力扩展
专注于其独立能力
只能通过核心提供接口操作系统资源
单一返回能力(Single Responsibility)
尽可能避免依赖其它插件
只依赖于核心
插件之间无依赖
插件不能影响核心
隔离
插件模块
插件可用性
获得插件的方式
命名、数据规范、访问协议
插件信息抽象规范
注册
OSGI,点对点绑定(依赖注入)
Web service,message,etc
自定义连接方式
标准规范配合版本策略
自定义规范配合Adapter
通信规范
连接
可以点对点,不能发布订阅
全局事件
不能点对点,可以发布订阅
系统事件
插件事件
事件
核心系统封闭
插件提供开放性
整体系统可持续升级
符合开闭原则
核心系统可以关闭插件
插件内的错误不会被传播到核心系统
错误的传播范围有限
可能有兼容性问题
各自独立升级改进
良好的隔离性
核心系统保持稳定,将变化尽量隔离在插件层
插件根据核心提供的接口和规范来提供丰富的外延功能
整体保持开放,持续进化
灵活性
核心系统和插件系统可以分开测试
插件可以运行在模拟环境
通过简化核心系统,提高其性能
插件按需加钱,降低资源消耗
可以动态关闭插件以保护核心系统
插件可在运行时动态添加到核心系统
减少核心系统停机时间
微内核架构的优点
需要分离核心功能与插件功能
插件需要可以热插拔
需要专门注册协议和通信协议
开发难度高
主要用于开发产品,不考虑扩展性
不以可扩展性见长
可以结合其他模式获得扩展性
可扩展性不高
微内核架构的缺点
名称-插件名称
功能-该插件提供的功能
位置-从何处装载该插件
依赖-插件所需依赖申明
权限-插件所需权限申明
注册规范
同步/异步
本地/远程
数据格式
定义通信机制
受限于核心系统,确定插件的开发语言
语言
依据核心系统定义规范实现功能
功能
按照核心系统定义的开发规范和注册规范提供注册信息
确定加载方式
遵循通信规范
实现插件
基于注册表获取插件信息
启动器/运行期
内存/远程
装载机制
Spring boot思想使用比较多
触发条件
装载条件
装载插件
如何使用微内核架构
通过将不同的应用接入ESB以扩展功能
ESB是核心系统
应用是插件
应用间无直接依赖,都与ESB沟通
ESB
通过BPM组合不同子流程形成新的流程扩展系统功能
BPM是核心系统
子流程是插件
子流程之间无直接依赖
BPM
NGINX通过Module为NGINX添加新的功能
NGINX是核心,Module是plugin
开源NGINX在编译期指定要添加的模块
Nginx Plus可以动态添加或移除Module
NGINX Plus
Servlet实现核心功能
Filter:针对request和response的操作
Listener:Servlet生命周期事件并执行相应的命令
Spring MVC、Struts众多功能都是基于Listener和Filter实现的
Servlet
微内核架构模式(Microkernel)
生财有大道,生之者众,食之者寡,为之者疾,用之者舒,则财恒足矣
核心问题
什么是生产者消费者模式
如何设计生产者消费者系统
即时战略游戏的迷思
世纪难题:水池放水问题
日志打印演进,由单机部署,到多态部署,再到分布式部署,最后使用消息队列(容器)方式记录消息服务
架构演进史
Producer拿到消息PUT消息到Container,Consumer在Container里面消费消息
同步调用变成了异步调用
生产数据和消费数据分离
协调不同处理速度
生产者消费者模式理论
系统运转的动力
为下一环节产生待处理的工作/数据
重点在于如何将数据发送到容器
对消费者无依赖
不关注消费者的How和When
与消费者关系
发送顺序
生产者
从容器中获取数据,并按照自身业务逻辑处理
依赖于容器,不直接依赖于生产者
向容器确认数据已经被消费
这个删除知识改变读取状态并不是真正的删除
从容器中删除(queue)
保留在容器中(Topic)
处理后的数据
消费者
消费者与生产者的交汇点
容量
保存时间
读写效率
保管数据的责任
生产者和消费者的差速器
数据分配策略
容器
数据堆积太多容易崩掉
数据不堆积
消费者不要太多
消费者无资源浪费
调度算法
平衡
核心讲的是时间触发流程
重点在事件本身
不解决事件/消息如何传递的问题
EDA
强调的是从生产端到消费端到全流程
从抽象程度来看EDA更抽象
Producer-Consumer
与EDA异同
决定消费者如何消费数据
Push
Poll
消费方式
Topic
Queue
分发方式
事务性
消费策略
Producer。Consumer和Container都可独立变化
Producer和Consumer互无依赖
无事务系统对三者都无约束
异步运作
Producer,Consumer和Container均可分开部署
Producer,Consumer和Container自称分布式系统
各自按需扩展
通过Container来平衡生产速度和消费速度
动态节点Producer和Consumer数量
避免产生过多数据
避免数据堆积在容器
减少资源浪费
平衡系统差速
生产数据超过消费数据
缓存数据
肖峰
生产数据的速度下降
消费端速度不变
填谷
整体系统运行于匀速状态
单点流量增加不影响系统稳定性
削峰填谷
优点
生产者放入/发送到容器的单体
容器内存储的单体
消费者消费单体
定义
数据单元具备业务含义
数据单元和颗粒度适中
从业务逻辑推导
传输过程中数据单元不可缺失
完整性保证
数据单元是独立的
两个数据单元之间互无影响
无依赖
设计数据单元
对发送成功的确认
始乱终弃(Fire and Forget)
望穿秋水(Synchronous send)
云中谁寄锦书来(Asynchronous send)
生产/发送
时间
空间
数据单元独立性
超时
错误
重试
异常处理
设计Producer
由Container发起,将数据单元推送给Consumer
Consumer可以尽快获得数据
推(Push)
由Consumer发起
Long polling
获取数据有滞后
拉(Pull)
Point to Point
1->1
不可重复消费
1-N
重复消费
Pub/Sub
分发模式
将网络数据流还原为数据单元
JSON
Avro
Thrift
Protobuf
反序列化
记录读到哪里了?下一次直接根据日志继续
Commit log
记录指针的方式,指针指向哪里,处理完,就指向下一个
Ack
消息确认
批量/单体
幂等
Nodes Master-slave
Partitions
Replica
只存meta data
读取转移
Non-replica
集群
数据单元的存储结构
时效性
消息/数据存储
分配数据单元到Consumer
设计Consumer消费方式
Producer保证Consumer至少收到一次数据单元
从业务分析Container中可能有重复数据单元
Consumer实现要防重或幂等
At least once
Producer保证Consumer最多收到一次数据单元
从业务分析Container中可能会丢失部分数据单元
Consumer可能无法读取到所需数据单元
引入第三方数据对比验证程序
At most once
Producer保证Consumer收到并仅收到一次数据单元
从业务分析Container中有且仅有一份数据单元
Consumer无需防重
Exactly once
注意:现实中很少能够实现Exactly once,大多数是实现At least once(消息推送)、At most once(银行转账)
消费保证
早餐炸油条,消费者等待,锅内现炸油条;生产者等待,当没有人买的时候就不会炸油条了;
Thread1往队列里面PUT消息,Thread2在队列中Take消息,Thread1和Thread2都有可能会等待行为就是BlockingQueue
BlockingQueue
支持OpenWire/Stomp/MQTT/AMQP协议
支持TCP/UDP/SSL/HTTP/WebSocket连接方式
Connector
Topic Regin
Queue Regin
Regin
JDBC
Journal
Cache
WM
Message Store
Store&Forward
Discovery
Network Services
ActiveMQ
Kafka与MQ很相似,Kafka不支持Queue只支持Topic
Kafka设计就是一个分布式设计,必须跟Zookeeper配合使用
Kafka(消息/日志)存在Topic会分成不同的Partition,会分布在某个Broker里面,所有的Broker、Partition都存在Zookeeper,扩容的时候,需要扩展Broker、Partition
topic的Partition里面的消息会根据大小设置不同的分片,查找使用的时候通过Index查找
每个Topic会被分成多个Partition,每个Partition会分配到不同的Consumer里面,其中Partition要跟Consumer一一相等,能保证数据读取正常
Partition的offset都是一对一的,能保证数据消费完整每个Topic都维护自己的Partition的读取Offset
Kafka
审批任务
Take任务
PUT任务到Pending tasks queue
任务API
提交任务
申请
ERP审批流程
Defining Custom Event
Event Listener Bean
Event Publisher Bean
Spring events
题目1:什么是BlockingQueue,如何利用BlockingQueue实现Producer-Consumer模式
不是很详细的话可以说说,Broker如何分配Topic,如何分配Partition,Consumer如何对应?消息复制原理?消息如何存储?Zookeeper里面存了什么?如何进行选举的?都要了解一下,再找相关的书籍看看
题目2:描述Kafka的集群架构如何实现的?
生产者消费者模式
四种架构设计模式
架构设计模式
0 条评论
下一页