Spring Cloud 学习系列:(八
@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?nam 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 e=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<FeignClientServiceHi> {
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]
评论