springcloud系列(四)----Hystrix 断路器

一. 简介

二. 搭建Hystrix 

2.1 基于Ribbon整合Hystrix

2.1.1 pox.xml

注: 需要引入eureka, ribbon, hystrix, actuator, dashboard, web依赖。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>ribbon</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>ribbon</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</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-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

        <!-- 防止找不到@EnableHystrixDashboard注解  引入后可以删除 -->
        <!--<dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-javanica</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
        </dependency>-->
        <!-- 防止找不到@EnableHystrixDashboard注解  引入后可以删除 -->


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


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2.1.2 application.yml

server:
  port: 8761

spring:
  application:
    name: ribbon

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8760/eureka/

2.1.3 启动类

package com.example.ribbon;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableHystrixDashboard
public class RibbonApplication {

    public static void main(String[] args) {
        SpringApplication.run(RibbonApplication.class, args);
        System.out.println("ribbon has started!");
    }

    @Bean
    @LoadBalanced   // 该注解开启Ribbon的负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }


    /**
     * 在2.0版本下需要在启动类中添加如下配置才可以访问断路器仪表盘
     * 访问短路监控url为:http://localhost:8761/hystrix
     * 在页面填写路径: http://localhost:8761/hystrix.stream
     * @return
     */
    @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;
    }

}

2.1.4 Controller类

package com.example.ribbon;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Autowired
    HelloService helloService;

    @GetMapping(value = "/sayHello")
    public String sayHello(@RequestParam String name) {
        return this.helloService.sayHello(name);
    }

}

2.1.5 对外暴露接口

package com.example.ribbon;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "helloError")
    public String sayHello(String name) {
        // eurekaclient对应的服务名称 ribbon会自动选择实例并解析为对应的url地址 然后访问俩个客户端对应的controller
        return this.restTemplate.getForObject("http://eurekaclient/sayHello?name=" + name, String.class);
    }

    // hystrix的回退方法
    public String helloError(String name) {
        return "hello " + name + ", sorry  i am down...";
    }

}

注: ribbon使用hystrix的回退方法与服务提供接口类在同一个类中。 如果访问失败,会调用回退方法。

       通过@HystrixCommand注解的fallbackMethod指定回退方法。

2.1.6 启动查看

2.1.6.1 查看eureka server

注: 看到该页面说明启动成功。

2.1.6.2 查看断路器监控页面

点击Monitor Stream显示如下:


2.1.7 测试断路器

关闭eurekaclient和eurekaclient2俩个客户端,然后继续调用,会返回回退方法中的结果:

此时, 断路器监控页面显示如下:

扫描二维码关注公众号,回复: 2874743 查看本文章


此时,将俩个客户端重新开启,经过一定次数的访问之后,断路器会关闭。

2.2 基于Feign整合Hystrix

2.2.1 pom.xml

注: 需要引入eureka, feign, openfeign, actuator, dashboard, web依赖。 feign默认集成了hystrix。

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>feign</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>feign</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
    </properties>

    <dependencies>

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

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

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
        </dependency>

        <!-- 防止找不到@EnableHystrixDashboard注解  引入后可以删除 -->
        <!--<dependency>
            <groupId>com.netflix.hystrix</groupId>
            <artifactId>hystrix-javanica</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
        </dependency>-->
        <!-- 防止找不到@EnableHystrixDashboard注解  引入后可以删除 -->


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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>

2.2.2 application.yml

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8760/eureka/

server:
  port: 8762

spring:
  application:
    name: feign

feign:
  hystrix:
    enabled: true

2.2.3 启动类

package com.example.feign;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrixDashboard
public class FeignApplication {

    public static void main(String[] args) {
        SpringApplication.run(FeignApplication.class, args);
        System.out.println("feign has started!");
    }


    /**
     * 在2.0版本下需要在启动类中添加如下配置才可以访问断路器仪表盘
     * 访问url为:http://localhost:8761/hystrix
     * 在页面填写路径: http://localhost:8761/hystrix.stream
     *
     * @return
     */
    @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;
    }

}

2.2.4 Controller类

package com.example.feign;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SayHelloController {

    @Autowired
    private SayHelloService sayHelloService;

    @GetMapping(value = "/sayHello")
    public String sayHello(@RequestParam String name) {
        return this.sayHelloService.sayHello(name);
    }

}

2.2.5 对外暴露接口

注: feign默认集成hystrix, 通过@FeignClient注解的fallback指定回退类。

package com.example.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * eurekaclient为提供服务的名称
 */
@FeignClient(value = "eurekaclient", fallback = SayHelloServiceHystrix.class)
@Service
public interface SayHelloService {

    @GetMapping(value = "/sayHello")
    String sayHello(@RequestParam(value = "name") String name);

}

注: feign使用hystrix通过使用@FeignClient注解的fallback属性指定回退类。

2.2.6 hystrix回退类

package com.example.feign;

import org.springframework.stereotype.Component;

/**
 * SayHelloService接口的Hystrix回退类  实现SayHelloService接口即可
 */
@Component
public class SayHelloServiceHystrix implements SayHelloService {

    @Override
    public String sayHello(String name) {
        return "hello " + name + ", sorry  i am down...";
    }
}
注: feign使用hystrix的回退方法在服务提供接口的实现类中,通过覆盖指定方法即可。 如果访问失败,会调用回退方法。

2.2.7 启动查看

如上。 注意要把访问端口改为8762即可。

2.2.6 测试断路器

如上。注意要把访问端口改为8762即可。


三. 代码路径

github路径:https://github.com/1956025812/springcloud

代码已提交,欢迎大家参考


猜你喜欢

转载自blog.csdn.net/qq_35206261/article/details/81021960