Java架构模式

分层架构模式

什么是分层架构?

层:软件的逻辑单元

每一层有特定的功能

组件被分配到不同的层

为什么分层?

将系统按照职责拆分和组织

上层依赖于直接下层,下层不可以依赖上层

不可以跃层访问

(经典分层架构:OSI 7层架构:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层。CS 、BS 架构,企业应用三层架构)

缘何分层

康威定律:系统的架构受制于组织的沟通结构

复杂度隔离:隔离业务复杂度和技术复杂度、解决不同层的问题可以选择不同技术栈、

每层变化速度不一致

防止错误传播

减低错误影响

防水仓设计

层自治:本层功能内聚、自主决策、只有本层的知识

分层架构优点

高内聚

低耦合

可维护性好

可测试性高

分层架构缺点

性能下降:分层引入通信开销、层与层都有数据转化、不能跨层访问

开发成本上升

分层架构设计

依赖规则

越向外越具体,越朝内越抽象

外圈 是软件,内圈是规则

依赖关系只能从外向内

定义职责

高层表示规则,底层实现细节

逻辑内聚自治分组

依据组织职责分工

定义技术栈

根据每层的需求各自选定

借鉴成功案例  ↵

部署方式

代码抽象与分层

层对外暴露接口,隐藏实现细节

实现依赖于抽象,抽象不可依赖于实现细节

代码不跨层调用,只依赖于直接的下一层

集成

集成前做单元测试

根据接口和技术栈确定集成方式

集成联调

分层架构模型

MVC

Model:Domain model 和业务逻辑

View: 展示数据和用户交互

Controller:接收输入并转换为对mode的操作

                   将model转化为view能展示的数据

MVVM

BFF

Backend for frontend

避免了终端与多个服务的交流

GraphQL

面试指导:
Http和底层TCP IP链接的关系

什么MVC架构?采用何种技术实现mvc

Spring Cloud Hystrix 断路器的工作原理

如何完成legacy系统重构

事件驱动的架构模式

什么是 EDA

事件驱动架构模式是一种异步分发事件的架构模式

用于高扩展且低耦合的系统

事件为核心,一系列解耦的、单一功能的事件处理器

两种Topology

Mediactor 中介  流程

Broker 无中心 无流程

Mediator中介模式

存在业务流程

多步骤

统一协调,居中调度

事件分层次

Event queue

源系统将event发送到queue

event 处理系统从queue中消费event

源系统和事件处理系统的连接点

Queue只关心事件的传输

Event mediator

中介从queue中消费原始事件,并分配、协调各个执行步骤

对应业务处理的各个步骤,产生待处理事件(业务事件)

将待处理事件异步分发带不同的通道(channel)

无具体业务逻辑,只知道有哪些步骤

Event channel

Mediator向channel发送消息processor从channel读取

某种业务事件(消息)的聚合

多个processor可以监听同一个channel

Event processor

监听channel的event

具体的、单一功能的业务逻辑单元

处理器之间无关联性

Mediator模式应用场景

Broker代理模式

无中心控制器

轻量的消息代理将消息串联成链状

分发至事件处理器组件

事件处理器独立运作

Event channel

Event Processor

监听channel的event,判断是否处理

处理一个事件,并发送一个事件,标明其行为

事件处理器,单一业务逻辑

处理器无关联性,不构成业务逻辑链

Broker

轻量级的代理

无业务逻辑的简单消息分发

源系统将event发送至代理(通道)共processor消费

事件通道可以是queue,topic或者两者组合

Broker模式应用场景:订单状态日志记录

Notification

源系统发送消息通知其他系统状态改变

接收方响应非必须

发身Event逻辑与处理Event逻辑无依赖,独立变化

解耦,各自扩展

Carried State Transfer

源系统推送信息及变化

   依赖者生成信息副本

容错

  源系统不可用时,依赖者可以使用副本

依赖者维护信息副本和变化

    数据的冗余

   数据一致性

提高整体性能

    依赖者直接使用信息副本

EDA解决了什么问题

EDA优点

整体灵活性

架构能否在不断改变的使用场景下快速响应

事件处理器组件目的单一、高度解耦,可以独立变化

代理拓扑结构比中介拓扑结构调度会更容易

  事件中介与事件处理器是耦合的

  代理模式完全耦合

可扩展性

高度解耦,独立变化

横向扩展

     不同组件的运行节点数均可自行调整

     组件本身可以自行决定是否再拆分实现

纵向扩展

   计算密集型还是内存密集型,按需调整

性能

  细粒度的事件处理器有利于提高性能

  整体架构是异步并行有利于提高性能

易于部署

  高度解耦的事件处理器组件让整体部署相对容易

缺点

可测试性

   单元测试无差异

   集成测试难

     组件众多

     异步

可维护性

  分布式部署

  异步

  异常处理难

性能

分布式消息传递会降低性能

  

典型应用场景

NIO 

针对不同的IO event分配不同的handler

Selector : 监控哪些Channel 有IO event

SelectionKey:维护IO event的状态和绑定的handler

Nginx

Nginx的工作进程一直监听端口并等待Event

Event 是由新建立的连接所触发

所有的连接都会被分配到一个对应的状态机

Non-blocking

短信验证码

电商订单生命周期管理

数据同步消息广播

模拟面试

servlet规范中listener的工作原理

电商系统下单成功,如果有风控问题,需要客服介入,如何设计

淘汰老系统,如何实现双写


微内核架构(可扩展)模式

定义

系统核心

资源封装

   硬件接口

   系统资源访问接口

   环境/上下文访问接口

   系统事件接口

定义插件规范

    使用场景

     规则

     条件  

 核心功能

     支持系统运作的最小功能集

 职责分离

     通用流程由核心系统定义

      核心定义规范,插件具体实现

  插件模块

核心系统能力扩展

   遵循核心系统规范

   实现其逻辑外延和业务逻辑

Single Responsibility

    专注于其独立功能

    只能通过核心提供的接口操作系统资源

插件间无依赖

  尽可能避免依赖其他插件

   只依赖于核心

隔离

   插件不能影响核心

注册

插件可用性

获取插件的方式

插件信息抽象规范

     名称、数据规范、访问协议

连接

自定义连接方式

   OSGI,点对点绑定(依赖注入)

   web service,message

通信规范

  标准规范配合版本策略

  自定义规范配合Adapter

事件

点对点发布/订阅
全局事件是       
系统事件
插件事件

优点

符合开闭原则

   核心系统封闭

   插件提供开放性

   整体系统可持续升级

良好的隔离性

   核心系统可以关闭插件

   错误的传播范围有限

        插件内的错误不会被转播到核心系统

  各自独立升级改进

        可能有兼容性问题

灵活性

    核心系统保持稳定,将变化尽量隔离在插件层

    插件根据核心提供的接口和规范来提供丰富的功能  

    整体保持开放,持续进化

可测试性

    核心系统和插件系统可以分开测试

    插件可以运行在模拟环境

性能

    通过简化核心系统,提高性能

    插件按需加载,降低资源消耗

    可以动态关闭插件以保护核心系统

易于部署

     插件在运行时动态添加到核心系统

     减少核心系统停机时间

 缺点

开发难度高

    需要分离核心功能与插件功能

    插件需要热插拔

    需要专门注册协议和通信协议

可扩展性不高

    主要用于开发产品,不考虑扩展性

    不以可扩展性见长

     可以结合其他模式获得扩展性

使用微内核

实际系统核心

定义核心功能

     实现MVP

封装系统资源

   插件通过接口访问

开放集成点

     支持与插件的集成和通信

定义开放规范

核心系统提供的接口及版本

上下文,环境参数

回调、钩子、事件

集成规范

注册规范

名称

功能

位置

依赖

权限

定义通信机制

同步/异步

本地/远程

数据格式

实现插件

语言:受限于核心系统,确定插件的开发语言

功能:依据核心系统定义的规范实现功能

注册:按照核心系统定义的开发规范和注册规范提供注册信息

集成:确定加载方式 ,遵循通信规范

装载插件

基于注册表获取插件信息

装载机制

    启动期/运行期

    内存/远程

装载条件

    触发条件

经典应用

操作系统

LInux

Windows

Eclipse

Rule Engine

   专家系统

      将人类专业知识转化为程序

      用程序来解决专业问题

  Rule

      Condition

      Action

  Rule Engine

      基于输入数据执行规则的专家系统

      如果满足条件则执行对应的任务

ESB(Enterprise Service Bus)

   通过将不同应用接入ESB以扩展系统功能

    ESB是核心系统

   应用是插件

   应用间无直接依赖,都与ESB沟通

BPM()

     通过BPM组合不同子流程形成新的流程扩展系统功能

     BPM是核心系统

     子流程是插件

      子流程间无直接依赖

NGNIX Plus

     NGNIX 通过module 为NGNIX添加新功能

     NGNIX是核心,module是plugin

     开源NGNIX在编译期指定要添加的模块

     NGNIX Plus 可以动态添加或移除module

Servlet

    Seevlet实现核心功能

插件

    Filter:针对request 和response的操作

    Listener: Servlet生命周期事件并执行相应命令

Spring MVC ,Struts众多功能都是基于Litenner和Filter实现

生产者消费者架构

生产者消费者模式

   同步调用变成异步调用

   生产数据与消费数据分离

   协调不同处理速度

   

生产者

   系统运转的动力

   为下一个环节产生待处理的工作/数据

   与消费者关系

      重点在如何将数据发送到容器

      对消费者无依赖

      不关注消费者的how/when

   发送顺序

消费者

从容器中获得数据,并按照自身业务逻辑处理

依赖于容器,不直接依赖于生产者

向容器确认数据已经被消费

处理后的数据

    从容器中删除

    保留在容器中

消费顺序

容器

消费者与生产者的交汇点

保管数据的责任

    容量

    保存时间

    读写效率

生产者和消费者的差速器

数据分配策略

核心问题

平衡

数据不堆积

消费者无资源浪费

EDA异同

  EDA

    时间触发流程

    重点在事件本身

    不解决事件/消息如何传递的问题

Producer-Consumer

   强调的是从生产端到消费端到全流程

   从抽象程度来看EDA更抽象

消费策略

决定消费者如何消费数据

消费方式

   PUSH

   Poll

分发方式

   Topic

   Queue

事务性

优点

低耦合

  Producer,Consumer和Container 均可独立变化

  Producer和Consumer互无依赖

  无事务系统对三者都无约束

  异步运作

分布式部署

   Producer,consumer和container均可分开部署

   Producer,consumer和container自成分布式系统

   各自按需扩展

平衡系统差速

通过container来平衡生产速度和消费速度

动态调节producer和consumer数量

减少资源浪费

   避免生产过多数据

   避免数据堆积在容器

消峰填谷

    消峰

        生产数据超过消费数据

        缓存数据

   填谷

      生产数据的速度下降

      消费端消费速度不变   

   单点流量增加不影响系统稳定性

      整体系统运行于匀速状态

设计数据单元

定义

  生产者放入/发送到容器的单体

  容器内存储的单体

  消费者消费的单体

从业务逻辑推导

  数据单元具备业务含义

  数据单元的颗粒度适中

完整性保证

    传输过程中数据单元不可缺失

无依赖

    数据单元是独立的

    两个数据单元之间无影响

设计Producer

生产/发送

   对发送成功的确认

  始乱终弃(Fire-and-forget)

   望穿秋水(Synchronous send')

  云中谁寄锦书来(Asynchronous send)

序列化

   数据单元变成用于网络传输的数据

   JSON

   AVro

   Thrift

    Protobuf

数据单元独立性

    时间

    空间

异常处理

   超时

  错误

  重试

Consumer消费方式

   由container发起,将数据单元推送给consumer

   Consumer可以尽快获得数据

拉(pull)

  由consumer发起

  获取数据有滞后

设计分发模式

Queue

   Point to Point

   1-》1

   不可重复消费

Pub/Sub

    Topic

    1->N

     重复消费

设计消费者

   反序列化

     将网络数据还原为数据单元

消费确认

   commit log

    Ack

消费策略

  批量/单体

  同步/异步

  幂等

设计container

集群

Replica

   Nodes Master-slave

   Partitions

Non-replica

  只存meta data

  读取转移

消息/数据存储

    数据单元的存储结构

    时效性

调度算法

    分配数据单元到consumer

Qos

at least one 

    producer保证consumer至少收到一次数据单元

    从业务分析container中可能有重复数据单元

    Consumer实现要防重或幂等

at most once

    producer 保证consumer 最多收到一次数据单元

    从业务分析container中可能会对视部分数据单元

   consumer可能无法读取到所需数据单元

    引入第三方数据对比验证程序

exactly once

   producer保证consumer收到并仅收到一次数据单元

   从业务分析container中有且仅有一份数据单元

   consumer无需防重

经典实现

BlockQueue

ActiveMQ

Kafka

ERP审批流程

Spring events

       

软件架构的评估理论

ATAM

CBAM 成本效益分析方法

生产环境全监控

  cpu使用率

   内存

   存储空间

   线程数 :线程数量 线程状态

系统测试与调优

线下压测

Jmeter

接口级别

小模块、组件 

环境差异

场景多样性

线下压测

模拟模拟流量

线上导流(TcpCopy、TM双引擎测试)

单机压测

集群/全链路压测  

写测试数据打标

接口读写场景混合

数据散列(冷+热)

负载测试与压力测试

压力测试

    流量逐步

        性能变化曲线

        最佳状态

        崩盘负载点

负载测试

    流量逐步

       性能指标

       临界资源

       最大负载

稳定性测试

条件

   一定的负载条件下

  较长时间执行

  稳定性指标(控制线)

目的

  不稳定因素

  系统瓶颈

稳定性测试范围

  链路 

  测试场景

构建模型

    基线

    控制线

    KPI

分析测试结果

算出标准差、方差

计算 控制线 = 数学期望 +- 3*标准差

如何确定最佳线程数

CPU密集型 : CPU核心数+1

最小线程数:CPU核心数 

IO密集型 :CPU核心数/(1-阻塞系数)(阻塞系数=阻塞时间/(阻塞时间+cpu时间))

实践出真知

增加线程数 :接口qps不变,甚至RT变长

减少线程数: 接口Qps下降

  

如何解决业务接口高RT的情况

异步

Future

CallBack

Guava包,ListenableFuture,SettableFuture,FutureCallBack

异步编排

CompletableFuture

系统容量规划

流量预估

系统容量预估

全链路压测

限流降级预案

网关流控

限流

   QPS 

       全局维度

       用户维度

       IP维度

   Sentinel

       调用方限流

       热点限流

准入

  黑名单

  白名单

  DDos高防

整形

预热/冷启动

匀速通过

排队机制

后端降级\客户端限流等

前端柔性

分布式系统理论

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值