JEE 将企业级软件架构分为三个层级:算法
- Web 层:负责与用户交互或者对外提供接口。
- 业务逻辑层:为实现业务逻辑而设计的流程处理和计算处理模块。
- 数据存取层:将业务逻辑层处理的结果持久化以待后续查询,并维护领域模型中对象的生命周期。
JEE 平台将不一样的模块化组件聚合后运行在通用的应用服务器上,例如:WebLogic、WebSphere、JBoss、Tomcat数据库
图1-1 JEE 时代的典型架构segmentfault
- Struts、Spring、Hibernate
- 视图、模型、控制器(Struts MVC)
图1-3 MVC 模型
后端
- Spring IoC --> 【Spring思惟导图,让Spring再也不难懂(ioc篇)】
- Spring AOP --> 【Spring思惟导图,让Spring再也不难懂(AOP 篇)】
图1-4 SSH 时代的架构
安全
从 JEE 到 SSH ,服务的特色仍然是单体化、服务的粒度抽象为模块化组件,全部组件耦合在一个项目中,并配置和运行在一个 JVM 进程中。
为解决上述问题,SOA 出现了:服务器
- SOA 表明面向服务的架构,俗称服务化。
- SOA 将应用程序的模块化组件经过【定义明确的接口和契约】联系起来,接口采用中立的方式进行定义,独立于某种语言、硬件和操做系统。
- SOA 一般经过网络通讯来完成,但不局限于某种网络协议,能够是底层的 TCP/IP,也能够是应用层的 HTTP,也能够是消息队列协议,甚至能够是约定的某种数据库存储形式。
SOA 服务化的发展:网络
1、Web Service
SOA 服务化的一种实现方式,使得运行在不一样机器及操做系统上的服务互相发现和调用成为可能,并能够经过某种协议交换数据。
图1-5 Web Service 的工做原理图架构
- 服务提供者 Web Service 2 和 Web Service 3 经过 UDDI 协议将服务注册到 Web Service 目录服务中。
- 服务消费者 Web Service 1 经过 UDDI 协议从 Web Service 目录中查询服务,并得到服务的 WSDL 服务描述文件。
- 服务消费者 Web Service 1 经过 WSDL 语言远程调用和消费 Web Service 2 和 Web Service 3 提供的服务。
2、ESB
ESB 是企业服务总线的简称,用户设计和实现网络化服务交互和通讯的软件模型,是 SOA 的另一种实现方式,主要用于企业信息化系统的集成服务场景中。
ESB 也适用于事件处理、数据转换、映射、消息和事件异步队列顺序处理、安全和异常处理、协议转换、保证通讯服务的质量等场景。
图1-6 ESB 架构图
ESB 服务密友中心化的服务节点,每一个服务提供者都是经过总线的模式插入系统,总线根据流程的编排负责将服务的输出进行转换并发送给流程要求的下一个服务进行处理。并发ESB 的核心在于企业服务总线的功能和职责:负载均衡
- 监控和控制服务之间的消息路由。
- 控制可拔插的服务化的功能和版本。
- 解析服务之间交互和通讯的内容和格式。
- 经过组合服务、资源和消息处理器来统一编排业务须要的信息处理流程。
- 使用冗余来提供服务的备份能力。
图1-7 微服务架构
【康威定律】
一、读者容错模式(Tolerant Reader)
微服务中服务提供者和消费者之间如何对接口的改变进行容错。在服务消费者处理服务提供者返回的消息过程当中,须要对服务返回的消息进行过滤,提取本身须要的内容,对多余或位置内容抛弃,不是硬生生的抛错。
推荐宽松的校验策略,只有没法识别信息,继续处理流程时,才能抛错。
二、消费者驱动契约模式
消费者驱动契约模式用来定义服务化中服务之间交互接口改变的最佳规则。
服务契约分为:提供者契约、消费者契约、消费者驱动契约,它从指望与约束的角度描述了服务提供者与消费者之间的联动关系。
- 提供者契约:以提供者为中心,消费者无条件遵照
- 消费者契约:对某个消费者的需求进行更为精确的描述,能够用来标识现有的提供者契约,也能够用来发现一个还没有明确的提供者契约。
- 消费者驱动的契约:表明服务提供者向其全部当前消费者承诺遵照的约束。一旦各消费者把具体的指望告知提供者,则提供者不管在什么时间和场景下,都不该该打破契约。
图1-10 服务之间的交互须要使用的三种服务契约
三、去数据共享模式
一、服务代理模式
根据业务的需求选择调用后端的某个服务,在返回给使用端前,能够对后端服务的输出进行加工,也能够直接把后端服务的返回结果返回给使用端。
图1-12 服务代理模式
![]()
【典型案例:平滑的系统迁移】
第 3 步,通常只会对读请求切换设计一个开关,开关打开时查询新系统,开关关闭时查询老系统。
图1-13 迁移案例中开关的逻辑
二、聚合服务模式模式
最经常使用的服务组合模式,根据业务流程处理的须要,以必定的顺序调用依赖的多个微服务,对依赖的微服务返回的数据进行组合、加工和转换,返回给使用方。
图1-14 服务聚合模式的架构
![]()
三、服务串联模式
相似工做流,最前面的服务1负责接收请求和相应使用方,串联服务后再与服务1交互,随后服务 1与服务2交互,最后,从服务2产生的结果通过服务1和串联服务逐个处理后返回给使用方。
图1-17 服务串联模式的架构
● 使用 RESTful 风格的远程调用实现;
● 采用同步调用模式,在串联服务没有完成返回以前,全部服务都会阻塞和等待;
● 一个请求会占用一个线程来处理;
● 不建议层级太多,若是能用服务聚合模式,优先使用服务聚合模式;
● 串联链路上增长节点,只要不是在正后方,串联服务无感知
图1-18 在串联服务中调用链的最后增长无感知的架构
图1-19 服务串联模式案例的架构图
四、服务分支模式
● 服务分支模式是服务代理模式、服务聚合模式和服务串联模式相结合的产物。
● 分支服务能够拥有本身的存储,调用多个后端的服务或者服务串联链,而后将结果进行组合处理再返回给客户端。
● 分支服务也可使用代理模式,简单地调用后端的某个服务或者服务链,而后将返回的数值直接返回给使用方。
图1-20 服务分支模式的架构图
调用链上有多个层次重复调用某基础服务,致使基础服务挂掉时影响的流量有累加效果:
假设基础服务资源池中的机器个数为 i,一次挂掉的机器个数为 j,一个调用链中调用 x 次基础服务,那么正确处理的流量的计算公式为:成功率 = ((i-j) / i) x方分支模式放大了服务的依赖关系,在现实设计中尽可能保持服务调用级别的简单,在使用服务组合和服务代理模式时,不要使用服务串联模式和服务分支模式,以保持服务依赖关系的清晰明了。
五、服务异步消息模式
核心的系统服务使用同步调用,核心链路之外的服务可使用异步消息队列进行异步化。
图1-20 服务异步消息模式的架构
五、服务共享数据模式
实际上是反模式
图1-25 服务共享数据模式
【在下面两种场景中,仍然须要数据共享模式】:
1、单元化架构
对性能要求高。
图1-26 单元化架构的示意图
![]()
2、遗留的总体服务
在重构微服务的过程当中,发现单体服务依赖的数据库表耦合在一块儿,对其拆分须要进行反规范化的处理,可能形成数据一致性问题。
一、舱壁隔离模式
1)微服务容器分组
将微服务的每一个节点服务池分为三组:
图1-27 服务分组
2)线程池隔离
图1-28 线程池隔离
二、熔断模式
图1-29 熔断模式
三、限流模式
【有以下几种主流的方法实现限流】:
1)计数器
2)令牌桶
图1-32 令牌桶结构
3)信号量
相似于生活中的漏洞
示例:
public class SemaphoreExample { private ExecutorService exec = Executors.newCachedThreadPool(); public static void main(String[] args) { final Semaphore sem = new Semaphore(5); for (int index = 0; index < 20; index++) { Runnable run = new Runnable() { public void run() { try { // 得到许可 sem.acquire(); // 同时只有 5 个请求能够到达这里 Thread.sleep((long) (Math.random())); // 释放许可 sem.release() System.out.println("剩余许可:" + sem.availablePermits()); } catch(InterruptedException e) { e.printStackTrace(); } } }; exec.execute(run); } exec.shutdown(); } }
四、实现转移模式
【若是微服务架构发生了熔断和限流,则该如何处理被拒绝的请求】
在微服务领域,jar 包被分为:
- 一方库:本服务在 JVM 进程内依赖的 Jar 包。
- 二房库:在服务外经过网络通讯或 RPC 调用的服务的 Jar 包。
- 三方库:所依赖的其余公司或者组织提
Java 微服务项目通常分为:服务导出层、接口层、逻辑实现层
- 服务导出层 : 最后会打包成一个 War 包,包含服务的实现 Jar 包、接口 Jar 包,以及 Web 项目导出 RPC 服务所需的配置文件等。
- 服务接口层 : 包含业务接口、依赖的 DTO 及须要的枚举类等,最后打包成 Jar 包,发布到 Maven 服务器,也包含在服务导出层的 War 包中。
- 服务实现层 : 包含业务逻辑实现类、依赖的第三方服务的包装类,以及下层数据库访问的 DAO 类,最后打包成 Jar。
【服务实现层的架构图】
【服务实现层的反模式架构图】
微服务项目须要实现自动化的CI/CD,包括:
- 代码管理
- 自动编译
- 发布 OA
- 自动化测试
- 性能测试
- 准生产部署和测试
- 生成环境发布
一、JDK RMI
Java 到 Java 的分布式调用框架,一个 Java 进程内的服务能够调用其余 Java 进程内的服务,使用 JDK 内置的序列化和反序列化协议。
- 序列化协议:JDK自带的专用序列化协议,不能跨语言
- 网络传输协议:底层网络协议
二、Hessian & Burlap
- 序列化协议:Hessian 序列化为二进制协议;Burlap 序列化为 XML 数据
- 网络传输协议:HTTP 协议
三、Spring HTTP Invoker
- 序列化协议:Hessian 序列化为二进制协议;Burlap 序列化为 XML 数据
- 网络传输协议:HTTP 协议
一、Dubbo
- 提供高性能、透明化的 RPC 远程服务调用,还提供了基本的服务监控、服务质量和服务调度
- 支持多种序列化协议和通讯编码协议,默认使用 Dubbo 协议传输 Hessian 序列化的数据
- 使用 ZooKeeper 做为注册中心来注册和发现服务
- 经过客户端负载均衡来路由请求,负载均衡算法包括:随机、轮询、最少活跃调用数、一致性哈希等。
二、HSF
High Speed Framework
三、Thrift
- 采用中间的接口描述语言定义并建立服务
- 支持跨语言服务开发和调用,并包含中间的接口描述语言与代码生成和转换工具
- 采用二进制序列化传输数据
四、AXIS
源于 IBM "SOAP4J",使用 SOAP 协议
五、Mule ESB
基于 Java 语言的企业服务总线产品,能够把多个异构系统经过总线模式集成在一块儿
一、Spring Boot
【图1-37 JEE时代,应用包含在容器内的架构图】
Spring Boot 相反,它将容器嵌入自启动的 Jar 包中,在 Spring Boot 应用启动时,内部启动嵌入的容器
【Spring Boot 的容器包含在应用内的架构图】Spring Boot 这种设计在微服务架构下有以下明显有点:
- 能够建立独立、自启动的应用程序
- 无需构建 War 包并发布到容器中,构建和维护 War 包、容器的配置和管理也须要成本
- 经过 Maven 的定制化标签,能够快速构建 Spring Boot 的应用程序
- 能够最大化的自动化配置 Spring,而无需人工配置各项参数
- 提供了产品话特色,如:性能分析、健康检查和外部化配置
- 无 XML 配置
- 是 Spring Cloud 构建微服务架构的重要基础
二、Netflix
提供服务发现、断路器和监控、智能路由、客户端负载均衡、易用的 REST 客户端等服务化必须的功能
三、Spring cloud Netflix
- 服务发现组件 Eureka
- 容错性组件 Hystrix
- 智能路由组件 Zuul
- 客户端负载均衡组件 Ribbon
【图 1-39 Spring Cloud Netfix 架构图】
【Netflix 交互流程】
- 服务在 Eureka 服务器实例注册
- Zuul 做为一个特殊的服务在 Eureka 上注册并发现服务
- Zuul 做为网关,将发现的服务导出给客户端
- RestTemplate 和 FeignClient 使用简单的服务调用方法调用服务一、服务2
【Netflix 特色】
- 服务在 Eureka 注册,由 Spring 管理的 Bean 来发现和调用
- 经过配置的方式能够启动嵌入式的 Eureka 服务器
- Feign 客户端经过声明的方式便可导入服务代理
- Zuul 使用 Ribbon 服务实现客户端负载均衡
- 经过声明的方式便可插入 Hystrix 的客户端
- 经过配置的方式便可启动 Hystrix 面板服务器
- 在 Spring 环境中能够直接配置 Netflix 组件
- Zuul 能够自动注册过滤器和路由器,造成一个反向代理服务器
- Hystrix 面板能够对服务的状态进行监控,并提供容错机制