(五)Spring Cloud 熔断器 hystrix

我们在前两章分别讲了通过Ribbon和Feign对服务进行负载均衡的访问,但是当访问的服务不可用时,可能就会有大量的请求等待从而消耗服务器的资源

通过熔断器hystrix,当服务不可用,或者达到我们设置的某个阈值时,我们就可以快速失败,从而防止资源耗尽,而避免雪崩效应的发生。

下面我们将分别对Ribbon和Feign进行熔断器的配置,代码我们将基于前2章的代码,此处将只只是新添加的代码

1. Ribbon使用RestTemplate配置熔断器

  我们基于eureka-ribbon-client项目做修改

     1.1 pom中添加hystrix的依赖

   

  <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-netflix-hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

    1.2 在启动类上加上 @EnableHystrix

 

package com.devin.eurekaribbonclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;

@EnableHystrix
@EnableEurekaClient
@SpringBootApplication
public class EurekaRibbonClientApplication {

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

}

   1.3 修改Service中RestTemplate对eureka-cleint的调用

   增加eureka-client不可用时的熔断方法,当服务接口不可用时,将调用熔断方法 helloFallback

   详细代码如下

    

package com.devin.eurekaribbonclient.service;

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

import javax.annotation.Resource;

/**
 * @author Devin Zhang
 * @className RibbonHelloService
 * @description TODO
 * @date 2020/3/28 11:54
 */
@Service
public class RibbonHelloService {

    @Resource
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "helloFallback")
    public String sayHello(String name) {
        return restTemplate.getForObject("http://EUREKA-CLIENT/sayHello?name=" + name, String.class);
    }

    public String helloFallback(String name) {
        return "hello " + name + " , response by hystrix";
    }
}

    1.4 测试

   启动eureka-server (7001)   eureka-client(7002)  eureka-ribbon-client(7004) 

   访问接口 http://localhost:7004/sayHelloFromRibbon?name=devin ,可以看到接口返回正常

   

   此时关闭 eureka-client ,再次刷新页面可以看到,请求已经进入到熔断器的方法

  

  2. 在Feign中使用熔断器

   我们基于上一章的eureka-feign-client 进行改造 ,因为feign中已经引入了熔断器,所以不需要添加新的依赖

     2.1 在配置文件 application.yml 中启用熔断器hystrix

     feign.hystrix.enabled=true ,完整的配置如下:

   

eureka:
  auth:
    user: dev
    password: 123456
  client:
    serviceUrl:
      defaultZone: http://${eureka.auth.user}:${eureka.auth.password}@localhost:7001/eureka/
  instance:
    #使用IP进行注册
    prefer-ip-address: true
    #配置实例的注册ID
    instance-id: ${spring.cloud.client.ip-address}:${server.port}
    #心跳时间,即服务续约间隔时间(缺省为30s)
    lease-renewal-interval-in-seconds: 5
    #发呆时间,即服务续约到期时间(缺省为90s)
    lease-expiration-duration-in-seconds: 10
    health-check-url-path: /actuator/health
server:
  port: 7004
spring:
  application:
    name: eureka-feign-client
feign:
  httpclient:
    enabled: true
  hystrix:
    enabled: true

  2.2 在声明式调用中,设置熔断器的调用类

 

package com.devin.eurekafeignclient.service;

import com.devin.eurekafeignclient.config.FeignConfig;
import com.devin.eurekafeignclient.vo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @author Devin Zhang
 * @className FeignHelloService
 * @description TODO
 * @date 2020/3/28 16:49
 */
@FeignClient(value = "eureka-client", configuration = FeignConfig.class,fallback = FeignHelloFallbacjService.class)
public interface FeignHelloService {

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

    @PostMapping(value = "/login", consumes = "application/json")
    String login(@RequestBody User user);
}

  

   2.3 定义熔断器调用的实现类

    该类实现了我们的声明式调用接口,并实现各个方法,这些方法将在调用的服务不可用时自动进行调用

   

package com.devin.eurekafeignclient.service;

import com.devin.eurekafeignclient.vo.User;

/**
 * @author Devin Zhang
 * @className FeignHelloFallbacjService
 * @description TODO
 * @date 2020/3/30 16:03
 */

public class FeignHelloFallbacjService implements FeignHelloService {

    @Override
    public String sayHello(String name) {
        return "hello " + name + " ,this is response by feign hystrix";
    }

    @Override
    public String login(User user) {
        return "hello " + user.getUserName() + " ,the server is busy now ,pls retry later,this is response by feign hystrix";
    }
}

 

  2.4  测试

     分别启动 eureka-server 7001  eureka-client 7002  eureka-feign-client 7004 

     get访问 http://localhost:7004/sayHelloFromFeign?name=devin 

     post访问 http://localhost:7004/loginFromFeign?userName=devin&userPass=123456

    可以看到返回正确的结果

   

 

此时,关闭eureka-client,分别访问以上两个接口,将可以看到熔断器hystrix返回的结果

  至此,我们分别在Ribbon和Feign实现了Hystrix熔断器的功能

   

猜你喜欢

转载自www.cnblogs.com/DevinZhang1990/p/12599388.html