Spring Cloud Hystrix(服务容错保护)(1)

版权声明:版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37598011/article/details/82561146

在前面的博客中我已经将Eureka与Ribbon的使用展示了出来,但是如果将其中的某一个服务停止(Hello-Service)。你会发现Ribbon任然会去访问那个页面。

这就需要用到断路器的功能。

首先将Ribbon工程的pom文件中加入该jar包:

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

再其主类工程中使用@EnableCircuitBreaker注解开启断路器功能:

@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class EurekaRibbonApplication {
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }

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

也可以用@SpringCloudApplication注解来替代:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public @interface SpringCloudApplication {
}

然后改造其服务的消费方式,新增Service层,注入RestTemplate实例。然后在其方法上添加@HystrixCommand注解来指定回调方法:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "helloFallback")
    public String helloService() {
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://hello-service/hello", String.class);
        String body = responseEntity.getBody();
        return body;
    }

    public String helloFallback() {
        return "error";
    }
}

Controller类改成如下:

@RestController
public class ConsumerController {

    @Autowired
    HelloService helloService;

    @RequestMapping("/ribbon-consumer")
    public String helloConsumer() {
        return helloService.helloService();
    }
}

运行后:

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

然后中断一个服务

随后可以发现再请求http://localhost:8099/ribbon-consumer它不会再请求已经断开的服务。

除了断开服务实例来模拟节点无法访问的情况之外,我们还能模拟下服务阻塞(长时间未响应)如:

@RestController
public class HelloController {

    private final Logger logger=Logger.getLogger(getClass());

    @Autowired
    private DiscoveryClient client;

    @RequestMapping("/hello")
    public String index() throws InterruptedException {
        int sleepTime=new Random().nextInt(3000);
        logger.info("sleep:"+sleepTime);
        Thread.sleep(sleepTime);
        return "Hello";
    }

}

修改Hello-Service中的服务提供者的代码,用Thread.sleep来进行模拟延时。

因为Hystrix默认的超时时间为1000毫秒,所以这里用0-3000的随机数进行了模拟,为了方便观察断路器的触发,在消费者调用函数也做了时间的记录:

   @HystrixCommand(fallbackMethod = "helloFallback")
    public String helloService() {
        long start=System.currentTimeMillis();
        ResponseEntity<String> responseEntity = restTemplate.getForEntity("http://hello-service/hello", String.class);
        String body = responseEntity.getBody();
        long end=System.currentTimeMillis();
        logger.info("消耗时间:"+(start-end));
        return body;
    }

此时可以看到当sleep大于1000的时候它就会返回error,即服务消费者因调用服务超时从而触发熔断请求,并回调逻辑返回结果。

猜你喜欢

转载自blog.csdn.net/qq_37598011/article/details/82561146