常用框架技术- 08 Spring Cloud简单易懂、易部署和易维护的分布式系统开发工具包
创始人
2024-04-07 00:07:29

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 1.微服务理论
    • 1.1 微服务的特点
    • 1.2 微服务与微服务架构
    • 1.3 微服务的优点
  • 2.分布式集群概念
    • 2.1 分布式集群概念
      • 2.1.1 什么是分布式
      • 2.1.2 什么是集群
      • 2.1.3 分布式集群的关系
    • 2.2 架构演进过程
      • 2.2.1 单体架构
      • 2.2.2 垂直架构
      • 2.2.3 SOA架构
      • 2.3.4 分布式架构
    • 2.3 RPC是什么
      • 2.3.1 RPC 框架原理
      • 2.3.2 服务之间的交互可以用两种方式
    • 2.4 分布式思想相关概念
      • 2.4.1 高并发
      • 2.4.2 高可用
      • 2.4.3 注册中心
      • 2.4.4 负载均衡
      • 2.4.5 服务雪崩
      • 2.4.6 服务熔断
      • 2.5.7 服务限流
      • 2.5.8 API网关
      • 2.5.9 服务跟踪
      • 2.5.10 弹性云
  • 3.Spring Cloud概述及环境准备
    • 3.1 Spring Cloud概述
    • 3.1 环境准备
      • 3.1.1 数据库环境准备
      • 3.1.2 项目准备
  • 4.Eureka服务注册与发现
    • 4.1 Eureka概述
      • 4.1.1 Eureka简介
      • 4.1.2 什么是服务注册
      • 4.1.3 Eureka的组件
    • 4.2 Eureka Server服务代码实现
      • 4.2.1 在springcloudparent项目中构建cloud-eureka-server7001模块,并导入依赖。
      • 4.2.2 编写yml配置文件,配置Eureka配置信息
      • 4.2.3 编写启动类EurekaServerMain7001.java
      • 4.2.4 启动服务测试
    • 4.3 将服务的提供者cloud-provider-payment8001注册到服务中心中
      • 4.3.1 导入依赖
      • 4.3.2 编写yml配置文件,配置Eureka配置信息
      • 4.3.3 在启动类上添加`@EnableEurekaClient`注解
      • 4.3.4 启动服务进行测试
    • 4.4 将服务的消费者cloud-consumer-order8000注册到服务中心中
      • 4.4.1 导入依赖
      • 4.4.2 编写yml配置文件,配置Eureka配置信息
      • 4.4.3 在启动类上添加`@EnableEurekaClient`注解
      • 4.3.4 启动服务进行测试
    • 4.5 总服务测试
  • 5.Ribbon负载均衡服务调用
    • 5.1 概述
      • 5.1.1 简介
      • 5.1.2 可以做什么
    • 5.2 Ribbon负载均衡演示
      • 5.2.1 架构示例图
      • 5.2.2 默认负载均衡策略代码演示
    • 5.3 负载均衡的策略
      • 5.3.1 IRule:根据特定算法从服务列表中选取一个要访问的服务
      • 5.3.1 将上述案例的默认策略改为RandomRule随机策略-编码方式
      • 5.3.2 配置轮询策略-配置yml方式
    • 5.4 负载均衡算法-轮询策略
    • 5.5 小结
  • 6.OpenFeign 声明式服务调用
    • 6.1 概述
      • 6.1.1 什么是Feign
      • 6.1.2 Feign作用
    • 6.2 OpenFeign开发步骤
      • 6.2.1 新建项目cloud-consumer-feign-order8000
      • 6.2.2配置YML文件
      • 6.2.3 编写启动类
      • 6.2.4 编写微服务调用PaymentFeignService接口并新增注解@FeignClient
      • 6.2.5 编写OrderController,通过微服务调用接口访问远程服务
      • 6.2.6 启动服务测试
      • 6.2.7 小结
    • 6.3 OpenFeign的超时设置
      • 6.3.1 超时演示
      • 6.3.2 什么是超时
      • 6.3.3 yml中配置OpenFeign的超时控制
    • 6.4 OpenFeign的日志打印
      • 6.4.1 概述
      • 6.4.2 配置日志bean
      • 6.2.3 在yml配置文件中需要配置开启日志的Feign客户端
      • 6.2.4 重启服务器访问测试
  • 7.Hystrix断路器
    • 7.1 雪崩的概述
    • 7.2 Hystrix简介
      • 7.2.1 服务的降级(Fallback)
      • 7.2.2 服务熔断Breaker
      • 7.2.3 服务限流
    • 7.3 高并发测试工具-Jmeter
    • 7.4 Hystrix案例
      • 7.4.1 构建一个新的服务提供者模块
      • 7.4.2 构建一个新的服务消费者模块
  • 7.5 服务的降级
    • 7.5.1 服务提供端降级处理:cloud-provider-hystrix-payment8001
    • 7.5.2 服务的消费端设置降级:cloud-consumer-feign-hystrix-order8000
    • 7.5.2 定义统一的降级方法
    • 7.5.2 实现服务降级业务解耦
    • 7.6 服务的熔断
      • 7.6.1 概述
      • 7.6.2 代码实现-cloud-provider-hystrix-payment8001项目
      • 7.6.3 服务熔断原理
    • 7.6 服务的限流
    • 7.7 服务监控hystrixDashboard
      • 7.7.1 服务监控的概述
      • 7.7.2 仪表盘9001
      • 7.7.3 断路器的演示
  • 8.Gateway新一代网关
    • 8.1 概述简介
      • 8.1.1 Gateway概述
      • 8.1.2 网关能干啥
      • 8.1.3 微服务架构中网关在哪里
    • 8.2 网关的核心概念
    • 8.3 Gateway工作流程
    • 8.4 入门案例
      • 8.4.1 创建新的模块cloud-gateway-gateway9527
      • 8.4.2 配置yml文件
      • 8.4.3 添加启动类
      • 8.4.4 在yml中配置路由映射
      • 8.4.5 启动程序测试
    • 8.5 通过微服务名实现动态路由
      • 8.5.1 配置yml文件
      • 8.5.2 启动程序测试
    • 8.6 Predicate的使用
      • 8.6.1 是什么
      • 8.6.2 常用的Route Predicate
    • 8.7 Filter的使用
      • 8.7.1 概述
      • 8.7.2 局部过滤器
      • 8.7.3 全局过滤器
      • 8.7.4 GatewayFilter(31种之多)
      • 8.7.5 GlobalFilter
      • 8.7.6 常用的GatewayFilter
    • 8.8 自定义过滤器
      • 8.8.1 自定义一个类LoginFilter实现GlobalFilter,Ordered接口
      • 8.8.2 重启网关测试
  • 9.SpringCloud Sleuth分布式链路请求跟踪
    • 9.1 概述
    • 9.2 搭建链路监控步骤
      • 9.2.1 zipkin
      • 9.2.2 服务提供者cloud-provider-payment8001
      • 9.2.3 服务消费者(调用方)cloud-consumer-order8000
      • 9.2.4 重启项目测试
  • 10 SpringCloud Alibaba入门简介
    • 10.1 为啥会有SpringCloud Alibaba
    • 10.2 SpringCloud Alibaba带来了什么?
      • 10.2.1 概述
      • 10.2.2 作用
    • 10.2.3 依赖
      • 10.2.4 如何用
  • 11.SpringCloud Alibaba Nacos服务注册和配置中心
    • 11.1 Nacos简介
    • 11.2 各种注册中心比较
    • 11.3 安装并运行Nacos
      • 11.3.1 下载Nacos
      • 11.3.2 安装并运行Nacos
      • 11.3.4 运行后在浏览器访问
      • 11.3.5 主页面如下
    • 11.4 Nacos作为服务注册中心演示
      • 11.4.1 官方网站
      • 11.4.2 基于Nacos的服务提供者
      • 11.4.3 基于Nacos的服务消费者
      • 11.4.4 服务注册中心对比
    • 11.5 Nacos作为服务配置中心演示
      • 11.5.1 Nacos作为配置中心-基础配置
      • 11.5.2. Nacos作为配置中心-分类配置
    • 11.6 Nacos集群和持久化配置(重要)
      • 11.6.1 官网说明
      • 11.6.2 Nacos持久化配置解释
      • 11.4.3. Linux版Nacos+MySQL生产环境配置
  • 12 SpringCloud Alibaba Sentinel实现熔断与限流
    • 12.1 Sentiel介绍
    • 12.2 安装Sentinel控制台
      • 12.2.1 Sentinel两个核心组件
      • 12.2.2 安装步骤
    • 12.3 初始化演示工程
      • 12.3.1 启动Nacos8848成功
      • 12.3.2 案例
    • 12.4 流控规则
      • 12.4.1 基本概述
      • 12.4.2 流量模式
      • 12.4.3 流控效果
    • 12.5 熔断规则
      • 12.5.1 基本概述
      • 12.5.2 熔断策略实战
    • 12.6 热点规则
      • 12.6.1 基本概述
      • 12.6.2 承上启下复习
      • 12.6.3 代码实现
      • 12.6.4 参数例外项
      • 12.6.5 其他
    • 12.7 系统规则
      • 12.7.1 基本概述
      • 12.7.2 系统规则
      • 12.7.3 配置全局QPS
    • 12.8 @SentinelResource
      • 12.8.1 基本概述
      • 12.8.2 流控规则+自定义处理
      • 12.8.3. 上面兜底方法面临的问题
      • 12.8.4. 集中自定义处理
      • 12.8.5. 更多注解属性说明
    • 12.9 熔断框架比较
    • 12.10 规则持久化
      • 12.10.1 基本概述
      • 12.10.2 代码实现


前言

Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。


提示:以下是本篇文章正文内容,下面案例可供参考

1.微服务理论

微服务(Microservice Architecture)是最近几年流行的一种架构思想。简单来说,微服务架构风格是一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中,服务间通信采用轻量级通信机制(通常用HTTP资源API)。这些服务围绕业务能力构建并且可通过全自动部署机制独立部署。这些服务共用一个最小型的集中式的管理,服务可用不同的语言开发,使用不同的数据存储技术。

1.1 微服务的特点

应用(服务)组件化
每一个应用都是一个单独的服务,所有的应用都可以被单独的替代或升级,单独进行部署。
服务无状态化
这个是可以实现微服务快速扩展的基本条件。
标准而轻量级的通信协议
Restful,把所有的应用通过相同的协议集成在一个平台当中。
去中心化
包含数据去中心化,技术栈去中心化。

1)技术去中心化:既可以使用java,也可以使用php,go。只要使用支持标准通信协议就可以接入微服务平台。

2)数据去中心化:每个服务可以使用自己独立的数据源,可以使用mysql,redis等等。
故障处理设计和实时监控
微服务发展到后面会越来越复杂,服务变多,环境复杂,所以当出现问题需要有相应的系统容错机制和完善的实时的日志监控。

1.2 微服务与微服务架构

微服务:强调的是服务的大小,他关注的是某一个点。
微服务架构:他是一种风格,一种思想,需要从整体上对软件系统进行通盘的考虑。
在这里插入图片描述

1.3 微服务的优点

  1. 简单灵活,可以独立部署,对其他服务不会影响。
  2. 松耦合,高内聚,易扩展。服务于服务之间是松耦合的。
  3. 专注,专业,可靠的小团队。微服务一个很大的特点就是可以和敏捷开发有个好的整合,因为微服务每个模块都可以很小,正好适合小团队。
  4. 语言,工具无关系。只要任何语言合适就可以使用。
  5. 能够实现复杂的项目的持续集成和持续交付。不像大型项目,发布一次可能几十分钟,牵涉的东西也很多,而微服务项目比较小,启动也很快

2.分布式集群概念

2.1 分布式集群概念

2.1.1 什么是分布式

分布式系统一定是由多个节点组成的系统。其中,节点指的是计算机服务器,而且这些节点一般不是孤立的,而是互通的。这些连通的节点上部署了我们的节点,并且相互的操作会有协同。分布式系统对于用户而言,他们面对的就是一个服务器,提供用户需要的服务而已,而实际上这些服务是通过背后的众多服务器组成的一个分布式系统,因此分布式系统看起来像是一个超级计算机一样。简单来说:很多"人”一起,干不样的事。这些不一样的事, 合起来是一件大事。

2.1.2 什么是集群

集群是指在几个服务器上部署相同的应用程序来分担客户端的请求。
它是同一个系统部署在不同的服务器上,比如一个登陆系统部署在不同的服务器上。好比 多个人一起做同样的事。集群主要的使用场景是为了分担请求的压力。但是,当压力进一步增大的时候,可能在需要存储的部分,比如mysql无法面对大量的“写压力”。因为在mysql做成集群之后,主要的写压力还是在master的机器上,其他slave机器无法分担写压力,这时,就引出了“分布式”。简单来说:很多“人”一起,干一样的事

2.1.3 分布式集群的关系

上面说了:分布式是一群人做不同的事情,所有的事务合起来是一个整体。集群是一群人做相同的事情。所有分布式系统中每一个节点服务都可以搭建集群,但是集群不一定是分布式架构。
在这里插入图片描述

2.2 架构演进过程

2.2.1 单体架构

一个war包或jar包的项目中,包含了应用所有功能的应用程序,我们通常称之为单体应用。单体架构中,全部功能集中在一个项目内(All in one),这是一种比较传统的架构风格。
在这里插入图片描述
优势:
架构简单,前期开发成本低、开发周期短,适合小型项目(OA、CRM、ERP 企业内部应用)。
缺点
① 复杂性高
② 技术债务逐渐上升
③ 部署速度逐渐变慢
④ 扩展能力受限,无法按需伸缩
⑤ 阻碍技术创新

2.2.2 垂直架构

垂直架构是指将单体架构中的多个模块拆分为多个独立的项目。形成多个独立的单体架构。垂直MVC项目主要有表现层,业务逻辑层,数据访问层组成的MVC架构,整个项目打包放在一个tomcat里面。适合于 访问量小,用户数不多的业务。
在这里插入图片描述
优点
技术栈可扩展(不同的系统可以用不同的编程语言编写)。
缺点
① 垂直架构中每一个系统还是单体架构。不利于开发、扩展、维护,项目的部署效率很低,代码全量编译和部署一次发布需要很长时间,更重要的是 如果某个功能出错有问题,所有的功能都需要再重新打包编译,部署效率极低。

② 相互无法访问,导致多个项目中可能要编写重复的功能代码,加载重复的数据。

③ 团队协作难度高,如多人使用 git 很可能在同一个功能上,多人同时进行了修改,作为一个大而全的项目,可能个人只是需要开发其中一个小的模块的需求,却需要导入整个项目全量的代码。

2.2.3 SOA架构

SOA 全称为 Service-Oriented Architecture,即面向服务的架构。它可以根据需求通过网络对松散耦合的粗粒度应用组件(服务)进行分布式部署、组合和使用。一个服务通常以独立的形式存在于操作系统进程中。站在功能的角度,把业务逻辑抽象成可复用的服务,通过服务的编排实现业务的快速再生,目的:把原先固有的业务功能转变为通用的业务服务,实现业务逻辑的快速复用。
在这里插入图片描述
优点
① 可重用性高
② 维护成本低
③ 可扩展性强
缺点
① 抽取服务的粒度大
② 技术难度较高,不容易解决bug

2.3.4 分布式架构

其实和 SOA 架构类似,微服务是在 SOA 上做的升华,微服务架构强调的一个重点是“业务需要彻底的组件化和服务化”,原有的单个业务系统会拆分为多个可以独立开发、设计、运行的小应用。这些小应用之间通过服务完成交互和集成。
在这里插入图片描述优点
① 服务拆分粒度更细,遵循单一职责原则,有利于提高开发效率。
② 可采用Http协议进行服务间的调用
③ 可以针对不同服务制定对应的优化方案,适用于互联网时代,产品迭代周期更短。
缺点
① 对开发团队技术要求高

2.3 RPC是什么

RPC(Remote Procedure Call)— 远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。

2.3.1 RPC 框架原理

在这里插入图片描述
RPC 架构主要包括三部分:

  • 服务注册中心(Registry),负责将本地服务发布成远程服务,管理远程服务,提供给服务消费者使用。
  • 服务提供者(Server),提供服务接口定义与服务实现类。
  • 服务消费者(Client),通过远程代理对象调用远程服务。
    服务提供者启动后主动向服务注册中心(Registry)注册机器IP、端口以及提供的服务列表;

服务消费者启动时向服务注册中心(Registry)获取服务提供方地址列表。服务注册中心(Registry)可实现负载均衡和故障切换。
RPC 调用过程
在这里插入图片描述
在这里插入图片描述

(1) 客户端(client)以本地调用方式调用服务;

(2) 客户端存根(client stub)接收到调用后,负责将方法、参数等组装成能够进行网络传输的消息体(将消息体对象序列化为二进制);

(3) 客户端通过 sockets 将消息发送到服务端;

(4) 服务端存根(server stub)收到消息后进行解码(将消息对象反序列化);

(5) 服务端存根(server stub)根据解码结果调用本地的服务;

(6) 本地服务执行并将结果返回给服务端存根(server stub);

(7) 服务端存根(server stub)将返回结果打包成消息(将结果消息对象序列化);

(8) 服务端(server)通过 sockets 将消息发送到客户端;

(9) 客户端存根(client stub)接收到结果消息,并进行解码(将结果消息发序列化);

(10) 客户端(client)得到最终结果。

RPC 就是要把 2、3、4、7、8、9 这些步骤都封装起来。

2.3.2 服务之间的交互可以用两种方式

1.RPC调用: Netty(Socket)+自定义序列化
2.RestAPI: 严格来说,SpringCloud是使用Rest方式进行服务之间交互的,不属于RPC。HTTP+JSON

2.4 分布式思想相关概念

2.4.1 高并发

1.通过设计保证系统可以并行处理很多请求。应对大量流量与请求

  • Tomcat最多支持并发多少用户?
    • Tomcat 默认配置的最大请求数是 150,也就是说同时支持 150 个并发,当然了,也可以将其改大。
    • 当某个应用拥有 250 个以上并发的时候,应考虑应用服务器的集群。
    • 具体能承载多少并发,需要看硬件的配置,CPU 越多性能越高,分配给 JVM 的内存越多性能也就越高,但也会加重 GC 的负担。
  • 操作系统对于进程中的线程数有一定的限制:
    • Windows 每个进程中的线程数不允许超过 2000
    • Linux 每个进程中的线程数不允许超过 1000
    • 另外,在 Java 中每开启一个线程需要耗用 1MB 的 JVM 内存空间用于作为线程栈之用。
    • Tomcat 默认的 HTTP 实现是采用阻塞式的 Socket 通信,每个请求都需要创建一个线程处理。这种模式下的并发量受到线程数的限制,但对于 Tomcat 来说几乎没有 BUG 存在了。
    • Tomcat 还可以配置 NIO 方式的 Socket 通信,在性能上高于阻塞式的,每个请求也不需要创建一个线程进行处理,并发能力比前者高。但没有阻塞式的成熟。
  • 这个并发能力还与应用的逻辑密切相关,如果逻辑很复杂需要大量的计算,那并发能力势必会下降。如果每个请求都含有很多的数据库操作,那么对于数据库的性能也是非常高的。
  • 对于单台数据库服务器来说,允许客户端的连接数量是有限制的。
  • 并发能力问题涉及整个系统架构和业务逻辑。
  • 系统环境不同,Tomcat版本不同、JDK版本不同、以及修改的设定参数不同。并发量的差异还是满大的。
    • maxThreads=“1000” 最大并发数 ,默认值为200
    • minSpareThreads=“100”//初始化时创建的线程数,默认值为10
    • acceptCount=“700”// 指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理,默认值为100

2.高并发衡量指标

  • 响应时间(RT)
    • 请求做出响应的时间,即一个http请求返回所用的时间
  • 吞吐量
    • 系统在单位时间内处理请求的数量
    • QPS(Query/Request Per Second)、 TPS(Transaction Per Second)
  • 每秒查询(请求)数、每秒事务数
    • 专业的测试工具:Load Runner
    • Apache ab
    • Apache JMeter
  • 并发用户数
    • 承载的正常使用系统功能的用户的数量

2.4.2 高可用

  • 高可用: 通常是指通过合理的设计下,减少服务不能提供的时间。是分布式中一个很重要的考虑因素。
  • 如何保证高可用:
    • 服务的集群部署
    • 数据库主从+双机热备
  • 主-备方式(Active-Standby方式)
    • 主-备方式即指的是一台服务器处于某种业务的激活状态(即Active状态),另一台服务器处于该业务的备用状态(即Standby状态)。
  • 双主机方式(Active-Active方式)
    • 双主机方式即指两种不同业务分别在两台服务器上互为主备状态(即Active-Standby和Standby-Active状态)

2.4.3 注册中心

  • 保存服务地址等信息的地方,方便其它调用者实时的获取服务信息。
  • 服务注册:服务的提供者,将服务的地址信息注册到注册中心。
  • 服务发现:服务的消费者,从注册中心发现并保存服务提供者的地址信息。

2.4.4 负载均衡

  • 是高并发、高可用系统必不可少的关键组件,目标是 尽力将网络流量平均分发到多个服务器上,以提高系统整体的响应速度和可用性。简单来说,就是根据某种策略将将请求发送给空闲的服务器。
  • 策略
    • 轮询(Round Robin)
    • 加权轮询(Weighted Round Robin)
    • 随机Random
    • 哈希Hash
    • 最小连接数LC
    • 最短响应时间LRT

2.4.5 服务雪崩

雪崩效应 : 在微服务之间进行服务调用是由于某一个服务故障,导致级联服务故障的现象,称为雪崩效应。雪崩效应描述的是提供方不可用,导致消费方不可用并将不可用逐渐放大的过程。
在这里插入图片描述

2.4.6 服务熔断

服务熔断的作用类似于我们家用的保险丝,当某服务出现不可用或响应超时的情况时,为了防止整个系统出现雪崩,暂时停止对该服务的调用。
在这里插入图片描述

2.5.7 服务限流

服务限流就是为了保护后端服务和数据不被大流量击垮而设计,当发生流量浪涌时,让实例能在最大有效负荷运行,而不会超过负载导致崩溃。限流就是限制某个服务每秒的调用本服务的频率
在这里插入图片描述

2.5.8 API网关

API网关要做很多工作,它作为一个系统的后端总入口,承载着所有服务的组合路由转换等工作,除此之外,我们一般也会把安全,限流,缓存,日志,监控,重试,熔断等放到 API 网关来做。

2.5.9 服务跟踪

当部署的服务越来越多的时候,需要跟踪一个请求从一个服务到下一个微服务的传播过程。追踪服务的调用链,记录整个系统执行请求过程。如:请求响应时间,判断链中的哪些服务属于慢服务(可能存在问题,需要改善)。

2.5.10 弹性云

所谓的弹性,指的是云端的可用资源能够随着用户的需求而灵活变化、自由升降,在业务高峰或低谷期,能匹配适量的资源。
弹性云服务器,简单地说,是指运行在云计算环境中的虚拟服务器,支持用户自由调度计算资源,不受传统硬件设备的限制。
Elastic Compute Service(ECS)弹性计算服务
动态扩容,压榨服务器闲时能力
例如:双11,618,高峰时多配置些服务器,平时减少多余的服务器配置(用于其他服务应用),避免资源浪费

3.Spring Cloud概述及环境准备

3.1 Spring Cloud概述

  • Spring Cloud 是一系列框架的有序集合。
  • Spring Cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来。
  • 通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
  • 它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、 断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。
  • Spring Cloud项目官方网址:https://spring.io/projects/spring-cloud
  • Spring Cloud 版本命名方式采用了伦敦地铁站的名称,同时根据字母表的顺序来对应版本时间顺序,比如:最早的Release版本:Angel,第二个Release版本:Brixton,然后是Camden、Dalston、Edgware,Finchley,Greenwich,Hoxton。
  • Spring Cloud 与 Dubbo 对比

在这里插入图片描述

  • spring cloud微服务架构
    在这里插入图片描述
  • spring cloud组件图
    在这里插入图片描述

3.1 环境准备

3.1.1 数据库环境准备

CREATE DATABASE  IF NOT EXISTS cloud2022 DEFAULT CHARACTER SET utf8 ;USE cloud2022 ;DROP TABLE IF EXISTS payment ;CREATE TABLE payment (id BIGINT (20) NOT NULL AUTO_INCREMENT COMMENT 'ID',SERIAL VARCHAR (300) DEFAULT NULL,PRIMARY KEY (id)
) ENGINE = INNODB AUTO_INCREMENT = 33 DEFAULT CHARSET = utf8 ;INSERT INTO payment (id, SERIAL) VALUES(31, '商品01'),(32, '商品02') ;

3.1.2 项目准备

在这里插入图片描述

初始化项目已准备好直接导入即可
在这里插入图片描述

4.Eureka服务注册与发现

4.1 Eureka概述

4.1.1 Eureka简介

  • Eureka 是 Netflix 公司开源的一个服务注册与发现的组件 。
  • Eureka 和其他 Netflix 公司的服务组件(例如负载均衡、熔断器、网关等) 一起,被 Spring Cloud 社区整合为Spring-Cloud-Netflix 模块。
  • Eureka 包含两个组件:Eureka Server (注册中心) 和 Eureka Client (服务提供者、服务消费者)。

4.1.2 什么是服务注册

  • Eureka采用了CS的设计架构,Eureka Server作为服务注册功能的服务器,它是服务注册中心。
  • 而系统中的其他微服务,使用Eureka的客户端连接到Eureka Server并维持心跳连接。这样系统的维护人员可以通过Eureka Server来监控系统中各个微服务是否正常运行。
  • 在服务注册与发现中,有一个注册中心。当服务器启动的时候,会把当前自己服务器的信息,比如:服务通讯地址等以别名方式注册到注册中心上。
  • 另一方(消费者服务),以该别名的方式去注册中心上获取到实际的服务通讯地址,然后,再实现本地RPC远程调用。
  • RPC远程调用框架核心设计思想:在于注册中心,因为使用注册中心管理每个服务与服务之间的一个依赖关系(服务治理概念)。
  • 在任何RPC远程框架中,都会有一个注册中心(存放服务地址相关信息(接口地址))。

在这里插入图片描述

4.1.3 Eureka的组件

1.Eureka Server提供服务注册服务
各个微服务节点通过配置启动后,会在Eureka Server中进行注册,这样Eureka Server中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观看到。
2.Eureka Client通过注册中心进行访问
是一个Java客户端,用于简化Eureka Server的交互,客户端同时也具备一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会在Eureka Server发送心跳(默认周期30秒)。如果Eureka Server在多个心跳周期内没有收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移出(默认90秒)

4.2 Eureka Server服务代码实现

4.2.1 在springcloudparent项目中构建cloud-eureka-server7001模块,并导入依赖。

在这里插入图片描述
导入相关依赖

	org.springframework.cloudspring-cloud-starter-netflix-eureka-servercom.atguigucloud-api-commons${project.version}org.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-actuatororg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklombokorg.springframework.bootspring-boot-starter-testtestjunitjunit

4.2.2 编写yml配置文件,配置Eureka配置信息

server:port: 7001spring:application:name: cloud-eureka-servereureka:instance:hostname: localhostclient:register-with-eureka: falsefetchRegistry: falseservice-url:defaultZone: http://localhost:7001/eureka

4.2.3 编写启动类EurekaServerMain7001.java

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerMain7001 {public static void main(String[] args) {SpringApplication.run(EurekaServerMain7001.class,args);}
}

4.2.4 启动服务测试

访问:http://localhost:7001/,看到如下结果证明访问成功!!!
在这里插入图片描述

4.3 将服务的提供者cloud-provider-payment8001注册到服务中心中

4.3.1 导入依赖

org.springframework.cloudspring-cloud-starter-netflix-eureka-client

4.3.2 编写yml配置文件,配置Eureka配置信息

eureka:client:register-with-eureka: truefetchRegistry: trueservice-url:defaultZone: http://localhost:7001/eureka

4.3.3 在启动类上添加@EnableEurekaClient注解

@SpringBootApplication
@MapperScan("com.tlc.mapper")
@EnableEurekaClient
public class PaymentMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentMain8001.class,args);}
}

4.3.4 启动服务进行测试

在浏览其中访问:http://localhost:7001/,看到如下结果证明配置成功!!!
在这里插入图片描述

4.4 将服务的消费者cloud-consumer-order8000注册到服务中心中

4.4.1 导入依赖

org.springframework.cloudspring-cloud-starter-netflix-eureka-client

4.4.2 编写yml配置文件,配置Eureka配置信息

eureka:client:register-with-eureka: truefetchRegistry: trueservice-url:defaultZone: http://localhost:7001/eureka

4.4.3 在启动类上添加@EnableEurekaClient注解

@SpringBootApplication
@EnableEurekaClient
public class OrderMain8000 {public static void main(String[] args) {SpringApplication.run(OrderMain8000.class,args);}
}

4.3.4 启动服务进行测试

在浏览其中访问:http://localhost:7001/,看到如下结果证明配置成功!!!
在这里插入图片描述

4.5 总服务测试

  1. 先要启动EurekaServer,7001服务
  2. 再要启动服务提供者8001服务和服务消费者80服务
  3. eureka服务器在这里插入图片描述
  4. 测试查询:http://localhost/consumer/payment/get/31
    在这里插入图片描述

5.Ribbon负载均衡服务调用

5.1 概述

5.1.1 简介

  • Ribbon是 Netflix 提供的一个基于HTTP和TCP的客户端负载均衡工具。
  • Ribbon主要有两个功能:
    • 简化远程调用
    • 负载均衡
  • 服务端负载均衡
    • 负载均衡算法在服务端
    • 由负载均衡器维护服务地址列表
  • 客户端负载均衡
    • 负载均衡算法在客户端
    • 客户端维护服务地址列表

5.1.2 可以做什么

1. LB(负载均衡)

  • 简单的说就是将用户的请求平均分配到多个服务器上,从而达到系统的HA(高可用)。
  • 常见的负载均衡有软件Nginx,LVS,硬件F5等。
  • Ribbon的本地负载均衡客户端 VS Nginx服务端负载均衡区别:
    • Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后,由nginx实现转发请求。即负载均衡是由服务器端完成的。
    • Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用。
  • 集中式LB
    • 即在服务的消费方和提供方之间使用独立的LB设施(可以是硬件,如F5,也可以是软件,如Nginx),由该设施负责把访问请求通过某种策略转发至服务的提供方;
  • 进程内LB
    • 将LB逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己再从这些地址中选择出一个合适的服务器。
    • Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取到服务提供方的地址。

2. 总结
Ribbon=负载均衡+RestTemplate调用

5.2 Ribbon负载均衡演示

5.2.1 架构示例图

在这里插入图片描述
Ribbon在工作时分成两步:
第一步,先选择EurekaServer,它优先选择在同一个区域内负载较少的server。
第二步,再根据用户指定的策略,在从server取到的服务注册列表中选择一个地址。其中Ribbon提供了多种策略。比如:轮询、随机和根据响应时间加权。
总结:Ribbon其实就是一个软负载均衡的客户端组件,他可以和其他所需请求的客户端结合使用,和eureka结合只是其中的一个实例。

5.2.2 默认负载均衡策略代码演示

1.创建多个cloud-provider-payment8001服务
①启动PaymentMain8001启动类
②在idea中拷贝2个PaymentMain800服务,PaymentMain8002、PaymentMain8003
在这里插入图片描述
在这里插入图片描述
③启动PaymentMain8002、PaymentMain8003服务
④重新编写cloud-provider-payment8001服务中的PaymentController类

@RestController
public class PaymentController {@Autowiredprivate PaymentService paymentService;@Value("${server.port}")private String serverPort;@GetMapping("/payment/get/{id}")public CommonResult getById(@PathVariable Long id){Payment payment = paymentService.getById(id);return new CommonResult(200,"查询成功----端口"+serverPort,payment);}
}

③重新启动PaymentMain8001、PaymentMain8002、PaymentMain8003服务

2.在cloud-consumer-order8000服务中添加Ribbon负载均衡

org.springframework.cloudspring-cloud-starter-netflix-ribbon

注意:这个不需要手动引用,Eureka客户端自带Ribbon
在这里插入图片描述
3.改写cloud-consumer-order8000服务中OrderController请求方式,通过Eureka服务拿到地址

@RestController
public class OrderController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/order/get/{id}")public CommonResult getById(@PathVariable long id){return restTemplate.getForObject("http://CLOUD-PAYMENT-SERVICE:8001/payment/get/" + id , CommonResult.class);}
}

4.在config.ApplicationContextConfig配置类中的getRestTemple方法上添加 @LoadBalanced注解

@SpringBootConfiguration
public class ApplicationContextConfig {@Bean@LoadBalanced //启用RestTemplate负载均衡的能力,才能通过服务名远程调用public RestTemplate getRestTemplate(){return new RestTemplate();}
}

5.在启动类上添加@RibbonClient注解

@SpringBootApplication
@EnableEurekaClient
public class OrderMain8000 {public static void main(String[] args) {SpringApplication.run(OrderMain8000.class,args);}
}

6.直接启动cloud-consumer-order8000服务测试默认的负载均衡策略
在ribbon中,默认的负载均衡策略是轮询
访问:http://localhost:8000/order/get/31
第一次查询结果:
在这里插入图片描述
第二次查询的结果
在这里插入图片描述
第三次的结果
在这里插入图片描述
以后查询的都依次顺序循环。轮询的顺序与你启动服务的顺序有关。

5.3 负载均衡的策略

5.3.1 IRule:根据特定算法从服务列表中选取一个要访问的服务

配置负载均衡策略的核心组件IRule
在这里插入图片描述
结构体系
在这里插入图片描述
策略介绍:

  1. com.netflix.loadbalancer.RoundRobinRule 轮询,默认策略。
  2. com.netflix.loadbalancer.RandomRule 随机
  3. com.netflix.loadbalancer.RetryRule 先按照RoundRobinRule的策略获取服务,如果获取服务失败则在指定时间内会进行重试,获取可用的服务
  4. WeightedResponseTimeRule 对RoundRobinRule的扩展,响应速度越快的实例选择权重越大,越容易被选择
  5. BestAvailableRule 会先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,然后选择一个并发量最小的服务
  6. AvailabilityFilteringRule 先过滤掉故障实例,再选择并发较小的实例
  7. ZoneAvoidanceRule 默认规则,复合判断server所在区域的性能和server的可用性选择服务器

5.3.1 将上述案例的默认策略改为RandomRule随机策略-编码方式

1.在启动类的上一级目录中创建配置规则包rule,在该包下创建策略
在这里插入图片描述

@Component
public class MyRule  {/*** @Description: 存储一个随机的负载均衡的对象,到Spring容器中* 注意:不能被SpringBoot启动类扫描到,*   一旦被扫描到,该对象会应用到全局(对所有服务的调用都使用随机的访问方式)* @Author: TCL* @Date: 2022/11/25* @Time: 20:32*/@Beanpublic IRule randomRule(){return new RandomRule();}
}

2.在配启动类上配置@RibbonClient,让其扫描到该类将IRule添加到IOC容器中

@SpringBootApplication
@RibbonClient(value = "CLOUD-PAYMENT-SERVICE", configuration = MyRule.class)
public class OrderMain8000 {public static void main(String[] args) {SpringApplication.run(OrderMain8000.class,args);}
}

3.重启服务测试
访问:http://localhost:8000/order/get/31
每次访问结果都是随机的。

5.3.2 配置轮询策略-配置yml方式

在yml中配置方式如下:

user-service: # 生产者服务名称
ribbon:
NFloadBalancerRuleClassName: XxxRule # 负载均衡策略

5.4 负载均衡算法-轮询策略

在这里插入图片描述

5.5 小结

  • ribbon是做负载均衡的,与nginx类似,两者的区别如下:
    • Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后,由nginx实现转发请求。即负载均衡是由服务器端完成的。
    • Ribbon本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用
  • 部署在客户端上部署ribbon的步骤
    • ①导入依赖(如果导入了Eureka依赖,会默认传递一个ribbon依赖)
    • ②编写配置类,在配置类中加载一个RestTemple到Spring容器中。在加载方法上添加@Bean、@LoadLoadBalanced注解
    • ③配置轮询策略:在启动类的上一级目录中创建规则包rule,在该包下创建规则类,并将规则添加到Spring容器中。
    • ④在启动类中添加@RibbonClient注解,加载规则配置类。
    • ⑤在controller中通过restTemplate.getForObject发起请求,访问服务的提供者。请求格式http://应用服务名称:端口号/资源访问路径

6.OpenFeign 声明式服务调用

6.1 概述

6.1.1 什么是Feign

  • Feign是一个声明式的web服务客户端,让编写web服务客户端变得非常容易,只需创建一个接口并在接口上添加注解即可
  • SpringCloud对Feign进行了封装,使其支持了SpringMVC标准注解和HttpMessageConverters。Feign可以与Eureka和Ribbon组合使用以支持负载均衡。

6.1.2 Feign作用

1.能做什么

  • Feign旨在使用编写Java Http客户端变得更容易。
  • 前面在使用Ribbon+RestTemplate时,利用RestTemplate对Http请求的封装处理,形成了一套模板化的调用方法。
  • 但是在实际开发中,由于对服务依赖的调用可能不止一处,往往一个接口会被多处调用,所以通常都会针对每个微服务自行封装一些客户端类来包装这些依赖服务端额调用。所以,Feign在此基础上做了进一步封装,由他来帮助我们定义和实现依赖服务接口的定义。
  • 在Feign的实现下,我们只需创建一个接口并使用注解的方式来配置它(以前是DAO接口上面标注Mapper注解,现在是一个微服务接口上面标注一个Feign注解即可),即可完成对服务提供方的接口绑定,简化了使用Spring Cloud Ribbon时,自动封装服务调用客户端的开发量。

2.Feign集成了 Ribbon
利用Ribbon维护了Payment的服务列表信息,并且通过轮询实现了客户端的负载均衡。而与Ribbon不同的是,通过Feign只需要定义服务绑定接口且以声明式的方法,优雅而简单的实现了服务调用。
3.Feign和OpenFeign两者区别
在这里插入图片描述
4.实现图解
在这里插入图片描述
实现思想:微服务调用接口+@FeignClient

6.2 OpenFeign开发步骤

6.2.1 新建项目cloud-consumer-feign-order8000

新项目中的内容与cloud-consumer-order8000一样,并且openFeign也是自带ribbon

	org.springframework.cloudspring-cloud-starter-netflix-eureka-clientorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-actuatororg.springframework.bootspring-boot-starter-testtestcom.tlccloud-api-commons1.0-SNAPSHOT

6.2.2配置YML文件

server:port: 8000
spring:application:name: cloud-consumer-feign-order8000
eureka:client:register-with-eureka: truefetchRegistry: trueservice-url:defaultZone: http://localhost:7001/eureka

6.2.3 编写启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderFeignMain8000 {public static void main(String[] args) {SpringApplication.run(OrderFeignMain8000.class,args);}
}

6.2.4 编写微服务调用PaymentFeignService接口并新增注解@FeignClient

在service包下创建接口类

@FeignClient(value = "CLOUD-PAYMENT-SERVICE") //声明远程调用的服务名称
public interface PaymentFeignService {/*** @Description: 远程调用方法* @Author: TCL* @Date: 2022/11/25* @Time: 21:31*/@GetMapping("/payment/get/{id}")public CommonResult getById(@PathVariable("id") Long id);
}

6.2.5 编写OrderController,通过微服务调用接口访问远程服务

@RestController
public class OrderController {// 调用远程微服务接口@Resourceprivate PaymentFeignService paymentFeignService;@GetMapping("/order/get/{id}")public CommonResult getById(@PathVariable long id){return paymentFeignService.getById(id);}
}

6.2.6 启动服务测试

访问:http://localhost:8000/order/get/31
发现测试成功。

6.2.7 小结

在这里插入图片描述

6.3 OpenFeign的超时设置

6.3.1 超时演示

1.在服务提供方cloud-provider-payment8001故意写暂停程序

 	/*** @Description: 暂停程序* @Author: TCL* @Date: 2022/11/25* @Time: 21:55*/@GetMapping(value = "/payment/feign/timeout")public String paymentFeignTimeout(){try { TimeUnit.SECONDS.sleep(3); }catch (Exception e) {e.printStackTrace();} //单位秒return "端口:"+serverPort;}

2.在消费端cloud-consumer-feign-order8000的服务调用接口PaymentFeignService中编写远程访问方法

@GetMapping(value = "/payment/feign/timeout")
public String paymentFeignTimeout();

3.在消费端cloud-consumer-feign-order8000的控制方法中调用超时方法

 	@GetMapping("/consumer/payment/feign/timeout")public String paymentFeignTimeout() {return paymentFeignService.paymentFeignTimeout();}

4.启动服务测试
http://localhost:8000/order/payment/feign/timeout
错误页面,OpenFeign默认等待一秒钟,超过后报错
在这里插入图片描述

6.3.2 什么是超时

  • 默认Feign客户端只等待一秒钟,但是,服务端处理需要超过1秒钟,导致Feign客户端不想等待了,直接报错。
  • 为了避免这样的情况,有时候我们需要设置Feign客户端的超时控制,也即Ribbon的超时时间,因为Feign集成了Ribbon进行负载均衡。

6.3.3 yml中配置OpenFeign的超时控制

#设置Feign客户端超时时间(openfeign默认支持ribbon)
ribbon:ConnectTimeout: 3000 #连接等待的最大时间,默认1000毫秒ReadTimeout:  3000 #请求处理等待的最大时间,默认1000毫秒MaxAutoRetries: 1 #同一台实例最大重试次数,不包括首次调用MaxAutoRetriesNextServer: 1 #切换服务的最大次数,不包括第一个服务OkToRetryOnAllOperations: false #是否所有请求都重试,false-仅get请求重试
#hystrix的超时时间
hystrix:command:default:execution:timeout:enabled: trueisolation:thread:timeoutInMilliseconds: 9000

一般情况下 都是 ribbon 的超时时间(<)hystrix的超时时间(因为涉及到ribbon的重试机制)
因为ribbon的重试机制和Feign的重试机制有冲突,所以源码中默认关闭Feign的重试机制,源码如下
在这里插入图片描述
要开启Feign的重试机制如下:(Feign默认重试五次 源码中有)

@Bean
Retryer feignRetryer() {return  new Retryer.Default();
}
  • 根据上面的参数计算重试的次数:
    (MaxAutoRetries+1)*(MaxAutoRetriesNextServer+1) 一共产生4次调用。
  • 如果在重试期间,时间超过了hystrix的超时时间,便会立即执行熔断,fallback。所以要根据上面配置的参数计算hystrix的超时时间,使得在重试期间不能达到hystrix的超时时间,不然重试机制就会没有意义。
  • hystrix超时时间的计算:
    (1 + MaxAutoRetries+MaxAutoRetriesNextServer) * ReadTimeout 即按照以上的配置 hystrix的超时时间应该配置为 (1+1+1)*3=9秒
  • 当ribbon超时后且hystrix没有超时,便会采取重试机制。
    • 当OkToRetryOnAllOperations设置为false时,只会对get请求进行重试。如果设置为true,便会对所有的请求进行重试 ,如果是put或post等写操作,如果服务器接口没做幂等性,会产生不好的结果,所以OkToRetryOnAllOperations慎用。如果不配置ribbon的重试次数,默认会重试一次

注意:
默认情况下,GET方式请求无论是连接异常还是读取异常,都会进行重试 非GET方式请求,只有连接异常时,才会进行重试
配置超时后,再次测试,发现发送请求后并不是立即报错,而是等待设置的超时时间过后报错。

6.4 OpenFeign的日志打印

6.4.1 概述

  • 日志打印:

    • Feign提供了日志打印功能,我们可以通过配置来调整日志级别,从而了解Feign中Http请求的细节。说白了就是对Feign接口的调用情况进行监控和输出。
  • 日志级别

    • NONE:默认的,不显示任何日志
    • BASIC:仅记录请求方法、RUL、响应状态码及执行时间
    • HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息
    • FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据

6.4.2 配置日志bean

在配置config报下创建FeignConfig,将日志级别加载到spring容器中

@Configuration
public class FeignConfig {@Beanpublic Logger.Level feignLoggerLevel(){return Logger.Level.FULL;}
}

6.2.3 在yml配置文件中需要配置开启日志的Feign客户端

#开启OpenFeign日志打印功能
logging:level:com.tlc.service.PaymentFeignService: debug

6.2.4 重启服务器访问测试

访问:http://localhost:8000/order/get/31
在这里插入图片描述

7.Hystrix断路器

7.1 雪崩的概述

复杂分布式体系结构中的应用程序有数十个依赖关系,每一个依赖关系在某些时候将不可避免的失败。
在这里插入图片描述
服务雪崩
多个微服务之间调用的时候,假如微服务A调用微服务B和微服务C,微服务B和微服务C又调用其他的微服务,这就是所谓的"扇出"。
如果扇出的链路上某个微服务的调用响应的时间过长或者不可用,对微服A的调用就会占用越来越多的系统资源,进而引起系统崩溃,所谓的"雪崩效应"。
对于高流量的应用来说,单一的后端依赖可能会导致所有的服务器上的所有资源都在几秒钟内饱和。比失败更糟糕的是,这些应用程序还可能导致服务之间的延迟增加,备份队列,线程和其他系统资源紧张,导致整个系统发生更多的级联故障。这些都表示需要对故障和延迟进行隔离和管理,以便单个依赖关系的失败,不能取消整个应用程序或系统。
所以,通常当你发现一个模块下的某个实例失败后,这时候这个模块依然还会接收流量,然后这个有问题的模块还调用了其他的模块,这样就会发生级联故障,或者叫雪崩。
也可以这样说:当一个服务调用另一个服务由于网络原因或自身原因出现问题,调用者就会等待被调用者的响应 当更多的服务请求到这些资源导致更多的请求等待,发生连锁效应(雪崩效应)

7.2 Hystrix简介

  • Hystrix是一个用于处理分布式系统的延迟容错的开源库,在分布式系统里,许多依赖不可避免的会调用失败,比如超时、异常等。
  • Hystrix能够保证在一个依赖出问题的情况下,不会导致整体服务失败,避免级联故障,以提高分布式系统的弹性。
  • 断路器本身是一种开关装置,当某个服务单元发生故障之后,通过断路器的故障监控(类似熔断保险丝),向调用方返回一个符合预期的、可处理的备选响应(Fallback),而不是长时间的等待或者抛出调用方无法处理的异常,这样就保证了服务调用方的线程不会被长时间、不必要地占用,从而避免了故障在分布式系统中的蔓延,乃至雪崩。
  • Hystrix作用:
    • 服务降级
    • 服务熔断
    • 服务限流
    • 服务隔离
    • 接近实时的监控

7.2.1 服务的降级(Fallback)

  • 服务器忙,请稍候再试,不让客户端等待并立刻返回一个友好提示
  • 哪些情况会触发降级
    • 程序运行异常
    • 超时自动降级
    • 服务熔断触发服务降级
    • 线程池/信号量打满也会导致服务降级
    • 人工降级

7.2.2 服务熔断Breaker

  • 类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示
  • 就是保险丝
    • 服务的降级->进而熔断->恢复调用链路

7.2.3 服务限流

秒杀高并发等操作,严禁一窝蜂的过来拥挤,大家排队,一秒钟N个,有序进行Flowlimit

7.3 高并发测试工具-Jmeter

下载地址:https://archive.apache.org/dist/jmeter/binaries/
在这里插入图片描述
在这里插入图片描述
添加一个并发请求的方式:
①
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7.4 Hystrix案例

7.4.1 构建一个新的服务提供者模块

1.构建模块cloud-provider-hystrix-payment8001,并导入相关依赖

 	org.springframework.cloudspring-cloud-starter-netflix-hystrixorg.springframework.cloudspring-cloud-starter-netflix-eureka-clientcom.tlccloud-api-commons1.0-SNAPSHOTorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-actuatororg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest

2.配置yml文件

server:port: 8001spring:application:name: cloud-hystrix-payment-serviceeureka:client:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://localhost:7001/eureka/

3.编写启动类

@SpringBootApplication
@EnableEurekaClient
public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class,args);}
}

4.编写service接口以及实现类serviceImpl

public interface PaymentService {/*** @Description: 执行成功* @Author: TCL* @Date: 2022/11/25* @Time: 23:10*/public String paymentInfo_OK(Integer id);/*** @Description: 超时方法* @Author: TCL* @Date: 2022/11/25* @Time: 23:10*/public String payment_Timeout(Integer id);
}@Service
public class PaymentServiceImpl implements PaymentService {//成功public String paymentInfo_OK(Integer id){return "线程池:"+Thread.currentThread().getName()+"   paymentInfo_OK,id:  "+id+"\t"+"哈哈哈"  ;}//失败public String payment_Timeout(Integer id){int timeNumber = 3;try { TimeUnit.SECONDS.sleep(timeNumber); }catch (Exception e) {e.printStackTrace();}return "线程池:"+Thread.currentThread().getName()+"   paymentInfo_TimeOut,id:  "+id+"\t"+"呜呜呜"+" 耗时(秒)"+timeNumber;}
}

5.编写controller类

@RestController
@Slf4j
public class PaymentController {@Resourceprivate PaymentService paymentService;@GetMapping("/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentService.paymentInfo_OK(id);log.info("*******result:"+result);return result;}@GetMapping("/payment/hystrix/timeout/{id}")public String paymentInfo_Timeout(@PathVariable("id") Integer id){String result = paymentService.payment_Timeout(id);log.info("*******result:"+result);return result;}
}

6.启动服务测试

  • 启动eureka7001
  • 启动cloud-provider-hystrix-payment8001
  • 访问
    • 访问: http://localhost:8001/payment/hystrix/ok/31
    • 每次调用耗费3秒钟: http://localhost:8001/payment/hystrix/timeout/31
  • 上述module均OK
    以上述为根基平台,从正确->错误->降级熔断->恢复

7.通过Jmeter进行压力测试

  • 压测的过程中再来访问一下微服务
    http://localhost:8001/payment/hystrix/ok/31
    http://localhost:8001/payment/hystrix/timeout/31

  • 演示结果

    • 两个都在自己转圈圈
    • 为什么会被卡死
      • tomcat的默认的工作线程数被打满了,没有多余的线程来分解压力和处理。
  • 压力测试结论

    • 上面还是服务提供者8001自己测试,假如此时外部的消费者80也来访问,那消费者只能干等,最终导致消费端80不满意,服务端8001直接被拖死

7.4.2 构建一个新的服务消费者模块

1.搭建cloud-consumer-feign-hystrix-order8000模块,并导入依赖

 	org.springframework.cloudspring-cloud-starter-netflix-hystrixorg.springframework.cloudspring-cloud-starter-openfeignorg.springframework.cloudspring-cloud-starter-netflix-eureka-clientcom.tlccloud-api-commons1.0-SNAPSHOTorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-actuatororg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest

2.编写yml配置文件

server:port: 8001spring:application:name: cloud-consumer-hystrix-ordereureka:client:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://localhost:7001/eureka/

4.编写启动类

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderHystrixMain8000 {public static void main(String[] args) {SpringApplication.run(OrderHystrixMain8000.class,args);}
}

5.启动服务测试
访问:http://localhost:8000/consumer/payment/hystrix/ok/32

6.高并发测试

  • 2W个线程压8001
  • http://localhost:8000/consumer/payment/hystrix/timeout/32
  • 消费者80,呜呜呜
    • 要么转圈圈等待
    • 要么消费端报超时错误
      报错:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.Sat Nov 26 08:15:59 CST 2022
There was an unexpected error (type=Internal Server Error, status=500).
Read timed out executing GET http://CLOUD-HYSTRIX-PAYMENT-SERVICE/payment/hystrix/timeout/32
feign.RetryableException: Read timed out executing GET http://CLOUD-HYSTRIX-PAYMENT-SERVICE/payment/hystrix/timeout/32at feign.FeignException.errorExecuting(FeignException.java:249)at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:129)at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:89)at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:100)at com.sun.proxy.$Proxy107.paymentInfo_Timeout(Unknown Source)at com.tlc.controller.OrderHystrixController.paymentInfo_Timeout(OrderHystrixController.java:33)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)

7.5 服务的降级

服务的降级可以在消费端配置,也可以在服务提供端配置。首先看在服务端配置值服务降级,这里会使用@HystrixCommand配置降级。该注解作用到方法上。表示该方法因为某种原因,该方法不能正常返回数据,降级使用备用的方法,返回数据。

7.5.1 服务提供端降级处理:cloud-provider-hystrix-payment8001

在服务提供端使用服务降级的场景:

  • 超时
  • 程序出现异常

①在service层中,设置自身调用超时时间的峰值,峰值内可以正常运行,超过了需要有兜底的方法处理,作服务降级fallback。

@Service
public class PaymentServiceImpl implements PaymentService {//成功public String paymentInfo_OK(Integer id) {return "线程池:" + Thread.currentThread().getName() + "   paymentInfo_OK,id:  " + id + "\t" + "哈哈哈";}/*** @Description: 设置超时时间,超过时间自动降级处理,走降级方法。* @Author: TCL* @Date: 2022/11/27* @Time: 8:06*/@HystrixCommand(// 降级方法调用fallbackMethod = "payment_TimeoutHandler" ,commandProperties = {// 设置超时时间,超时5s自动走降级方法@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "5000")})public String payment_Timeout(Integer id) {
//        int timeNumber = 3;int timeNumber = 10; // 模拟超时时间
//        int i = 1/0; // 模拟异常try {TimeUnit.SECONDS.sleep(timeNumber);} catch (Exception e) {e.printStackTrace();}return "线程池:" + Thread.currentThread().getName() + "   paymentInfo_TimeOut,id:  " + id + "\t" + "呜呜呜" + " 耗时(秒)" + timeNumber;}//兜底方法,上面方法出问题,我来处理,返回一个出错信息public String payment_TimeoutHandler(Integer id) {return "服务提供端,线程池:"+Thread.currentThread().getName()+" payment_TimeoutHandler,系统繁忙,请稍后再试\t o(╥﹏╥)o ";}
}

一旦调用服务方法失败并抛出了错误信息后,会自动调用@HystrixCommand标注好的fallbackMethod调用类中的指定方法
②在启动类上添加@EnableHystrix注解

@SpringBootApplication
@EnableHystrix
@EnableEurekaClient
public class PaymentHystrixMain8001 {public static void main(String[] args) {SpringApplication.run(PaymentHystrixMain8001.class,args);}
}

③启动服务,测试程序
访问:http://localhost:8001/payment/hystrix/timeout/31
测试超时和算数异常,都会走兜底方法——服务降级
在这里插入图片描述

7.5.2 服务的消费端设置降级:cloud-consumer-feign-hystrix-order8000

订单微服务,也可以更好的保护自己,自己也依样画葫芦进行客户端降级保护。注意:服务降级可以在服务提供者侧,也可以在服务消费者侧。更多是在服务消费者侧。在消费端中使用服务降级的场景:

  • 程序出现异常
  • 远程调用出现错误
  • 程序连接超时

1.在yml中配置,在远程调用出错时启用Hystrix

feign:hystrix:enabled: true #远程调用出错时,启用hystrix

2.在启动类上添加@EnableHystrix注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
public class OrderHystrixMain8000 {public static void main(String[] args) {SpringApplication.run(OrderHystrixMain8000.class,args);}
}

3.在业务中编写服务降级OrderHystrixController

@RestController
@Slf4j
public class OrderHystrixController {@Resourceprivate PaymentHystrixService paymentHystrixService;@GetMapping("/consumer/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentHystrixService.paymentInfo_OK(id);log.info("*******result:"+result);return result;}@HystrixCommand(fallbackMethod = "payment_TimeoutHandler",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")//超过1.5秒就降级自己})@GetMapping("/consumer/payment/hystrix/timeout/{id}")public String paymentInfo_Timeout(@PathVariable("id") Integer id){
//        int age = 1/0; // 模拟异常,导致降级int timeout = 3000; // 模拟超时,导致降级if (timeout != 0){try {Thread.sleep(timeout);} catch (InterruptedException e) {e.printStackTrace();}}String result = paymentHystrixService.paymentInfo_Timeout(id);log.info("*******result:"+result);return result;}//兜底方法,上面方法出问题,我来处理,返回一个出错信息public String payment_TimeoutHandler(Integer id) {return "服务的消费端8000,对方支付系统繁忙请10秒后再试。或自己运行出错,请检查自己。";}
}

4.启动服务进行测试
访问:http://localhost:8000/consumer/payment/hystrix/timeout/31
在这里插入图片描述
出现的问题

  • 每个业务方法对应一个兜底的方法,代码膨胀,代码耦合
  • 统一通用处理和自定义独立处理的分开

7.5.2 定义统一的降级方法

如果没有特殊的处理方法,就使用默认的降级方法,通过@DefaultProperties(defaultFallback = “”)+@DefaultProperties(defaultFallback = “”)设置统一跳转到统一处理结果页面,通用的和独享的各自分开,避免了代码膨胀,合理减少了代码量。
1.代码实现

@RestController
@Slf4j
@DefaultProperties(defaultFallback = "payment_Global_FallbackMethod")
public class OrderHystrixController {@Resourceprivate PaymentHystrixService paymentHystrixService;@GetMapping("/consumer/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id){String result = paymentHystrixService.paymentInfo_OK(id);log.info("*******result:"+result);return result;}@HystrixCommand(fallbackMethod = "payment_TimeoutHandler",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="1500")//超过1.5秒就降级自己})@GetMapping("/consumer/payment/hystrix/timeout/{id}")public String paymentInfo_Timeout(@PathVariable("id") Integer id){
//        int age = 1/0; // 模拟异常,导致降级int timeout = 3000; // 模拟超时,导致降级if (timeout != 0){try {Thread.sleep(timeout);} catch (InterruptedException e) {e.printStackTrace();}}String result = paymentHystrixService.paymentInfo_Timeout(id);log.info("*******result:"+result);return result;}//兜底方法,上面方法出问题,我来处理,返回一个出错信息public String payment_TimeoutHandler(Integer id) {return "服务的消费端8000,对方支付系统繁忙请10秒后再试。或自己运行出错,请检查自己。";}@GetMapping("/consumer/payment/hystrix/timeout02/{id}")public String paymentInfo_Timeout02(@PathVariable("id") Integer id){
//        int age = 1/0; // 模拟异常,导致降级int timeout = 3000; // 模拟超时,导致降级if (timeout != 0){try {Thread.sleep(timeout);} catch (InterruptedException e) {e.printStackTrace();}}String result = paymentHystrixService.paymentInfo_Timeout(id);log.info("*******result:"+result);return result;}@GetMapping("/consumer/payment/hystrix/timeout03/{id}")public String paymentInfo_Timeout03(@PathVariable("id") Integer id){
//        int age = 1/0; // 模拟异常,导致降级int timeout = 3000; // 模拟超时,导致降级if (timeout != 0){try {Thread.sleep(timeout);} catch (InterruptedException e) {e.printStackTrace();}}String result = paymentHystrixService.paymentInfo_Timeout(id);log.info("*******result:"+result);return result;}//下面是全局fallback方法public String payment_Global_FallbackMethod(){return "Global异常处理信息,请稍后再试,(┬_┬)";}
}

2.重启服务器,测试程序
访问:http://localhost:8000/consumer/payment/hystrix/timeout02/31
http://localhost:8000/consumer/payment/hystrix/timeout03/31
测试结果都是:
在这里插入图片描述
3.出现的问题
服务的降级方法和业务逻辑混一起,会出现耦合。服务降级,客户端去调用服务端,碰上服务端宕机或关闭。可能导致整个服务宕机。解决方式只需要为Feign客户端定义的接口添加一个服务降级处理的实现类即可实现解耦。

7.5.2 实现服务降级业务解耦

未来我们要面对的异常

  • 运行
  • 超时
  • 宕机

再看我们的业务类PaymentController
修改cloud-consumer-feign-hystrix-order8000
根据cloud-consumer-feign-hystrix-order8000已经有的PaymentHystrixService接口,重新新建一个类(PaymentFallbackService)实现该接口,统一为接口里面的方法进行异常处理PaymentFallbackService类实PaymentFeignClientService接口.
1.定义PaymentFallbackService类实PaymentFeignClientService

@Component
public class PaymentFallbackService implements PaymentHystrixService {@Overridepublic String paymentInfo_OK(Integer id) {return "-----PaymentFallbackService fall back-paymentInfo_OK , (┬_┬)";}@Overridepublic String paymentInfo_Timeout(Integer id) {return "-----PaymentFallbackService fall back-paymentInfo_TimeOut , (┬_┬)";}
}

2.配置yml,添加容错机制

feign:hystrix:enabled: true #远程调用出错时,启用hystrix

3.编写PaymentFeignClientService接口

@FeignClient(value = "CLOUD-HYSTRIX-PAYMENT-SERVICE",fallback = PaymentFallbackService.class)
@Component
public interface PaymentHystrixService {@GetMapping("/payment/hystrix/ok/{id}")public String paymentInfo_OK(@PathVariable("id") Integer id);@GetMapping("/payment/hystrix/timeout/{id}")public String paymentInfo_Timeout(@PathVariable("id") Integer id);
}

4.测试程序

7.6 服务的熔断

7.6.1 概述

1.断路器

  • 类比保险丝达到最大服务访问后,直接拒绝访问,拉闸限电,然后调用服务降级的方法并返回友好提示
  • 就是保险丝
  • 服务的降级->进而熔断->恢复调用链路
    2.熔断机制概述
    熔断机制是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时,会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。
    当检测到该节点微服务调用响应正常后,恢复调用链路。
    在SpringCloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状态,当失败的调用到一定阈值,缺省是10秒内20次调用并有50%的失败情况,就会启动熔断机制。熔断机制的注解是@HystrixCommand

7.6.2 代码实现-cloud-provider-hystrix-payment8001项目

1.找到修改PaymentServiceImpl,添加服务熔断机制

  //服务熔断@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),  //是否开启断路器@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),   //当在配置时间窗口内达到此数量,打开断路,默认20个@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),  //断路多久以后开始尝试是否恢复,默认5s@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60"), //出错百分比阈值,当达到此阈值后,开始短路。默认50%})public String paymentCircuitBreaker(Integer id){if (id < 0){throw new RuntimeException("*****id 不能负数");}String serialNumber = IdUtil.simpleUUID();//hutool.cn工具包return Thread.currentThread().getName()+"\t"+"调用成功,流水号:"+serialNumber;}public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){return "id 不能负数,请稍候再试,(┬_┬)/~~     id: " +id;}

2.修改PaymentController,添加方法

    //===服务熔断@GetMapping("/payment/circuit/{id}")public String paymentCircuitBreaker(@PathVariable("id") Integer id){String result = paymentService.paymentCircuitBreaker(id);log.info("*******result:"+result);return result;}

3.启动服务进行测试
自测cloud-provider-hystrix-payment8001
正确: http://localhost:8001/payment/circuit/31
在这里插入图片描述
错误: http://localhost:8001/payment/circuit/-31
在这里插入图片描述
一次正确一次错误trytry
重点测试
多次错误(狂点),然后慢慢正确,发现刚开始不满足条件,就算是正确的访问地址也不能进行访问,需要慢慢的恢复链路

7.6.3 服务熔断原理

1.大神总结
在这里插入图片描述
2.熔断器的类型

  • 熔断打开: 请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间),当打开时长达到所设时钟则进入熔断状态。
  • 熔断关闭: 熔断关闭不会对服务进行熔断
  • 熔断半开: 部分请求根据规则调用当前服务,如果请求成功且符合规则则认为当前服务恢复正常。
  • 关闭熔断 : 当服务一直处于正常状态 能正常调用

3.官网断路器流程图
①官网步骤
②断路器在什么情况下开始起作用

//服务熔断
@HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback",commandProperties = {@HystrixProperty(name = "circuitBreaker.enabled",value = "true"),  //是否开启断路器@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "20"),   //当快照时间窗(默认10秒)内达到此数量才有资格打开断路,默认20个@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "5000"),  //断路多久以后开始尝试是否恢复,默认5s@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"), //出错百分比阈值,当达到此阈值后,开始短路。默认50%
})

涉及到断路器的三个重要参数:快照时间窗、请求总数阈值、错误百分比阈值。
配置属性参考:https://github.com/Netflix/Hystrix/wiki/Configuration

  • 快照时间窗 : 断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10秒。
  • 请求总数阈值: 在快照时间窗内,必须满足请求总数阈值才有资格熔断。默认20,意味着在10秒内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开
  • 错误百分比阈值: 当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设定50%阈值情况下,这时候就会将断路器打开。

③断路器开启或者关闭的条件

  • 当满足一定阀值的时候(默认10秒内超过20个请求次数)
  • 当失败率达到一定的时候(默认10秒内超过50%请求失败)
  • 到达以上阀值,断路器将会开启
  • 当开启的时候,所有请求都不会进行转发
  • 一段时间之后(默认是5秒),这个时候断路器是半开状态,会让其中一个请求进行转发。如果成功,断路器会关闭,若失败,继续开启。重复4和5

④断路器打开之后

  • 再有请求调用的时候,将不会调用主逻辑,而是直接调用降级fallbak。通过断路器,实现了自动地发现错误并将降级逻辑切换为主逻辑,减少响应延迟的效果。
  • 原来的主逻辑要如何恢复呢?
    对于这一个问题,hystrix也为我们实现了自动恢复功能。
    当断路器打开,对主逻辑进行熔断之后,hystrix会启动一个休眠时间窗,在这个时间窗内,降级逻辑是临时的成为主逻辑,当休眠时间窗到期,断路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器将继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器继续进入打开状态,休眠时间窗重新计时。

⑤All配置
在这里插入图片描述

7.6 服务的限流

因为Hystrix停止维护了,所以后面用阿里的Sentinel来实现服务限流

7.7 服务监控hystrixDashboard

7.7.1 服务监控的概述

除了隔离依赖服务的调用以外,Hystrix还提供了准实时的调用监控(Hystrix Dashboard),Hystrix会持续地记录所有通过Hystrix发起的请求的执行信息,并以统计报表和图形的形式展示给用户,包括每秒执行多少请求多少成功,多少失败等。Netflix通过hystrix-metrics-event-stram项目实现了对以上指示的监控。Spring Cloud也提供了Hystrix Dashboard的整合,对监控内容转化成可视化界面。

7.7.2 仪表盘9001

1.新建一个模块:cloud-consumer-hystrix-dashboard9001,并导入依赖

	org.springframework.cloudspring-cloud-starter-netflix-hystrix-dashboardorg.springframework.bootspring-boot-starter-actuatororg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest

2.配置yml文件

server:port: 9001
hystrix:dashboard:proxy-stream-allow-list: "*"

3.创建启动类,添加新的注解@EnableHystrixDashboard

@SpringBootApplication
@EnableHystrixDashboard
public class HystrixDashboardMain9001 {public static void main(String[] args) {SpringApplication.run(HystrixDashboardMain9001.class,args);}
}

4.所有的服务提供者添加新的依赖

org.springframework.bootspring-boot-starter-actuator

5.启动cloud-consumer-hystrix-dashboard9001该微服务后续将监控微服务8001
访问:http://localhost:9001/hystrix
在这里插入图片描述

7.7.3 断路器的演示

1. 修改cloud-provider-hystrix-payment8001,添加一个配置类

@Configuration
public class HystrixConfig {/***此配置是为了服务监控而配置,与服务容错本身无关,springcloud升级后的坑*ServletRegistrationBean因为springboot的默认路径不是"/hystrix.stream",*只要在自己的项目里配置上下面的servlet就可以了*/@Beanpublic ServletRegistrationBean getServlet() {HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);registrationBean.setLoadOnStartup(1);registrationBean.addUrlMappings("/hystrix.stream");registrationBean.setName("HystrixMetricsStreamServlet");return registrationBean;}}

2.测试程序
9001监控8001
http://localhost:8001/hystrix.stream
在这里插入图片描述
测试地址
http://localhost:8001/payment/circuit/31
http://localhost:8001/payment/circuit/-31
上述测试通过
ok
先访问正确地址,再访问错误地址,再正确地址,会发现图示断路器都是慢慢放开的
监控结果,成功
在这里插入图片描述
监控结果,失败
在这里插入图片描述
如何看
7色
在这里插入图片描述
1圈
实心圆:共有两种含义。它通过颜色的变化代表了实例的健康程度,它的健康度从绿色<黄色<橙色<红色递减。
该实心圆除了颜色的变化之外,它的大小也会根据实例的请求流量发生变化,流量越大该实心圆就越大。所以通过该实心圆的展示,就可以在大量的实体中快速的发现故障实例和高压力实例。
1线
曲线:用来记录2分钟内流量的相对变化,可以通过它来观察到流量的上升和下降趋势。
整体图说明
在这里插入图片描述
整体图说明二
在这里插入图片描述
监控多种复杂的服务提提供端
在这里插入图片描述

8.Gateway新一代网关

8.1 概述简介

https://docs.spring.io/spring-cloud-gateway/docs/2.2.6.RELEASE/reference/html/
在这里插入图片描述
Cloud全家桶中有个很重要的组件就是网关,在1.x版本中都是采用的Zuul网关https://github.com/Netflix/zuul/wiki
但在2.x版本中,zuul的升级一直跳票,SpringCloud最后自己研发了一个网关代替Zull,那就是SpringCloud Geteway;
总之一句话:Geteway是原Zuul1.x版的替代
在这里插入图片描述

8.1.1 Gateway概述

  • Gateway是在spring生态系统之上构建的API网关服务,基于Spring5,SpringBoot2和Project Reactor等技术。
  • Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等
  • SpringCloud Gateway是SpringCloud的一个全新项目,基于Spring5.X+SpringBoot2.X和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。
  • 为了提升网关的性能,SpringCloud Gatway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通讯框架Netty。
  • SpringCloud Gateway的目标提供统一的路由方式且基于Filter链的方式提供了网关基本的功能,例如:安全、监控/指标、和限流。
  • 总之Spring Cloud Gateway 使用的Webflux中的reactor-netty响应式编程组件,底层使用了Netty通讯框架
    在这里插入图片描述

8.1.2 网关能干啥

  • 反向代理
  • 鉴权
  • 流量控制
  • 熔断
  • 日志监控
  • 。。。。。。

8.1.3 微服务架构中网关在哪里

在这里插入图片描述

8.2 网关的核心概念

Route(路由): 路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
Predicate(断言): 参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由。
Filter(过滤): 指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。

在这里插入图片描述
Web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。
Predicate就是我们的匹配条件: 而Filter,就是可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了。

8.3 Gateway工作流程

https://docs.spring.io/spring-cloud-gateway/docs/2.2.6.RELEASE/reference/html/
在这里插入图片描述
在这里插入图片描述
客户端向Spring Cloud Gateway发出请求。然后在Gateway Handler Mapping中找到与请求匹配的路由,将其发送到Gateway Web Handler.
Handler再通过指定的过滤器链来将请求发送给我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。
Filter在"pre"类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在"post"类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量控制等有着非常重要的作用
网关的核心逻辑是:路由转发+执行过滤器链

8.4 入门案例

8.4.1 创建新的模块cloud-gateway-gateway9527

创建新的模块cloud-gateway-gateway9527并导入相关依赖

 	org.springframework.cloudspring-cloud-starter-gatewaycom.tlccloud-api-commons1.0-SNAPSHOTorg.springframework.cloudspring-cloud-starter-netflix-hystrixorg.springframework.cloudspring-cloud-starter-netflix-eureka-clientorg.springframework.bootspring-boot-devtoolsruntimetrueorg.projectlomboklomboktrueorg.springframework.bootspring-boot-starter-testtest

8.4.2 配置yml文件

server:port: 9527
spring:application:name: cloud-gatewayeureka:instance:hostname: cloud-gateway-serviceclient:register-with-eureka: truefetch-registry: trueservice-url:defaultZone: http://localhost:7001/eureka

8.4.3 添加启动类

@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {public static void main(String[] args) {SpringApplication.run(GateWayMain9527.class,args);}
}

8.4.4 在yml中配置路由映射

  cloud:gateway:routes:- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名uri: http://localhost:8001   #匹配后提供服务的路由地址predicates:- Path=/payment/get/**   #断言,路径相匹配的进行路由- id: payment_routh2uri: http://localhost:8001predicates:- Path=/payment/lb/**   #断言,路径相匹配的进行路由

在这里插入图片描述

8.4.5 启动程序测试

启动7001:cloud-eureka-server7001
启动8001:cloud-provider-payment8001
启动9527网关:cloud-gateway-gateway9527
访问说明
在这里插入图片描述
添加网关前: http://localhost:8001/payment/get/31
添加网关后: http://localhost:9527/payment/get/31

8.5 通过微服务名实现动态路由

默认情况下Gateway会根据注册中心的服务列表,以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能
一个eureka7001+两个服务提供者8001/8002
修改uri属性:uri: lb://服务名称

 discovery:locator:enabled: true  #开启从注册中心动态创建路由的功能,利用微服务名进行路由

8.5.1 配置yml文件

  cloud:gateway:discovery:locator:enabled: true  #开启从注册中心动态创建路由的功能,利用微服务名进行路由routes:- id: payment_routh #路由的ID,没有固定规则但要求唯一,建议配合服务名
#          uri: http://localhost:8001   #匹配后提供服务的路由地址uri: lb://cloud-payment-servicepredicates:- Path=/payment/get/**   #断言,                
            

相关内容

热门资讯

埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...