Spring Cloud Netflix的学习

Updated on with 0 views and 0 comments

Spring Cloud Netflix的学习

NetFlix 网飞的SpringCloud、服务发现组件 Eureka

系统架构演变

  • 集中式架构

当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架**(ORM)是影响项目开发的关键**。

image-20210903153545383

存在的问题:

· 代码耦合,开发维护困难

· 无法针对不同模块进行针对性优化

· 无法水平扩展

· 单点容错率低,并发能力差

  • 垂直拆分

当访问量逐渐增大,单一应用无法满足需求,此时为了应对更高的并发和业务需求,我们根据业务功能对系统进行拆分:

image-20210903153819117

优点:

· 系统拆分实现了流量分担,解决了并发问题

· 可以针对不同模块进行优化

· 方便水平扩展,负载均衡,容错率提高

缺点:

· 系统间相互独立,会有很多重复开发工作,影响开发效率

  • 分布式服务

当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,
使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的分布式调用是关键。

image-20210903154019137

优点:

· 将基础服务进行了抽取,系统间相互调用,提高了代码复用和开发效率

缺点:

· 系统间耦合度变高,调用关系错综复杂,难以维护

  • 服务治理SOA

当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)是关键

image-20210903154822967

Dubbo Service的远程调用

Zookeeper 实现 注册中心

以前出现了什么问题?

· 服务越来越多,需要管理每个服务的地址

· 调用关系错综复杂,难以理清依赖关系

· 服务过多,服务状态难以管理,无法根据服务情况动态管理

服务治理要做什么?

· 服务注册中心,实现服务自动注册和发现,无需人为记录服务地址

· 服务自动订阅,服务列表自动推送,服务调用透明化,无需关心依赖关系

· 动态监控服务状态监控报告,人为控制服务状态

缺点:

· 服务间会有依赖关系,一旦某个环节出错会影响较大

· 服务关系复杂,运维、测试部署困难,不符合DevOps(开发部署等一体化)思想

缺点:

服务间依赖关系、某个环节出错影响较大

服务关系复杂、运维测试部署难度大、不符合服务一体化Devops

  • 微服务

目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一件事。

  • 微服务与微服务架构

微服务是一种架构模式或者一种架构风格,提倡将单一应用程序划分成一组小的服务独立部署,服务之间相互配合、相互协调,每个服务运行于自己的进程中。

服务与服务间采用轻量级通讯,如HTTP的RESTful API等

避免统一的、集中式的服务管理机制 去中心化

  • 微服务的优缺点

优点

  • 每个服务足够内聚,足够小,比较容易聚焦

  • 开发简单且效率高,一个服务只做一件事情

  • 开发团队小,一般2-5人足以(当然按实际为准)

  • 微服务是松耦合的,无论开发还是部署都可以独立完成

  • 微服务能用不同的语言开发 go语言,javascript==> node.js --> vue.js

    1 ~ 3年的沉淀期 ==> java范围,扩展 go语言,javascript ==> node.js

    4 ~ 6 年发展期 ==> 管理方向,把控到整个软件的开发周期 ==> 项目经理,项目总监

    技术方向,大牛 ==> 架构师 ==> CTO
    

    7 ~ 9 年瓶颈期 ==> 管理层,创业

  • 易于和第三方集成,微服务允许容易且灵活的自动集成部署(持续集成工具有Jenkins,Hudson,bamboo等)

  • 微服务易于被开发人员理解,修改和维护,这样可以使小团队更加关注自己的工作成果,而无需一定要通过合作才能体现价值

  • 微服务允许你融合最新的技术

  • 微服务只是业务逻辑的代码,不会和HTML,CSS或其他界面组件融合。

  • 每个微服务都可以有自己的存储能力,数据库可自有也可以统一,十分灵活。

缺点

  • 开发人员要处理分布式系统的复杂性
  • 多服务运维难度,随着服务的增加,运维的压力也会增大
  • 依赖系统部署
  • 服务间通讯的成本(时间和经济)
  • 数据的一致性
  • 系统集成测试
  • 性能监控的难度 (Nacos、Sentinel、Sleuth、zipkin)
发展方向

1-3 年沉淀期:Java 范围、扩展:**go 语言**、nodejs、python

4-6 年发展期:明显划分方向。

管理方向 ==>把控整个软件的开发周期 分配任务 项目经理、项目总监

35 岁之前进入管理层 或者 自我创业 就不会出局、对于软件行业、软件成熟的架构有更深入的了解

技术方向 ==> 大牛、架构师、CTO

7-9 年瓶颈期:管理层、创业

远程调用方式对比

微服务还是SOA

RPC:远程过程调用、RMI 远程方法调用、webservice、dubbo

Http:基于TCP、缺点消息封装臃肿(消息头、消息体)、Rest 风格

RPC 思考

概念解释:

RPC,即 Remote Procedure Call(远程过程调用),是一个计算机通信协议。 该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。

说得通俗一点就是:A计算机提供一个服务,B计算机可以像调用本地服务那样调用A计算机的服务。

作用体现:

通过上面的概念,我们可以知道,实现RPC主要是做到两点:

  1. 实现远程调用其他计算机的服务
  2. 像调用本地服务一样调用远程服务

问题思考:

SpringBoot 一站式开发 一般情况下 Service 和 Controller 不分开

Dubbo 更适用于 SSM 的开发、Service 注册在 Dubbo、Controller 远程调用 注册的 service、xml 文件 服务注册

网络通信:底层TCP 的协议

RPC 对调用的过程封装

动态代理方式、隐藏实现的细节

image-20210903161738133

封装接口

序列化工具 JDK-serializer 序列化与反序列化

序列化为字节网络传输

Http 思考

概念解释

超文本协议:应用层的协议 。规定了网络传输的请求格式、响应格式、资源定位和操作的方式等。但是底层采用什么网络传输协议,并没有规定,不过现在都是采用TCP协议作为底层传输协议。

http和rpc差别:

  • RPC 没有定义数据传输格式、Http 定义了资源定位的路径(RequestMapping)、RPC并不需要(RPC 需定义生产者消费者需要扫描的包)
  • 最终要的一点:RPC 需要远程调用 API层面的封装、Http 协议没有这样要求、需要自己实现请求、响应

优缺点:

  • RPC 方式更加透明、对用户方便。Http 方式更灵活、没有规定 API 和语言,跨语言、跨平台(PHP、JavaScript等ok)
  • RPC方式需要在 API 层面进行封装 限制了开发语言环境

浏览器 就是 Http 协议的实现 请求和响应

如何选择

  • 速度来看:RPC 速度快、 通用定义的http1.1协议的tcp报文包含太多无用的信息(可采用gzip 压缩)
  • 难度来看:RPC实现较为复杂,http相对比较简单
  • 灵活性来看:http 更灵活 不关心细节实现,跨平台、跨语言。

对效率要求更高、并且开发过程使用统一的技术栈、RPC

需要更加灵活、跨语言、跨平台、http 更合适

微服务 强调 独立、自制、灵活 基于 Http 的 Rest 风格服务

RPC 方式限制较多

SpringCloud

Spring 的三大模块:SpringBoot (构建)、SpringCloud(协调)、SpringCloudDataFlow(连接)

Spring Cloud 是什么

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

Spring Cloud项目的官方网址:https://spring.io/projects/spring-cloud

SpringCloud和SpringBoot的关系

Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务,Spring Cloud是一个基于Spring Boot实现的云应用开发工具;

Spring Boot专注于快速方便开发单个微服务个体,Spring Cloud关注全局的服务治理框架,它将SpringBoot开发的一个个微服务整合并管理起来,为各个服务之间提供 服务发现、负载均衡、断路器、路由、配置管理、微代理,消息总线、全局锁、分布式会话等集成服务;

Spring Boot使用了默认大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置,Spring Cloud很大的一部分是基于Spring Boot来实现,可以不基于Spring Boot吗?不可以。

Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。

Spring Boot 使用 Hoxton 版本

Spring Cloud Netflix 主要框架

服务发现 Netflix Eureka

服务调用 Netflix Feign

熔断器 Netflix Hystrix

服务网关 Netflix Zuul(舍弃) SpringCloud Gateway(推荐)(支持异步、匹配规则更灵活、依赖SpringCloud)

分布式配置 SpringCloudConfg

Eureka

相较于 Zookeeper的 Dubbo 和 Nacos,无需搭建注册中心,注册中心作为微服务存在

Eureka 是Spring Cloud Netflix 微服务套件中的一部分, 它基于Netflix Eureka 做了二次封装, 主要负责完成微服务架构中的服务治理功能。我们只需通过简单引入依赖和注解配置就能让Spring Boot 构建的微服务应用轻松地与Eureka 服务治理体系进行整合。

Eureka包含两个组件:Eureka Server和Eureka Client。

Eureka Server提供服务注册服务。

Eureka Client是一个java客户端,用来简化与Eureka Server的交互、客户端同时也就是一个内置的、使用轮询(round-robin)负载算法的负载均衡器。

image-20210903100339819

Eureka 服务器做集群 防止宕机

Eurake注册中心的搭建

新建父工程 eureka-demo

依赖

SpringBoot 版本2.3.9.RELEASE 不使用阿里系、依赖管理只需要一个 SpringCloud Hoxton

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.bh</groupId>
    <artifactId>eureke-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>eureke-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <packaging>pom</packaging>
  
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

一个注册中心的情况下

定义子模块 EurekaServer01

依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>	
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>

配置文件

server:
  port: 8888
spring:
  application:
    name: EurekaServer01
eureka:
  client:
    # 当前的注册中心不做为客户端注册到其他的注册中心中(只有一个注册中心)
    register-with-eureka: false
    # 不从其他的注册中心中获取数据
    fetch-registry: false
    # 注册中心 注册地址
    service-url:
      defaultZone: http://localhost:8888/erureka

主启动类

@SpringBootApplication
@EnableEurekaServer
public class EurekaService01App {

    public static void main(String[] args) {
        SpringApplication.run(EurekaService01App.class);
    }
}

二个注册中心的情况下

新增 子 EurekaServer02

修改配置

注册中心的地址必须指向其他的注册中心、不能是自己

允许注册到其他注册中心 和从其他注册中心获取数据 这就构成了注册同步CAP 的 C 一致性

server:
  port: 9999
spring:
  application:
    name: EurekaServer02
eureka:
  client:
    # 当前的注册中心做为客户端注册到其他的注册中心中(只有一个注册中心)
    register-with-eureka: true
    # 从其他的注册中心中获取数据
    fetch-registry: true
    # 注册中心 注册地址
    service-url:
      defaultZone: http://localhost:8888/eureka

效果

image-20210903200059169

提供者和消费者的搭建

新建提供者模块 EurekaProvider

新增依赖

<dependencies>
    <!-- web-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- client-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

配置

实现了 注册一致性 defaultZone 写一个也可以

server:
  port: 9001
spring:
  application:
    name: provider
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka,http://localhost:9999/erueka

主启动类

@SpringBootApplication
//@EnableDiscoveryClient // 开启 Spring Cloud 所有客户端
@EnableEurekaClient // 开启 Eureka 客户端
public class ProviderApp {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApp.class);
    }
}

Controller

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String sayHello() {
        return "Hello Provider!";
    }
}

注解

@EnableDiscoveryClient 开启 SpringCLoud 所有客户端

@EnableEurekaClient 只开启 Euerka 客户端

新建消费者模块 EurekaConsumer

需要的依赖、配置和提供者大体相似 就不记录了

Controller

@RestController
public class HiController {

    @RequestMapping("/hi")
    public String sayHi() {
        return "hi";
    }
}

服务剔除与自我保护机制

1.服务剔除

注册到eureka的服务可能由于内存溢出或网络故障等原因使得服务不能正常的工作,而服务注册中心并未收到“服务下线”的请求。服务注册中心在启动时会创建一个定时任务,默认每隔一段时间(默认为60秒)将当前清单中超时(默认为90秒)没有续约的服务剔除,这个操作被称为失效剔除。

2.服务保护

我们关停一个服务,很可能会在Eureka面板看到一条警告:

这是触发了Eureka的自我保护机制。当服务未按时进行心跳续约时,Eureka会统计服务实例最近15分钟心跳续约的比例是否低于了85%。

在生产环境下,因为网络延迟等原因,心跳失败实例的比例很有可能超标,但是此时就把服务剔除列表并不妥当,因为服务可能没有宕机。

Eureka在这段时间内不会剔除任何服务实例,直到网络恢复正常。生产环境下这很有效,保证了大多数服务依然可用,不过也有可能获取到失败的服务实例,因此服务调用者必须做好服务的失败容错。

可以通过下面的配置来关停自我保护:

90s 剔除、低于85 保护

eureka:
  server:
    # 关闭自我保护机制
    enable-self-preservation: false

image-20210903205253727

有三种远程调用的实现方式:基于LoadBalanceClient、Ribbon、Feign

基于LoadBalance服务调用

增加一个基础类 基础包

EurekaCommon

依赖 lombok

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

实体类 UserEntity

@Data
public class UserEntity implements Serializable {
    private long id;
    private String name;
    private Integer age;
}

service

```java
public interface UserService {
    List<UserEntity> findAll();
}

服务提供者、消费者 添加依赖

<dependency>
    <groupId>com.bh</groupId>
    <artifactId>EurekaCommon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

编写提供者的数据

UserServiceImpl

@Service
public class UserServiceImpl implements UserService {
    @Override
    public List<UserEntity> findAll() {


        List<UserEntity> list = new ArrayList<>();
        list.add(new UserEntity(20210903L,"xx",12));
        list.add(new UserEntity(20210904L,"xx",18));
        list.add(new UserEntity(20210905L,"xx",19));
        return list;
    }
}

Controller

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/findAll")
    public List<UserEntity> findAll() {
        return userService.findAll();
    }
}

编写 消费者

主启动类 添加 Bean

@Bean
public RestTemplate restTemplate() {
    return new RestTemplate();
}

UserServiceImpl

@Service
public class UserServiceImpl implements com.offcn.service.UserService {

    // 远程调用
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    /*
    获取访问路径
     */
    public String getServiceUrl() {
        ServiceInstance provider = loadBalancerClient.choose("PROVIDER");
        String ip = provider.getHost();
        int port = provider.getPort();
        String url = "http://" + ip +":" + port;
        return url;

    }

    @Override
    public List<UserEntity> findAll() {
        String url = getServiceUrl();
        List<UserEntity> list = restTemplate.getForObject(url + "/user/findAll", List.class);
        return list;
    }
}

Controller

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/showUser")
    public List<UserEntity> showUser() {

        return userService.findAll();
    }
}

实现远程调用

image-20210903221237696

默认是轮询形式的负载均衡

image-20210903221439906

基于 Ribbon 的远程调用

依赖

<!-- web-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- client-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<!-- ribbon-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
</dependencies>

配置

server:
  port: 9102
spring:
  application:
    name: consumerByRibbon
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8888/eureka

服务提供者

// 获取 端口地址
@Value("${server.port}")
private Integer port;

入口地方创建对象加Bean、加注解LoadBalance(负载均衡)

new RestTemplate

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
}

路径 自定义 "http://PROVIDER" 实现负载均衡

@LoadBalanced 对应 PROVIDER、loclahost 会出错

负载均衡规则配置

1.规则分类

默认情况下Ribbon的负载均衡策略是轮询,Ribbon常用的负载均衡规则:

1、简单轮询策略(RoundRobinRule) 默认

以轮询的方式依次将请求调度不同的服务器

2、随机策略 (RandomRule)

随机选择状态为UP的Server

3、加权响应时间策略 (WeightedResponseTimeRule)

根据响应时间分配一个weight,响应时间越长,weight越小,被选中的可能性越低。

4、区域权重策略(ZoneAwareRule)

综合判断server所在区域的性能和server的可用性选择server

5、最低并发策略(BestAvailableRule)

逐个查看server,选择一个并发连接最低的server

6、重试策略(RetryRule)

对选定的负载均衡策略机上重试机制

7、可用过滤策略(AvailabilityFilteringRule)

过滤掉一直失败并被标记为circuit tripped的server

8、ResponseTimeWeightedRule

已废弃,作用同WeightedResponseTimeRule

2.规则配置

yml文件配置指定服务的负载均衡策略

# com.netflix.loadbalancer.RandomRule #配置规则 随机

# com.netflix.loadbalancer.RoundRobinRule #配置规则 轮询

# com.netflix.loadbalancer.RetryRule #配置规则 重试

# com.netflix.loadbalancer.WeightedResponseTimeRule #配置规则 响应时间权重

# com.netflix.loadbalancer.BestAvailableRule #配置规则 最空闲连接策略

针对每个服务来在消费端如UserWeb02的application.yml中配置负载均衡规则

PROVIDER: #服务名称
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule

重试机制

1.重试机制理解

当我们选择轮询负载均衡策略的时候,如果一个服务停掉,因为服务剔除的延迟,消费者并不会立即得到最新的服务列表,此时再次访问你会得到错误提示:

Spring Cloud 整合了Spring Retry 来增强RestTemplate的重试能力,当一次服务调用失败后,不会立即抛出一次,而是再次重试另一个服务。

2.重试机制实现

1.修改配置文件application.yml

spring:
  #开启Spring Cloud的重试功能
  cloud:
    loadbalancer:
      retry:
        enabled: true
PROVIDER:
  ribbon:
    #配置指定服务的负载均衡策略
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule
    # 是否对所有操作都进行重试
    OkToRetryOnAllOperations: true
    ConnectTimeout: 250 # Ribbon的连接超时时间
    ReadTimeout: 1000 # Ribbon的数据读取超时时间
    # 切换实例的重试次数
    MaxAutoRetriesNextServer: 1
    # 对当前实例的重试次数
    MaxAutoRetries: 1

注意:使用重试,要设置负载均衡策略为轮询com.netflix.loadbalancer.RoundRobinRule

2.修改pom文件引入依赖

<dependency>
          <groupId>org.springframework.retry</groupId>
          <artifactId>spring-retry</artifactId>      
 </dependency>

3.修改主启动类方式

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    // 单位毫秒
    requestFactory.setReadTimeout(200);
    requestFactory.setConnectTimeout(200);
    return new RestTemplate(requestFactory);
}

4.测试效果

重启项目UserWeb02,

访问地址:http://127.0.0.1:9002/

不断刷新页面,可以看到用户服务显示内容在变化,负载均衡效果已经生效,到此ribbon消费者成功

如图:

关闭生产者项目ProviderService002

再次访问http://127.0.0.1:9002/

重试机制生效不会再产生刚才的调用错误。

注意:重试过于频繁后台也会出现异常,但是页面不会再次出现错误。

基于 Feign 的远程调用

Feign是一个声明式的web服务客户端,它使编写web服务客户端变得更加容易。创建一个接口并添加一个Fegin的注解@FeignClient,就可以通过该接口调用生产者提供的服务。Spring Cloud对Feign进行了增强,使得Feign支持了Spring MVC注解

两点:1、Feign采用的是接口加注解的声明式服务调用;

2、Fegin整合Ribbon及Eureka,支持负载均衡

依赖

spring-boot-starter-web
spring-cloud-starter-netflix-eureka-client
spring-cloud-starter-openfeign

主启动类 Feign

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.offcn.consumer.feign")

接口+注解

@FeignClient(value = "PROVIDER")
public interface ProviderService {
  
    @GetMapping("/user/findAll")
    public Map<String,Object> findAll();
}

使用 AutoWired 注解

熔断器 Netflix Hystrix

a、b、c 级联调用调用出错、防止调用失败,返回fallback数据。

熔断依赖

<!-- 熔断依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

开启熔断器

@EnableCircuitBreaker

回调降级方法

Ribbon 方式

@HystrixCommand(fallbackMethod = "findAllFallback")

降级服务方法写同一个类里面

image-20210906093442684

Feign 的方式

@FeignClient(value = "PROVIDER",fallback = ProviderServiceFallback.class)

创建回调降级方法的实现类继承远程调用类

@Component
public class ProviderServiceFallback implements ProviderService {
    @Override
    public Map<String, Object> findAll() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("List",new ArrayList<>());
        map.put("msg","feign 远程调用失败");
        return map;
    }
}

配置文件开启熔断器

feign:
  hystrix:
    enable: true

Hystrix Dashborad

断路器是根据一段时间窗内的请求情况来判断并操作断路器的打开和关闭状态的。而这些请求情况的指标信息都是HystrixCommand和HystrixObservableCommand实例在执行过程中记录的重要度量信息,它们除了Hystrix断路器实现中使用之外,对于系统运维也有非常大的帮助。这些指标信息会以“滚动时间窗”与“桶”结合的方式进行汇总,并在内存中驻留一段时间,以供内部或外部进行查询使用,Hystrix Dashboard就是这些指标内容的消费者之一。

监测组件

 <dependencies>
    <!-- 熔断监控监测组件-->
    <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>
  </dependencies>

主启动类加入注解

@EnableHystricDashboard

豪猪Logo

image-20210906205459754

修改 Feign 的主启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.offcn.consumer.feign")
@EnableCircuitBreaker
@EnableHystrixDashboard
public class ConsumerFeignApp {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerFeignApp.class);
    }

    @Bean
    public ServletRegistrationBean getServlet(){
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);  //系统启动时加载顺序 越小越优先
        registrationBean.addUrlMappings("/hystrix.stream");//路径
        registrationBean.setName("HystrixMetricsStreamServlet"); // 访问名字
        return registrationBean;
    }
}

image-20210906211156613


标题:Spring Cloud Netflix的学习
作者:HB2Ocean
地址:http://future-hb.top:8080/articles/2021/09/05/1630828638363.html