Spring Cloud 学习系列:(八)断路器——Hystrix

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.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.hystrix.EnableHystrix;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

@SpringBootApplication

@EnableEurekaClient

@EnableDiscoveryClient

@EnableHystrix

public class MicroserviceProviderServiceRibbonApplication {

public static void main(String[] args) {

SpringApplication.run(MicroserviceProviderServiceRibbonApplication.class, args);

}

@Bean

@LoadBalanced

RestTemplate restTemplate() {

return new RestTemplate();

}

}

(3)、改造HelloService类,在 HelloService 方法上加上@HystrixCommand注解。该注解对该方法创建了断路器的功能,并指定了 fallbackMethod 熔断方法,熔断方法直接返回了一个字符串,字符串为 "sorry " + riemann + “, system fallback!”,代码如下:

@Service

public class HelloService {

@Autowired

RestTemplate restTemplate;

@HystrixCommand(fallbackMethod = “hiError”)

public String hiService(String name) {

return restTemplate.getForObject(“http://microservice-provider-service-hi/hi?name=” + name, String.class);

}

public String hiError(String name) {

return “sorry " + riemann + “, system fallback!”!”;

}

}

(4)、启动:microservice-provider-service-ribbon 工程,当我们访问http://localhost:8763/hi?name=riemann,浏览器显示:

hi riemann ,i am from port: 8764

(5)、此时关闭 microservice-provider-service-hi 工程,当我们再访问http://localhost:8763/hi?name=riemann,浏览器会显示:

sorry riemann, system fallback!

2、在 Feign 中使用断路器

(1)、Feign 是自带断路器的,在D版本的 Spring Cloud 之后,它没有默认打开。需要在配置文件中配置打开它,在配置文件加以下代码:

feign:

hystrix:

enabled: true

(2)、基于 microservice-eureka-feign 工程进行改造,只需要在 FeignClient 的FeignClientServiceHi 接口的注解中加上 fallback 的指定类就行了:

@FeignClient(value = “microservice-provider-service-hi”,fallback = FeignClientFallback.class)

public interface FeignClientServiceHi{

@RequestMapping(value = “/hi”,method = RequestMethod.GET)

String sayHiFromFeignClient(@RequestParam(value = “name”) String name);

}

(3)、FeignClientFallback 需要实现 FeignClientServiceHi接口,并注入到I oc 容器中,代码如下:

@Component

public class FeignClientFallback implements FeignClientServiceHi{

@Override

public String sayHiFromFeignClient(String name) {

return "sorry " + name + “, system fallback!”;

}

}

(4)、启动 microservice-eureka-server-feign-hystrix 与 microservice-provider-service-feign-hystrix 工程,浏览器打开http://localhost:8763/hi?name=riemann,注意此时 microservice-provider-service-hi 工程没有启动,网页显示:

sorry riemann, system fallback!

(5)、打开 microservice-provider-service-hi 工程,再次访问,浏览器显示:

hi riemann ,i am from port: 8764

这就表明断路器起作用了。

3、在 Feign 中使用断路器 (通过 Fallback Factory 检查回退原因)

很多场景下,需要了解回退原因,此时可使用注解 @FeignClient 的 fallbackFactory 属性。

跟第2小点差不多,需要改 FeignClientServiceHi 这个接口。

package com.riemann.microserviceproviderservicehi.client;

import feign.hystrix.FallbackFactory;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.cloud.openfeign.FeignClient;

import org.springframework.stereotype.Component;

import org.springframework.stereotype.Service;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

@FeignClient(value = “microservice-provider-service-hi”, fallbackFactory = FeignClientFallback.class)

public interface FeignClientServiceHi {

@RequestMapping(value = “/hi”,method = RequestMethod.GET)

String sayHiFromFeignClient(@RequestParam(value = “name”) String name);

}

/**

  • 回退类 FeignClientFallback 需实现 Feign Client 接口

*/

@Component

class FeignClientFallback implements FallbackFactory {

private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallback.class);

// 检查回退原因

public FeignClientServiceHi create(Throwable cause) {

return new FeignClientServiceHi() {

@Override

public String sayHiFromFeignClient(String name) {

// 日志最好放在各个fallback方法中,而不要直接放在create方法中。

// 否则在引用启动时,就会打印该日志。

LOGGER.info("fallback; reason was: ", cause);

return "sorry " + name + “, system fallback!”;

}

};

}

}

这样,当 Feign 回退时,控制台就会打印日志。

2019-10-08 17:15:35.881 INFO 3700 — [er-service-hi-1] c.r.m.client.FeignClientFallback : fallback; reason was:

java.lang.RuntimeException: com.netflix.client.ClientException: Load balancer does not have available server for client: microservice-provider-service-hi

at org.springframework.cloud.openfeign.ribbon.LoadBalancerFeignClient.execute(LoadBalancerFeignClient.java:90) ~[spring-cloud-openfeign-core-2.1.3.RELEASE.jar:2.1.3.RELEASE]

at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:108) ~[feign-core-10.2.3.jar:na]

at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78) ~[feign-core-10.2.3.jar:na]

at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:109) ~[feign-hystrix-10.2.3.jar:na]

at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:302) ~[hystrix-core-1.5.18.jar:1.5.18]

at com.netflix.hystrix.HystrixCommand$2.call(HystrixCommand.java:298) ~[hystrix-core-1.5.18.jar:1.5.18]

at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ~[rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) ~[rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) [rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) [rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) [rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) [rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48) [rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) [rxjava-1.3.8.jar:1.3.8]

at rx.Observable.unsafeSubscribe(Observable.java:10327) [rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51) ~[rxjava-1.3.8.jar:1.3.8]

at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) ~[rxjava-1.3.8.jar:1.3.8]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值