六、服务容错保护(Hystrix服务降级)

1、简介

在微服务架构中,我们将系统拆分成立一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程间运行,依赖通过远程调用的方式执行,这样就可以因为网络原因或者依赖服务自身问题出现调用故障或延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务的积压,线程资源无法释放,最终导致自身服务的瘫痪,进一步甚至出现故障的蔓延导致整个系统的瘫痪。如果这样的架构存在如此严重的隐患,那么相较于传统的架构就会更加的不稳定。为了解决这样的问题,就产生了断路器等一系列的服务保护机制。针对上述问题,在Spring Cloud Hystrix中实现了线程隔离、断路器等一系列的服务保护功能。它也是基于Netflix的开源框架 Hystrix实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。Hystrix具备了服务降级、服务熔断、线程隔离、请求缓存、请求合并以及服务监控等强大功能。

创建工程

在之前创建的microservice-spring-cloud工程下,新建一个Moudle,命名为microservice-consumer-movie-ribbon-with-hystrix。然后我们在pom.xml中,引入如下的坐标

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

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-hystrix</artifactId>
    </dependency>
</dependencies>

代码部分

User实体类(和之前的一样)

package zhuangxp.entity;

import java.io.Serializable;
import java.math.BigDecimal;

public class User implements Serializable {
    private Long id;

    private String username;

    private String name;

    private short age;

    private BigDecimal balance;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public short getAge() {
        return age;
    }

    public void setAge(short age) {
        this.age = age;
    }

    public BigDecimal getBalance() {
        return balance;
    }

    public void setBalance(BigDecimal balance) {
        this.balance = balance;
    }
}

MovieController

package zhuangxp.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import zhuangxp.entity.User;

@RestController
public class MovieController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/movie/{id}")
    @HystrixCommand(fallbackMethod = "findByIdFallback")
    public User getById(@PathVariable("id") Long id){
        return this.restTemplate.getForObject("http://microservice-provider-user/getUser/"+id,User.class);
    }

    public User findByIdFallback(Long id) {
        User user = new User();
        user.setId(0L);
        return user;
    }



}

和之前的MovieController不同的是,我们在具体执行逻辑的方法上增加了@HystrixCommand(fallbackMethod = "findByIdFallback")注解来指定服务降级的方法,然后编写降级的方法,这个方法的参数和返回值应该和原方法保持一致。

启动类

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class MainAppConsumerRibbonWithHystrix {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

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

启动类中使用@EnableCircuitBreaker来开启Hystrix的使用。

测试验证

启动microservice-discovery-eureka、microservice-provider-user、microservice-consumer-movie-ribbon-with-hystrix。访问MovieController中的getById方法,路径http://localhost:3001/movie/1,可以正常返回到数据,如下

{"id":1,"username":"user1","name":"张三","age":18,"balance":100.00}

当我们的服务提供者挂掉后(方便演示,手动给停掉),就会访问到降级的方法,返回值如下:

{"id":0,"username":null,"name":null,"age":0,"balance":null}

猜你喜欢

转载自www.cnblogs.com/beanbag/p/10127827.html