IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> springCloud第三课(Hystrix监控平台、DashBoard、Turbine监控、熔断器的状态、微服务网关Zuul) -> 正文阅读

[Java知识库]springCloud第三课(Hystrix监控平台、DashBoard、Turbine监控、熔断器的状态、微服务网关Zuul)

springCloud第三课(Hystrix监控平台、DashBoard、Turbine监控、熔断器的状态、微服务网关Zuul))

上文回顾

上文我们实现了hystrix的熔断降级,我们知道,当请求失败,被拒绝,超时的时候,都会进入到降级方法中。但进入降级方法并不意味着断路器已经被打开。那么如何才能了解断路器中的状态呢?
上文链接
项目源码gitee:gitee地址


一、Hystrix的监控平台

除了实现容错功能,Hystrix还提供了近乎实时的监控,HystrixCommand和HystrixObservableCommand在执行时,会生成执行结果和运行指标。比如每秒的请求数量,成功数量等。这些状态会暴露在Actuator提供的/health端点中。
只需为项目添加 spring-boot-actuator 依赖,重启项目,访问http://localhost:9013/actuator/hystrix.stream ,即可看到实时的监控数据。


搭建Hystrix监控平台

引入jar包

在这里插入图片描述


这个不出意外的话,在之前健康检查时就已经引入了。

重启服务

访问测试一下
在这里插入图片描述
发现根本访问不到,这里其实有个坑,要在yml文件中配置一下如下


配置yml文件

management:
  endpoints:
    web:
      exposure:
        include: '*'

在这里插入图片描述


再次重启服务

再次请求
在这里插入图片描述

发现它一直ping,然后请求一个服务
在这里插入图片描述


搭建Hystrix DashBoard监控

刚刚讨论了Hystrix的监控,但访问/hystrix.stream接口获取的都是以文字形式展示的信息。很难通过文字直观的展示系统的运行状态,所以Hystrix官方还提供了基于图形化的DashBoard(仪表板)监控平台。Hystrix仪表板可以显示每个断路器(被@HystrixCommand注解的方法)的状态。


导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
添加注解

在启动类使用@EnableHystrixDashboard注解激活仪表盘项目

重启服务

重启服务,访问测试
在这里插入图片描述


将之前的访问的连接输入到监控连接里面,如下图
在这里插入图片描述

然后点击按钮进入
在这里插入图片描述


然后访问服务一个测试
在这里插入图片描述


注意:Hystrix仪表板可以显示每个断路器(被@HystrixCommand注解的方法)的状态,未被添加注解的方法无法监控。

二、断路器聚合监控Turbine

在微服务架构体系中,每个服务都需要配置Hystrix DashBoard监控。如果每次只能查看单个实例的监控数据,就需要不断切换监控地址,这显然很不方便。要想看这个系统的Hystrix Dashboard数据就需要用到Hystrix
Turbine。Turbine是一个聚合Hystrix 监控数据的工具,他可以将所有相关微服务的 Hystrix监控数据聚合到一起,方便使用。引入Turbine后,整个监控系统架构如下:
在这里插入图片描述


搭建ebuy-turbine

新建一个springboot项目

过程略

引入jar包

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
<!--turbine监控平台-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-turbine</artifactId>
        </dependency>
        <!--hystrix熔断 (因为监控平台只监控hystrix监控的方法)-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!--监控 文本数据显示-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

配置多个微服务的hystrix监控

在application.yml的配置文件中开启turbine并进行相关配置
在这里插入图片描述

server:
  port: 8031 #端口
spring:
  application:
    name: ebuy-turbine #服务名称
logging:
  level:
    cn.ebuy: DEBUG
eureka:
  client:
    service-url:
      # 集群配置多个,单机配置一个
      defaultZone: http://127.0.0.1:9880/eureka/,http://127.0.0.1:9890/eureka/
  instance:
    prefer-ip-address: true #使用ip地址注册
    lease-expiration-duration-in-seconds: 10 #eureka client 发送心跳给server端,续约到期时间(默认90秒)
    lease-renewal-interval-in-seconds: 5 #发送心跳续约时间间隔
turbine:
  cluster-name-expression: "'default'"
  app-config: ebuy-order

注:# 要监控的微服务列表,多个用,分隔

  • eureka相关配置 : 指定注册中心地址
  • turbine相关配置:指定需要监控的微服务列表
    turbine会自动的从注册中心中获取需要监控的微服务,并聚合所有微服务中的 /hystrix.stream 数据

配置启动类

在这里插入图片描述

  • 作为一个独立的监控项目,需要配置启动类,开启HystrixDashboard监控平台,并激活Turbine

测试

浏览器访问 http://localhost:8031/hystrix 展示HystrixDashboard。
并在url位置输入 http://localhost:8031/turbine.stream(文本数据),http://localhost:8031/hystrix(监控平台),动态根据turbine.stream数据展示多个微服务的监控数据


输入需要监控的微服务地址

在这里插入图片描述
在这里插入图片描述


这样turbine监控微服务平台便是搭建完成了。


三、熔断器的状态

回顾一下

回顾一下上面的情况,当product停止服务时,请求order服务,order由于请求不到product而熔断,如下图

正常未停止product微服务时:
在这里插入图片描述
停止product微服务:
在这里插入图片描述
请求order服务,发生熔断
在这里插入图片描述


上图可以看出监控平台显示服务状态是failure失败,而非Short-Circuited熔断,那这是为什么呢???


熔断器状态

熔断器有三个状态 CLOSEDOPENHALF_OPEN 熔断器默认关闭状态,当触发熔断后状态变更为OPEN ,在等待到指定的时间,Hystrix会放请求检测服务是否开启,这期间熔断器会变为 HALF_OPEN 半开启状态,熔断探测服务可用则继续变更为 CLOSED 关闭熔断器。
熔断器流程图


Closed:关闭状态(断路器关闭),所有请求都正常访问。代理类维护了最近调用失败的次数,如果某次调用失败,则使失败次数加1。如果最近失败次数超过了在给定时间内允许失败的阈值,则代理类切换到断开(Open)状态。此时代理开启了一个超时时钟,当该时钟超过了该时间,则切换到半断开(Half-Open)状态。该超时时间的设定是给了系统一次机会来修正导致调用失败的错误。

Open:打开状态(断路器打开),所有请求都会被降级(熔断兜底)。Hystix会对请求情况计数,当一定时间
内失败请求百分比达到阈值,则触发熔断,断路器会完全关闭。默认失败比例的阈值是50%,请求次数最少不低于20次。

Half Open:半开状态,open状态不是永久的,打开后会进入休眠时间(默认是5S)。随后断路器会自动进入半开状态。此时会释放1次请求通过,若这个请求是健康的,则会关闭断路器,否则继续保持打开,再次进行5秒休眠计时。


测试之前的准备

为了能够精确控制请求的成功或失败,我们在一下代码做调整
在这里插入图片描述
注:这样如果参数是id为816753,一定成功,其它情况都失败。

我们准备两个请求窗口:

  • 成功请求:http://localhost:9013/order/hystrix/816753
  • 不成功请求:http://localhost:9013/order/hystrix/1

熔断器的默认触发阈值是20次请求,不好触发。休眠时间时5秒,时间太短,不易观察,为了测试方便,我们可以通过配置修改熔断策略:

circuitBreaker.requestVolumeThreshold=5
circuitBreaker.sleepWindowInMilliseconds=10000
circuitBreaker.errorThresholdPercentage=50

在这里插入图片描述

  • requestVolumeThreshold:触发熔断的最小请求次数,默认20
  • errorThresholdPercentage:触发熔断的失败请求最小占比,默认50%
  • sleepWindowInMilliseconds:熔断多少秒后去尝试请求
  • 然后重启服务

开始测试

熔断器处于关闭状态

  • 请求正确的服务

在这里插入图片描述

  • 服务仍是关闭状态
  • 请求错误的服务,但是请求次数小于5次
    在这里插入图片描述
  • 服务仍是关闭状态
  • 请求错误的服务,次数大于5次 在这里插入图片描述- 此时熔断器的状态变为开启状态,进入休眠时间(5秒)

熔断器处于打开状态

  • 在熔断器进入开启状态之后不到5s内请求正确的服务 在这里插入图片描述

  • 发现正确的服务也被熔断处理

  • 在熔断器进入开启状态之后不到5s内请求错误的服务 在这里插入图片描述

总结:熔断器处于开启状态下,所有服务都会被降级处理

熔断器处于半开状态

  • 熔断器进入开启状态之后5s,进入半开状态
  • 此时请求正确的服务 在这里插入图片描述- 服务正常返回,并且熔断器状态变为关闭
  • 熔断器进入开启状态之后5s,进入半开状态
  • 此时请求错误的服务 在这里插入图片描述
  • 熔断器状态变为开启状态,进入5秒休眠期

注意:为了方便理解,可以根据上述的熔断器状态流程图来分析


四、微服务网关

在学习完前面的知识后,微服务架构已经初具雏形。但还有一些问题:不同的微服务一般会有不同的网络地址,客户端在访问这些微服务时必须记住几十甚至几百个地址,这对于客户端方来说太复杂也难以维护。如下图:
在这里插入图片描述


如果让客户端直接与各个微服务通讯,可能会有很多问题:

  • 客户端会请求多个不同的服务,需要维护不同的请求地址,增加开发难度
  • 在某些场景下存在跨域请求的问题
  • 加大身份认证的难度,每个微服务需要独立认证

因此,我们需要一个微服务网关,介于客户端与服务器之间的中间层,所有的外部请求都会先经过微服务网关。客户端只需要与网关交互,只知道一个网关地址即可,这样简化了开发还有以下优点:

  • 易于监控
  • 易于认证
  • 减少了客户端与各个微服务之间的交互次数

在这里插入图片描述


服务网关的概念

什么是微服务网关

API网关是一个服务器,是系统对外的唯一入口。API网关封装了系统内部架构,为每个客户端提供一个定制的API。API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。服务端通过API-GW注册和 管理服务。

作用和应用情景

网关具有的职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。当然,最主要的职责还是与“外界联系”。


常见的API网关实现方式

  • Kong

基于Nginx+Lua开发,性能高,稳定,有多个可用的插件(限流、鉴权等等)可以开箱即用。问题:只支持Http协议;二次开发,自由扩展困难;提供管理API,缺乏更易用的管控、配置方式。

  • Zuul

Netflix开源,功能丰富,使用JAVA开发,易于二次开发;需要运行在web容器中,如Tomcat。问题:缺乏管控,无法动态配置;依赖组件较多;处理Http请求依赖的是Web容器,性能不如Nginx

  • Traefik

Go语言开发;轻量易用;提供大多数的功能:服务路由,负载均衡等等;提供WebUI 问题:二进制文件部署,二次开发难度大;UI更多的是监控,缺乏配置、管理能力;

  • Spring Cloud Gateway

SpringCloud提供的网关服务

  • Nginx+lua实现

使用Nginx的反向代理和负载均衡可实现对api服务器的负载均衡及高可用 问题:自注册的问题和网关本身的扩展性


基于Nginx的网关实现

Nginx介绍

在这里插入图片描述


正向/反向代理

正向代理

在这里插入图片描述

正向代理,“它代理的是客户端,代客户端发出请求”,是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

反向代理

在这里插入图片描述

多个客户端给服务器发送的请求,Nginx服务器接收到之后,按照一定的规则分发给了后端的业务处理服务器进行处理了。此时~请求的来源也就是客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,Nginx扮演的就是一个反向代理角色。客户端是无感知代理的存在的,反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。反向代理,“它代理的是服务端,代服务端接收请求”,主要用于服务器集群分布式部署的情况下,反向代理隐 藏了服务器的信息,如果只是单纯的需要一个最基础的具备转发功能的网关,那么使用Ngnix是一个不错的选择


微服务网关Zuul

Zuul简介

ZUUL是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,Zuul组件的核心是一系列的过滤器,这些过滤器可以完成以下功能:

  • 动态路由:动态将请求路由到不同后端集群
  • 压力测试:逐渐增加指向集群的流量,以了解性能
  • 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请求
  • 静态响应处理:边缘位置进行响应,避免转发到内部集群
  • 身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求。Spring Cloud对Zuul进行
    了整合和增强。

搭建Zuul网关服务器

创建工程导入依赖
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        <!--zuul网关的jar-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

编写启动类

在这里插入图片描述

  • @EnableZuulProxy : 通过 @EnableZuulProxy 注解开启Zuul网管功能

编写配置
  • 创建配置文件 application.yml ,并添加相应配置
server:
  port: 9090 #端口
spring:
  application:
    name:  ebuy-zuul #服务名称
logging:
  level:
    cn.ebuy: DEBUG

Zuul中的路由转发

最直观的理解:“路由”是指根据请求URL,将请求分配到对应的处理程序。在微服务体系中,Zuul负责接收所有的请求。根据不同的URL匹配规则,将不同的请求转发到不同的微服务处理。

对应的配置
zuul:
  routes:
    ebuy-order: #只是个在这个配置文件中的节点名字这里是路由id,随意写
      path: /ebuy-order/** # 映射路径 
      url: http://127.0.0.1:9013/ # 映射路径对应的实际url地址
      sensitive-Headers: #默认zuul会屏蔽cookie,cookie不会传到下游服务,这里设置为空则取
消默认的黑名单,如果设置了具体的头信息则不会传到下游服务

    ebuy-product:
      path: /ebuy-product/**
      url: http://127.0.0.1:9015/
      sensitive-Headers:

例子: path: /ebuy-order001/** # 映射路径
地址栏访问 :http://localhost:9090/ebuy-order001/order/hystrix/816753

启动测试
  • 启动服务 在这里插入图片描述

  • 访问测试 在这里插入图片描述


面向服务的路由

微服务一般是由几十、上百个服务组成,对于一个URL请求,最终会确认一个服务实例进行处理。如果对每个服务实例手动指定一个唯一访问地址,然后根据URL去手动实现请求匹配,这样做显然就不合理

Zuul支持与Eureka整合开发,根据ServiceID自动的从注册中心中获取服务地址并转发请求,这样做的好处不仅可以通过单个端点来访问应用的所有服务,而且在添加或移除服务实例的时候不用修改Zuul的路由配置。

添加Eureka客户端依赖

改造上述的项目
添加依赖

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
添加Eureka客户端发现功能

在这里插入图片描述


添加Eureka配置,获取服务信息
  • Eureka配置
# Eureka配置
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:9890/eureka/,http://127.0.0.1:9880/eureka
      lease-expiration-duration-in-seconds: 10 #eureka client发送心跳给server端后,续约到期时间(默认90秒)
      lease-renewal-interval-in-seconds: 5 #发送心跳续约时间间隔
      registry-fetch-interval-seconds: 5 # 获取服务列表的周期:5s
  instance:
    prefer-ip-address: true   # 使用ip地址註冊
  • zuul面向服务的路由配置

因为已经有了Eureka客户端,我们可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问,而且Zuul已经集成了Ribbon的负载均衡功能。

zuul:
  routes:
    ebuy-order:
      path: /ebuy-order/**
      serviceId: ebuy-order #配置转发的微服务名称
    ebuy-product:
      path: /ebuy-product/**
      serviceId: ebuy-product #配置转发的微服务名称

注:serviceId: 指定需要转发的微服务实例名称

访问测试
  • 重启服务,开始测试 在这里插入图片描述
    在这里插入图片描述
  • 可以看出zuul已经实现了负载均衡

简化的路由配置

在刚才的配置中,我们的规则是这样的:

  • zuul.routes.<route>.path=/xxx/** : 来指定映射路径。 <route> 是自定义的路由名。
  • zuul.routes.<route>.serviceId=/product-service :来指定服务名。
    而大多数情况下,我们的 <route> 路由名称往往和服务名会写成一样的。因此Zuul就提供了一种简化的配置语法: zuul.routes.<serviceId>=<path>
    上面的配置可以简化为一条:
zuul:
  routes:
    ebuy-product: /ebuy-product/** #第一个ebuy-product是指服务名,第二个是地址栏要输入的映射路径
    ebuy-order: /ebuy-order/**

重启服务测试

不再截图展示

发现问题

  • 模拟高并发情况下的问题 在这里插入图片描述
  • 重启,然后再次使用zuul的路径访问服务 在这里插入图片描述
  • 发现提示com.netflix.zuul.exception.ZuulException: Hystrix Readed time out

回顾之前我们配置,可以给zuul配置如下(注意是ebuy-zuul项目)

ebuy-product:
  ribbon:
    #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    ConnectTimeout: 2500 # Ribbon的连接超时时间(创建连接时间:毫秒)
    ReadTimeout: 5000 # Ribbon的数据读取超时时间 (得到数据的时间)
    OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
    MaxAutoRetries: 1 # 对当前实例的重试次数 (1表示不重试自己)
ebuy-order:
  ribbon:
    #NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
    ConnectTimeout: 2500 # Ribbon的连接超时时间(创建连接时间:毫秒)
    ReadTimeout: 5000 # Ribbon的数据读取超时时间 (得到数据的时间)
    OkToRetryOnAllOperations: true # 是否对所有操作都进行重试
    MaxAutoRetriesNextServer: 1 # 切换实例的重试次数
    MaxAutoRetries: 1 # 对当前实例的重试次数 (1表示不重试自己)

在这里插入图片描述

  • 然后重启配置
  • 重新访问测试 在这里插入图片描述
  • 问题解决(可以把ebuy-product的模拟所写的线程休眠注释掉了)

默认的路由规则

在使用Zuul的过程中,上面讲述的规则已经大大的简化了配置项。但是当服务较多时,配置也是比较繁琐的。因此Zuul就指定了默认的路由规则:

  • 默认情况下,一切服务的映射路径就是服务名本身。
    • 例如服务名为: ebuy-product ,则默认的映射路径就是: /ebuy-product/**

那么到底是什么意思呢?
意思就是说上述的路由配置是完全不需要的(当然前提是你的访问路径想要和应用名同名)

  • 注释掉路由相关的配置 在这里插入图片描述
  • 访问服务测试 在这里插入图片描述
  • 访问完全没问题

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-09-22 14:31:58  更:2021-09-22 14:34:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:29:47-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码