Откат Hystrix Javanica не работает в Spring Cloud 1.0
Я создал очень простой пример короткого замыкания Hystrix на основе примера весеннего облака для запуска @spencergibb feign-eureka. Сначала я думал, что не могу заставить по умолчанию вызывать fallbackMethod по умолчанию для hystrix javanica из-за симуляции... теперь, удаляя симуляцию, по умолчанию резервный метод hystrix по-прежнему не улавливает исключения.
pom.xml
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
<version>1.0.0.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
:
</dependencies>
Основной файл:
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@RestController
public class HelloClientApplication {
@Autowired
HelloClientComponent helloClientComponent;
@RequestMapping("/")
public String hello() {
return helloClientComponent.makeMultipleCalls();
}
public static void main(String[] args) {
SpringApplication.run(HelloClientApplication.class, args);
}
}
HelloClientComponent.java (создан, потому что я знаю, что javanica ожидает, что он находится внутри управляемого компонента или службы Spring):
@Component
public class HelloClientComponent {
@Autowired
RestTemplate restTemplate;
public String makeMultipleCalls() {
int cnt=20;
StringBuilder sb = new StringBuilder();
while (cnt-- > 0) {
String response = theServerRequestRoot();
sb.append(response).append(" ");
}
return sb.toString();
}
public String theServersRequestRootFallback() {
System.out.println("BOMB!!!!!!");
return "BOMB!!!!!!";
}
@HystrixCommand(fallbackMethod = "theServersRequestRootFallback", commandKey = "callToServers")
public String theServerRequestRoot() {
ResponseEntity<String> result = restTemplate.getForEntity("http://HelloServer", String.class);
System.out.println(result.getBody());
return result.getBody();
}
}
Я запускаю 2 сервера, один из которых всегда срабатывает и отвечает, а другой не работает 30% времени с ошибкой 500. Когда я скручиваю этот клиент (в '/'), все идет нормально для вызовов без принудительного сбоя. Круглая обработка работает также хорошо. Когда второй сервер возвращает ошибку 500, fallbackMethod не вызывается, а curl в '/' заканчивается и возвращается с ошибкой.
Обновление с решением в соответствии с предложениями Спенсера и Дейва. Изменить на следующее:
Основной файл приложения:
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@RestController
public class HelloClientApplication {
@Autowired
HelloClientComponent helloClientComponent;
@RequestMapping("/")
public String hello() {
int cnt=20;
StringBuilder sb = new StringBuilder();
while (cnt-- > 0) {
String response = helloClientComponent.theServerRequestRoot(); // call directly to @Component in order for @HystrixCommand to intercept via AOP
sb.append(response).append(" ");
}
return sb.toString();
}
public static void main(String[] args) {
SpringApplication.run(HelloClientApplication.class, args);
}
}
HelloClientComponent.java:
@Component
public class HelloClientComponent {
@Autowired
RestTemplate restTemplate;
public String theServersRequestRootFallback() {
System.out.println("BOMB!!!!!!");
return "BOMB!!!!!!";
}
@HystrixCommand(fallbackMethod = "theServersRequestRootFallback", commandKey = "callToServers")
public String theServerRequestRoot() {
ResponseEntity<String> result = restTemplate.getForEntity("http://HelloServer", String.class);
System.out.println(result.getBody());
return result.getBody();
}
}
1 ответ
@HystrixCommand
работает только потому, что Spring создает прокси для вызова этого метода. Если вы вызываете метод из прокси-сервера, он не проходит через перехватчик. Вам нужно позвонить @HystrixCommand
От другого @Component
(или используйте AspectJ).