SpringCloud 熔断器 Hystrix 实现

背景:在实际的微服务系统中,是有众多的服务的,并且经常一个服务需要依赖另一个服务,例如大的电商系统中,切分的订单服务和支付的服务就会有互相依赖的情况,而如果其中一个服务挂掉了,另一个服务一直请求,是肯定拿不到返回的,这样长时间的请求就会堆积,造成服务的崩溃,这样造成整个系统的瘫痪,这样的架构相较于传统架构更加不稳定。而为了解决和应对这个问题就出现了熔断器Hystrix。

目录

(一)简介

(二)实现方式 

1.Ribbon

2.使用feign的方式 

(一)简介

Netflix的创造了一个调用的库Hystrix实现了熔断器图案。在微服务架构中,通常有多层服务调用。

SpringCloud 熔断器 Hystrix 实现_第1张图片

较低级别的服务中的服务故障可能导致用户级联故障。当对特定服务的呼叫达到一定阈值时(Hystrix中的默认值为5秒内的20次故障),电路打开,不进行通话。在错误和开路的情况下,开发人员可以提供后备。 

SpringCloud 熔断器 Hystrix 实现_第2张图片

开放式电路会停止级联故障,并允许不必要的或失败的服务时间来愈合。回退可以是另一个Hystrix保护的调用,静态数据或一个正常的空值。回退可能被链接,所以第一个回退使得一些其他业务电话又回到静态数据。

(二)实现方式 

springCloud中可以通过Ribbon和Feign两种方式实现熔断器,下面的依旧是基于之前的工程:eureka实现,Ribbon实现,feign实现

1.Ribbon

在之前Ribbon项目pom.xml中加入Hystrix依赖

  
            org.springframework.cloud
            spring-cloud-starter-netflix-hystrix

在ribbon启动类上加上hystrix注解@EnableHystrix

package com.cloud.ribbonservice;

import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class RibbonserviceApplication {

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

    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule ribbonRule() {
        return new RandomRule();	//这里配置策略,和配置文件对应
    }

}

然后再调用方法上加上@HystrixCommand(fallbackMethod = "portFallback")注解,并加上断路之后的回调方法portFallback。

package com.cloud.ribbonservice.service;

import com.cloud.ribbonservice.controller.Controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;

@Service
public class RibbonService implements IRibbonService {

    private static final Logger logger = LoggerFactory.getLogger(IRibbonService.class);

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    LoadBalancerClient loadBalancerClient;

    @HystrixCommand(fallbackMethod = "portFallback")
    public String port() {
        this.loadBalancerClient.choose("SPRING-CLIENT-01");
        String info = restTemplate.getForObject("http://SPRING-CLIENT-01/getInfo/port", String.class);
        return restTemplate.getForObject("http://SPRING-CLIENT-01/getInfo/port", String.class);

    }

    private String portFallback()
    {
        logger.error("The service is Down");
        System.err.println("The service is Down");
        return "Service down";
    }

   

}

这样基础就配置好了。

然后启动注册中心,SPRING-CLIENT-01服务,ribbon服务。

在浏览器或者postman中输入

http://localhost:11000/getInfo/hellol

 SpringCloud 熔断器 Hystrix 实现_第3张图片

关闭 SPRING-CLIENT-01服务,刷新浏览器

SpringCloud 熔断器 Hystrix 实现_第4张图片

SpringCloud 熔断器 Hystrix 实现_第5张图片

触发熔断成功。

2.使用feign的方式 

 1.在之前的feign工程中pom.xml中加入Hystrix依赖

2.feign的配置文件application.properties文件中打开Hystrix的开关 feign.hystrix.enabled=true

server.port = 10010

eureka.client.serviceUrl.defaultZone= http://localhost:12345/eureka/
spring.application.name= SPRING-FEIGN-SERVICE


spring.datasource.url=jdbc:mysql://127.0.0.1:3306/testmysql
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5

feign.hystrix.enabled=true

在调用接口中加入一个熔断的类,这个类要实现之前调用其他服务的接口

package com.springcloudfeign.feign.service;

import org.springframework.stereotype.Component;

@Component
public class ErrorHystrix implements FeignDemoService {

    @Override
    public String getPort() {
        return "sorry, it's error!";
    }

    @Override
    public String getPortTwo() {
        return "sorry, it's also error!";
    }


}

然后再FeignDemoService接口注解中加入熔断回调的类的注解@FeignClient(value = "SPRING-CLIENT-01" ,fallback = ErrorHystrix.class)

package com.springcloudfeign.feign.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient(value = "SPRING-CLIENT-01" ,fallback = ErrorHystrix.class)
public interface FeignDemoService {

    @RequestMapping(value = "port" , method = RequestMethod.GET)
    String getPort();

    @RequestMapping(value = "getInfo/show" , method = RequestMethod.GET)
    String getPortTwo();
}

这样就可以了。

SPRING-SERVICE-01没有关调用feign中接口的方式和返回是:

浏览器中输入:

http://localhost:10010/getInfoTwo

返回:

SpringCloud 熔断器 Hystrix 实现_第6张图片

断开 SPRING-SERVICE-01服务,刷新浏览器返回:

说明熔断器调用成功。

以上代码github地址: 源码地址

 

 

 

 

 

 

 

 

你可能感兴趣的:(SpringCloud,分布式,架构,Spring,Cloud)