抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

Spring Cloud Hystrix介绍

在分布式环境中,许多服务依赖关系中的一些必然会失败。Hystrix是一个库,它通过添加延迟容忍和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix通过隔离服务之间的访问点、停止跨服务的级联故障并提供回退选项来实现这一点,所有这些选项都提高了系统的总体弹性。

简单来说,就是分布式项目中,有很多微服务之间不听的项目调用,如果出现了被调用者出现问题,宕机了,那么这时候熔断器就要发挥它的作用了。

https://imgconvert.csdnimg.cn/aHR0cHM6Ly93d3cuc3ByaW5nY2xvdWQuY2MvaW1hZ2VzL0h5c3RyaXhHcmFwaC5wbmc?x-oss-process=image/format,png

Ribbon实现熔断

ribbon-hystrix子项目搭建

继续在之前的聚合工程中创建子项目,consumer-ribbon-hystrix

pom文件

新加入cloud,hystrix配置文件即可

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

yml配置

eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka01:8800/eureka/,http://eureka02:8810/eureka/
server:
  tomcat:
    uri-encoding: UTF-8
  port: 11001

spring:
application:
name: consumer-ribbon-hystrix
main:
allow-bean-definition-overriding: true

启动类

@EnableHystrix //在启动类上添加@EnableHystrix注解开启Hystrix的熔断器功能。
@SpringBootApplication
//@EnableDiscoveryClient //从Spring Cloud Edgware开始,@EnableDiscoveryClient 或@EnableEurekaClient 可省略。只需加上相关依赖,并进行相应配置,即可将微服务注册到服务发现组件上。
public class ConsumerRibbonHystrixApplication {

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


    //开启restTemplate负载均衡
    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    /**
     * 配置随机负载策略,需要配置属性service-B.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
     */
    @Bean
    public IRule ribbonRule() {
        return new RandomRule();
    }

}

Controller

@RestController
public class HiController {

    @Autowired
    private HiService hiService;

    @GetMapping("/hi")
    public String sayHello(String name){
        return hiService.sayHello(name);
    }
}

Service

@Service
public class HiServiceImpl implements HiService {


    @Autowired
    private RestTemplate restTemplate;

    @Override
    @HystrixCommand(fallbackMethod = "getDefaultUser")
    public String sayHello(String name) {
        if(null != name){
            String url = "http://provider/hello?name="+name;
            System.err.println(url);
            return restTemplate.getForObject(url,String.class);
        }else {
            //名字为空请求一个不存在的地址
            String url = "http://provider/null";
            return restTemplate.getForObject(url,String.class);
        }

    }

    public String getDefaultUser(String name) {
        return "熔断,默认回调--名称是:"+name;
    }

}

运行

https://img-blog.csdnimg.cn/20200326144606642.gif

Feign实现熔断

feign-hystrix子项目搭建
新建一个consumer-feign-hystrix子项目,目录结构如下

https://img-blog.csdnimg.cn/20200326144911251.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM2MzU3MjQy,size_16,color_FFFFFF,t_70

yml配置文件

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8800/eureka/,http://localhost:8810/eureka/
server:
  tomcat:
    uri-encoding: UTF-8
  port: 11002
feign:
  hystrix:
    enabled: true #启用hystrix
#  servlet:
#    context-path: /gbq_consumer
spring:
  main:
    allow-bean-definition-overriding: true  #避免相同名字的Feign注册会导致重复注册
  application:
    name: consumer-feign-hystrix

启动类

@SpringBootApplication
@EnableFeignClients
//@EnableDiscoveryClient
public class ConsumerFeignHystrixApplication {

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

}

不需要加其他的东西

Controller

@RestController
public class HiController {

    @Resource
    private GetHello getHello;

    @GetMapping("/test")
    public User getPostUser(User user){
        return getHello.getPostUser(user);
    }

}
//GetHello
@FeignClient(name = "provider",fallback = UserFeignClientFallback.class)
//@FeignClient(name = "provider")
public interface GetHello {

    @RequestMapping(value = "/getPostUser",method = RequestMethod.POST)
    User getPostUser(@RequestBody User user);

}

Comment

@Component
public class UserFeignClientFallback implements GetHello{

    @Override
    public User getPostUser(User user) {
        return new User(1,"熔断用户1");
    }
}

对应的provider接口

@PostMapping("/getPostUser")
    public User getPostUser(@RequestBody User user) throws InterruptedException {
        if (user.getId()!=1){
            System.err.println("1");
            return user; //正常返回
        }else {
            Thread.sleep(10000L);//休息10秒,意味着会出现请求超时
            return null; 
        }

    }

请求超时就会发生熔断

运行

https://img-blog.csdnimg.cn/20200326155317866.gif

评论