SpringCloud Netflix

一、微服务架构

1.1 微服务架构概念

微服务架构,是一种架构概念,就是将一个单体应用中的每个功能分解到各个离散的服务中,以实现对单体应用的解耦,并提供更加灵活的服务支持

1.2 微服务架构优点

  • 解决了单体项目的复杂性问题
  • 每个服务都可以由单独的团队进行开发
  • 每个服务都可以使用单独的技术栈进行开发
  • 每个服务都是独立的进行部署和维护
  • 每个服务都可以独立进行扩展

1.3 微服务架构缺点

  • 微服务架构本身就是一个缺点:如何把握”微“的粒度
  • 微服务架构是一个分布式系统,虽然单个服务变得简单了,但是服务之间存在互相调用,整个服务架构的系统变得更复杂了
  • 微服务架构需要依赖分布式数据库架构
  • 微服务的单元测试及调用变得比单体更为复杂
  • 部署基于微服务架构的应用程序变得非常复杂
  • 进行微服务架构的应用程序开发的技术成本变得更高

二、微服务架构开发需要解决的问题

在微服务架构开发的系统中必然存在很多个服务,服务之间需要相互感知对方的存在,需要进行服务间的调用,该如何实现呢?

1.如此多的服务间如何互相发现?

2.服务之间如何通信?

3.服务出现故障如何处理?

4.前端访问多个不同的服务时,该如何统一访问路径?

2.1服务之间如何相互发现

微服务架构——每个服务只处理一件事情/一个步骤,在一个复杂的业务中必然存在服务间的互相调用,服务想要相互调用必须先发现对方。
服务注册与发现中心也是一台独立的服务器

  1. 服务提供者服务注册与发现中心进行注册
  2. 服务注册与发现中心进行服务记录,并与服务提供者保持心跳
  3. 服务消费者通过服务注册与发现中心进行服务查询(服务发现)
  4. 服务注册与发现中心返回可用的服务的服务器地址列表
  5. 服务消费者通过负载均衡访问服务提供者

2.2服务之间如何通信

服务消费者在调用服务提供者时,首先需要通过服务注册与发现中心进行服务查询,返回服务列表给服务消费者。服务消费者通过LoadBalance调用服务提供者。它们之间通过数据传输规则进行通信,即同步调用和异步调用

2.2.1 同步调用

  • REST(SpringCloud Netflix、SpringCloud Alibaba)
    • 基于HTTP协议的请求和响应
    • 更容易实现、技术更灵活
    • 支持多语言、同时可以实现跨客户端
    • 适用面很广
  • RPC(Dubbo)
    • 基于网络层协议通信
    • 传输效率高
    • 安全性更高
    • 如果有统一的开发规划或者框架,开发效率比较高

2.2.2 异步调用

服务间的异步通信通常是通过消息队列实现的

2.3 服务故障如何解决

2.3.1 服务故障雪崩

在一条服务调用链中,因为某个服务节点的故障导致依赖这个服务的服务被阻塞,如果此时大量的用户请求涌入,产生阻塞的服务就可能会因为资源耗尽而导致服务瘫痪。

服务之间存在依赖,单个服务的故障可能会对整个系统造成灾难性的后果,这就是服务故障的”雪崩效应“。

2.3.2 解决雪崩问题

  • 服务集群——尽量保证每个服务可用
  • 服务降级与熔断

2.4 客户端如何访问多个接口服务

通过路由网关实现接口的统一访问

三、微服务架构框架

3.1主流的微服务架构框架

  • Dubbo (阿里--开源 Apache)
  • Dubbox (当当网基于 Dubbo)
  • jd-hydra (京东基于 Dubbo)
  • SpringCloud Netflix / SpringCloud Alibaba
  • ServiceComb(华为)

3.2 SpringCloud简介

SpringCloud 是一个基于 SpringBoot 实现的微服务架构应用开发框架,并提供了针对微服务架构应用开发的服务注册与发现熔断器网关路由配置管理负载均衡消息总线数据监控等一系列工具

3.3 SpringCloud核心组件

  • SpringCloud Netflix
    • Eureka 服务注册与发现中心,用于服务治理
    • Ribbon 服务访问组件,用于服务调用,实现负载均衡
    • Hystrix 熔断器,用于服务容错管理
    • Feign 服务访问组件(对 Ribbon 和 Hystrix 的封装)
    • zuul 网关组件
  • SpringCloud Config 配置管理组件——分布式配置中心
  • SpringCloud Bus 消息总线
  • SpringCloud Consul 服务注册与发现中心(功能类似 Eureka)

四、搭建服务注册与发现中心

使用 SpringCloud Netflix 中的 Eureka 搭建服务注册与发现中心

4.1 创建SpringBoot应⽤,添加依赖

  • spring web
  • eureka server

4.2 配置服务注册与发现中⼼

## 设置服务注册与发现中⼼的端⼝
server:
    port: 8761
## 在微服务架构中,服务注册中⼼是通过服务应⽤的名称来区分每个服务的
## 我们在创建每个服务之后,指定当前服务的 应⽤名/项⽬名
spring:
    application:
        name: service-eureka
eureka:
    client:
        ## ip 就是服务注册中⼼服务器的ip
        ## port 就是服务注册与发现中⼼设置的port
        service-url:
            defaultZone: http://...:8761/eureka
        ## 设置服务注册与发现中⼼是否为为集群搭建(如果为集群模式,多个eureka节点之间需要相互注册)
        register-with-eureka: false
        ## 设置服务注册与发现中是否作为服务进⾏注册
        fetch-registry: false

4.3 在启动类添加@EnableEurekaServer注解

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

五、服务注册

创建服务注册到服务注册与发现中⼼

5.1 创建SpringBoot应⽤

创建 SpringBoot 应⽤,完成功能开发

5.2 注册服务

将能够完成特定业务的 SpringBoot 应⽤作为服务提供者,注册到服务注册与发现中⼼

5.2.1 添加依赖

  • eureka-server

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

5.2.2 配置application.yml

## 当前服务的port
server:
    port: 9001
    
## 当前应⽤名会作为服务唯⼀标识注册到eureka
spring:
    application:
        name: ...
    datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/...?characterEncoding=utf-8
        username: ...
        password: ...
mybatis:
    mapper-locations: classpath:mappers/*
    type-aliases-package: ...
## 配置Eureka服务注册与发现中⼼的地址
eureka:
    client:
        service-url:
            defaultZone: http://...:8761/eureka

5.2.3 在当前服务应⽤的启动类添加@EnableEurekaClient注解

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

六、服务发现-Ribbon

服务消费者通过 eureka 查找服务提供者,通过服务调⽤组件调⽤提供者

  • eureka server
  • ribbon

6.1 基础配置

6.1.1创建SpringBoot应⽤,添加依赖

  • eureka server
  • ribbon

6.1.2 配置application.yml

server:
    port: 8001
spring:
    application:
        name: ...
eureka:
    client:
        service-url:
            defaultZone: http://...:8761/eureka

6.1.3 在启动类添加@EnableDiscoveryClient注解

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

6.2 服务调用

6.2.1 配置RestTemplate

@Configuration
public class AppConfig {
    @LoadBalanced //启⽤Ribbon(负载均衡)
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }
}

6.2.2 在Service中注⼊RestTemplate对象调⽤服务

@Service
public class OrderAddServiceImpl implements OrderAddService {
    @Autowired
    private RestTemplate restTemplate;
    @Override
    public ResultVO saveOrder(Order order) {
        //1. 调⽤ order-add服务进⾏保存
        ResultVO vo = restTemplate.postForObject("http://order-add/order/add", order, ResultVO.class);
        //2. 调⽤ orderitem-add 保存订单快照
        //3. 调⽤ stock-update 修改商品库存
        //4. 调⽤ shopcart-del 删除购物⻋记录
        return null;
    }
}

6.3 Ribbon服务调⽤说明

@LoadBalanced 注解是 Ribbon 的⼊⼝,在 RestTemplate 对象上添加此注解之后,再使⽤ RestTemplate 发送REST请求的时候,就可以通过 Ribbon 根据服务名称从 Eureka 中查找服务对应的访问地址列表,再根据负载均衡策略(默认轮询)选择其中的⼀个,然后完成服务的调⽤

  • 获取服务列表
  • 根据负载均衡策略选择服务
  • 完成服务调⽤

七、基于Ribbon进⾏服务调⽤的参数传递

7.1 RestTemplate发送调⽤请求的⽅法

SpringCloud的服务调⽤是基于 REST 的,因此当服务提供者规定了请求的⽅式,服务消费者必须发送对应⽅式的请求才能完成服务的调⽤,RestTemplate 提供了多个⽅法⽤于发送不同形式的请求

//post⽅式请求
restTemplate.postForObject();
//get⽅式请求
restTemplate.getForObject();
//delete⽅式请求
restTemplate.delete();
//put⽅式请求
restTemplate.put();

7.2 put/post请求传参

  • 服务消费者请求传参

    //参数1:访问服务的url
    //参数2:传递的对象参数
    //参数3:指定服务提供者返回的数据类型
    ResultVO vo = restTemplate.postForObject("http://order-add/order/add",
                                             order, ResultVO.class);
    
  • 服务提供者接收参数

    @PostMapping("/add")
    public ResultVO addOrder(@RequestBody Order order){
        return orderService.saveOrder(order);
    }
    

7.3 get请求传参

  • 服务消费者请求传参

    String userId = order.getUserId();
    ResultVO vo = restTemplate.getForObject("http://order-add/order/add?
                                            userId="+userId, ResultVO.class);
    
  • 服务提供者接收参数

    @GetMapping("/add")
    public ResultVO addOrder(Order order){
        return orderService.saveOrder(order);
    }
    

八、服务发现-Feign

8.1 基础配置

8.1.1 创建SpringBoot应用,添加依赖

  • spring web
  • eureka server
  • openfeign

8.1.2 配置application.yml

server:
    port: 8002
spring:
    application:
        name: api-order-add-feign
eureka:
    client:
        service-url:
            defaultZone: http://localhost:8761/eureka

8.1.3 在启动类添加注解

@SpringBootApplication
@EnableDiscoveryClient //声明为服务消费者
@EnableFeignClients //声明启⽤feign客户端
public class ApiOrderAddFeignApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiOrderAddFeignApplication.class, args);
    }
}

8.2 服务调用

使⽤Feign进⾏服务调⽤的时候,需要⼿动创建⼀个服务访问客户端(接⼝)

8.2.1 创建Feign客户端

@FeignClient("order-add")
public interface OrderAddClient {
    @PostMapping("order/add")
    public ResultVO addOrder(Order order);
}

8.2.2 使用Feign客户端调用服务

@Service
public class OrderAddServiceImpl implements OrderAddService {
    @Autowired
    private OrderAddClient orderAddClient;
    @Override
    public ResultVO saveOrder(Order order) {
        //1. 调⽤ order-add服务进⾏保存
        ResultVO vo = orderAddClient.addOrder(order);
        //2. 调⽤ orderitem-add 保存订单快照
        //3. 调⽤ stock-update 修改商品库存 
        //4. 调⽤ shopcart-del 删除购物⻋记录
        return vo;
    }
}

8.3 Feign传参

8.3.1 POST请求

  • 通过请求体传递对象

    • 服务提供者

      @PostMapping("/add")
      public ResultVO addOrder(@RequestBody Order order){
          System.out.println("-------------------order-add");
          System.out.println(order);
          return orderService.saveOrder(order);
      }
      
    • 服务消费者(Feign客户端)

      @FeignClient("order-add")
      public interface OrderAddClient {
          @PostMapping("order/add")
          public ResultVO addOrder(Order order);
      }
      
  • 通过请求行传参

    • 服务提供者

      @PostMapping("/add")
      public ResultVO addOrder(@RequestBody Order order,String str){
          System.out.println("-------------------order-add");
          System.out.println(order);
          System.out.println(str);
          return orderService.saveOrder(order);
      }
      
    • 服务消费者( Feign 客户端)

      //1.对⽤POST请求调⽤服务,Feign客户端的⽅法参数默认为body传值(body只能有⼀个值)
      //2.如果有多个参数,则需要通过 @RequestParam 声明参数为请求⾏传值
      @PostMapping("order/add")
      public ResultVO addOrder(Order order,@RequestParam("str") String str);
      

8.3.2 GET请求

Get请求调⽤服务,只能通过url传参

在Feign客户端的⽅法中,如果不指定参数的传值⽅式,则默认为 body 传参,Get 请求也不例外;因此对于 Get 请求传递参数,必须通过 @RequestParam 注解声明

  • 服务提供者

    @GetMapping("/get")
    public Order addOrder(String orderId){
        return new Order();
    }
    
  • 服务消费者( Feign 客户端)

    @GetMapping("order/get")
    public Order getOrder(@RequestParam("orderId") String orderId);
    

九、服务注册与发现中⼼的可靠性和安全性

9.1 可靠性(Eureka集群搭建)

在微服务架构系统中,服务消费者是通过服务注册与发现中⼼发现服务、调⽤服务的,服务注册与发现中⼼服务器⼀旦故障,将会导致整个微服务架构系统的崩溃,如何保证 Eureka 的可靠性呢?

——使⽤eureka集群

## 设置服务注册与发现中⼼的端⼝
server:
    port: 8761
## 在微服务架构中,服务注册中⼼是通过服务应⽤的名称来区分每个服务的
## 我们在创建每个服务之后,指定当前服务的 应⽤名/项⽬名
spring:
    application:
        name: service-eureka
eureka:
    client:
        ## 设置服务注册与发现中⼼是否为集群搭建
        register-with-eureka: true
        ## 设置服务注册与发现中是否作为服务进⾏注册
        fetch-registry: true
        ## ip 就是服务注册中⼼服务器的ip
        ## port 就是服务注册与发现中⼼设置的port
        service-url:
            defaultZone: http://IP:8761/eureka

9.2 安全性(整合SpringSecurity)

当完成 Eureka 的搭建之后,只要知道ip和port就可以随意的注册服务、调⽤服务,这是不安全的,我们可以通过设置帐号和密码来限制服务的注册及发现。

——整合Spring Security

## 设置服务注册与发现中⼼的端⼝
server:
    port: 8761
## 在微服务架构中,服务注册中⼼是通过服务应⽤的名称来区分每个服务的
## 我们在创建每个服务之后,指定当前服务的 应⽤名/项⽬名
spring:
    application:
        name: service-eureka
eureka:
    client:
        ## 设置服务注册与发现中⼼是否为集群搭建
        register-with-eureka: true
        ## 设置服务注册与发现中是否作为服务进⾏注册
        fetch-registry: true
        ## ip 就是服务注册中⼼服务器的ip
        ## port 就是服务注册与发现中⼼设置的port
        service-url:
            defaultZone: http://IP:8761/eureka

9.2.1 添加SpringSecurity的依赖

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

9.2.2 设置访问eureka的帐号和密码

spring:
    security:
        user:
            name: ...
            password: ...

9.2.3 配置Spring Security

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        //设置当前服务器的所有请求都要使⽤spring security的认证

        http.authorizeRequests().anyRequest().authenticated().and().httpBasic(
        );
    }
}

9.2.4 服务提供者和服务消费者连接到注册中⼼都要帐号和密码

eureka:
    client:
        service-url:
            defaultZone: http://账号:密码@localhost:8761/eureka

十、熔断器-Hystrix

服务故障的雪崩效应:当A服务调⽤B服务时,由于B服务的故障导致A服务处于阻塞状态,当量的请求可能会导致A服务因资源耗尽⽽出现故障。

为了解决服务故障的雪崩效应,出现了熔断器模型。

10.1 简介

熔断器作⽤:

  • 服务降级:⽤户请求A服务,A服务调⽤B服务,当B服务出现故障或者在特定的时间段内不能给A服务响应,为了避免A服务因等待B服务⽽产⽣阻塞,A服务就不等B服务的结果了,直接给⽤户⼀个降级响应
  • 服务熔断:⽤户请求A服务,A服务调⽤B服务,当B服务出现故障的频率过⾼达到特定阈值(5s 20次)时,当⽤户再请求A服务时,A服务将不再调⽤B服务,直接给⽤户⼀个降级响应

10.2 原理

10.3 基于Ribbon服务调⽤的熔断器使⽤

10.3.1 服务消费者的服务降级

  • 添加熔断器依赖hystrix

    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  • 在启动类添加@EnableHystrix注解

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableHystrix
    public class ApiOrderAddApplication {
        public static void main(String[] args) {
            SpringApplication.run(ApiOrderAddApplication.class, args);
        }
    }
    
  • 在调⽤服务提供者的业务处理⽅法中,进⾏降级配

    @Service
    public class OrderAddServiceImpl implements OrderAddService {
        @Autowired
        private RestTemplate restTemplate;
        
        @HystrixCommand(fallbackMethod = "fallbackSaveOrder",commandProperties = {
          @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
        })
        public ResultVO saveOrder(Order order) {
            //1. 调⽤ order-add服务进⾏保存
            //参数1:访问服务的url
            //参数2:传递的对象参数
            //参数3:指定服务提供者返回的数据类型
            ResultVO vo = restTemplate.postForObject("http://order-add/order/add",order, ResultVO.class);
            System.out.println(vo);
            //2. 调⽤ orderitem-add 保存订单快照
            //3. 调⽤ stock-update 修改商品库存
            //4. 调⽤ shopcart-del 删除购物⻋记录
            return vo;
        }
        /**
         * 降级⽅法:与业务⽅法拥有相同的参数和返回值
         * @return
         */
        public ResultVO fallbackSaveOrder(Order order){
            return ResultVO.fail("⽹络异常,请重试!",null);
        }
    }
    

10.3.2 服务提供者的服务降级

  • 配置步骤⼀致

  • 服务提供者接⼝降级

    @RestController
    @RequestMapping("/order")
    public class OrderController {
        @Autowired
        private OrderService orderService;
        
        @HystrixCommand(fallbackMethod = "fallbackAddOrder",commandProperties = {
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000")
        })
        @PostMapping("/add")
        public ResultVO addOrder(@RequestBody Order order){
            System.out.println("-------------------order-add");
            System.out.println(order);
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return orderService.saveOrder(order);
        }
        public ResultVO fallbackAddOrder(@RequestBody Order order){
            System.out.println("-------------------order-add--fallback");
            return ResultVO.fail("订单保存失败!",null);
        }
    }
    

10.3.3 服务熔断配置

  • 熔断器状态:闭合、打开、半开

  • 服务熔断配置

    @HystrixCommand(fallbackMethod ="fallbackSaveOrder",commandProperties = {
        @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="3000"),
        @HystrixProperty(name="circuitBreaker.enabled",value="true"),//启⽤服务熔断
        @HystrixProperty(name="circuitBreaker.sleepWindowInMilliseconds",value="10000"),//时间
        @HystrixProperty(name="circuitBreaker.requestVolumeThreshold",value="10"),//请求次数
        @HystrixProperty(name="circuitBreaker.errorThresholdPercentage",value="50"),//服务错误率
    })
    public ResultVO saveOrder(Order order) {
        //1. 调⽤ order-add服务进⾏保存
        ResultVO vo = restTemplate.postForObject("http://order-add/order/add", order, ResultVO.class);
        System.out.println(vo);
        //2. 调⽤ orderitem-add 保存订单快照
        //3. 调⽤ stock-update 修改商品库存
        //4. 调⽤ shopcart-del 删除购物⻋记录
        return vo;
    }
    /**
    * 降级⽅法:与业务⽅法拥有相同的参数和返回值
    * @return
    */
    public ResultVO fallbackSaveOrder(Order order){
        return ResultVO.fail("⽹络异常,请重试!",null);
    }
    

    服务熔断:当⽤户请求服务A,服务A调⽤服务B时,如果服务B的故障率达到特定的阈值时,熔断器就会被打开⼀个时间周期(默认5s,可⾃定义),在这个时间周期内如果⽤户请求服务A,服务A将不再调⽤服务B,⽽是直接响应降级服务。

10.4 基于Feign服务调⽤的熔断器使⽤

Feign是基于Ribbon和Hystrix的封装

10.4.1 Feign中的熔断器使⽤

  • 添加依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Hoxton.SR11</spring-cloud.version>
    </properties>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>
    
  • 在application.yml启⽤熔断器机制

    feign:
      hystrix:
          enabled: true
    
  • 在启动类添加 @EnableHystrix

    @SpringBootApplication
    @EnableDiscoveryClient
    @EnableFeignClients
    @EnableHystrix
    public class ApiOrderAddFeignApplication {
        public static void main(String[] args) {
            SpringApplication.run(ApiOrderAddFeignApplication.class,args);
        }
    }
    
  • 创建服务降级处理类

    FeignClient的服务降级类:1.必须实现Feign客户端接⼝,2.必须交给Spring容器管理

    @Component
    public class OrderAddClientFallback implements OrderAddClient {
        public ResultVO addOrder(Order order, String str) {
            System.out.println("-------addOrder的降级服务");
            return ResultVO.fail("fail",null);
        }
        public Order getOrder(String orderId) {
            System.out.println("-------getOrder的降级服务");
            return new Order();
        }
    }
    
  • 在 Feign 客户端指定降级处理类

    @FeignClient(value = "order-add", fallback = OrderAddClientFallback.class)
    public interface OrderAddClient {
        //1.对⽤POST请求调⽤服务,Feign客户端的⽅法参数默认为body传值(body只能有⼀个值)
        //2.如果有多个参数,则需要通过@RequestParam声明参数为请求⾏传值
        @PostMapping("order/add")
        public ResultVO addOrder(Order order,@RequestParam("str") String str);
        @GetMapping("order/get")
        public Order getOrder(@RequestParam("orderId") String orderId);
    }
    
  • Service类通过Feign客户端调⽤服务

    @Service
    public class OrderAddServiceImpl implements OrderAddService {
        @Autowired
        private OrderAddClient orderAddClient;
        //当我们创建Feign客户端的降级类并交给Spring管理后 在Spring容器中就会出现两个OrderAddClient对象
        @Override
        public ResultVO saveOrder(Order order) {
            //1. 调⽤ order-add服务进⾏保存
            ResultVO vo = orderAddClient.addOrder(order,"测试字符串");
            Order order1 = orderAddClient.getOrder("订单编号");
            System.out.println(order1);
            //2. 调⽤ orderitem-add 保存订单快照
            //3. 调⽤ stock-update 修改商品库存
            //4. 调⽤ shopcart-del 删除购物⻋记录
            return vo;
        }
    }
    

10.5熔断器仪表盘监控

如果服务器的并发压⼒过⼤、服务器⽆法正常响应,则熔断器状态变为open属于正常的情况;但是如果⼀个熔断器⼀直处于open状态、或者说服务器提供者没有访问压⼒的情况下熔断器依然为open状态,说明熔断器的状态就不属于正常情况了。如何了解熔断器的⼯作状态呢 ?

——熔断器仪表盘

10.5.1 搭建熔断器仪表盘

  • 创建SpringBoot项目,添加依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
    </dependency>
    
  • 配置仪表盘的port和appName

    server:
      port: 9999
    spring:
      application:
          name: hystrix-dashboard
    hystrix:
      dashboard:
          proxy-stream-allow-list: "localhost"
    
  • 启动类添加 @EanbleHystrixDashboard 注解

    @SpringBootApplication
    @EnableHystrixDashboard
    public class HystrixDashboardApplication {
        public static void main(String[] args) {
            SpringApplication.run(HystrixDashboardApplication.class,args);
        }
    }
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,245评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,749评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,960评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,575评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,668评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,670评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,664评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,422评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,864评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,178评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,340评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,015评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,646评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,265评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,494评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,261评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,206评论 2 352

推荐阅读更多精彩内容