Я пытаюсь разобраться с работой Feign клиента в Java и вызываю Откат в случае ошибки, и я столкнулся с некоторыми трудностями. Я написал самый простой пример, чтобы понять, как это работает, но, похоже, я запутался. Пожалуйста, помогите мне понять, где моя ошибка.
Я также разместил этот пример на github, чтобы сделать его более удобным: https://github.com/ksereda/feign-fallback-example
Клиент вызывает service-one через Feign и получает строку «Получить строку из SERVICE-ONE».
Клиент также вызывает service-two через Feign и получает строку "Get String from SERVICE-TWO".
Условие: в случае недоступности service-two , клиент должен вызывать класс Fallback, в котором указывается вызов service-three и вместо "Get String from SERVICE-TWO" , клиент должен получить "Получить строку из сервис-три" из сервис-три.
Сервис-два и service-three одинаковы, возвращаются только разные строки.
Код службы один:
@RestController
@RequestMapping("/")
public class OneController {
Logger logger = Logger.getLogger(OneController.class.getName());
@GetMapping("/getStringFromServiceOne")
public String getString() {
logger.info("Get String from SERVICE-ONE");
return "Get String from SERVICE-ONE";
}
}
Servi код ce-two:
@RestController
@RequestMapping("/")
public class TwoController {
Logger logger = Logger.getLogger(TwoController.class.getName());
@GetMapping("/getStringFromServiceTwo")
public String getString() {
logger.info("Get String from SERVICE-TWO");
return "Get String from SERVICE-TWO";
}
}
Код услуги три:
@RestController
@RequestMapping("/")
public class ThreeController {
Logger logger = Logger.getLogger(ThreeController.class.getName());
@GetMapping("/getStringFromServiceThree")
public String getString() {
logger.info("Get String from SERVICE-THREE");
return "Get String from SERVICE-THREE";
}
}
Код клиента:
Контроллер:
@RestController
@RequestMapping("/")
public class ClientController {
Logger logger = Logger.getLogger(ClientController.class.getName());
@Autowired
private ServiceOneFeignClient serviceOneFeignClient;
@Autowired
private ServiceTwoFeignClient serviceTwoFeignClient;
@RequestMapping(path = "/getDataFromServiceOneByFeign")
public String getDataFromServiceOne() {
String result = serviceOneFeignClient.getString();
logger.info("Calling through Feign Client");
return result;
}
@RequestMapping(path = "/getDataFromServiceTwoByFeign")
public String getDataFromServiceTwo() {
String result = serviceTwoFeignClient.getString();
logger.info("Calling through Feign Client");
return result;
}
}
Feign 1:
@FeignClient(name = "service-one", url = "http://localhost:8081/")
public interface ServiceOneFeignClient {
@GetMapping("/getStringFromServiceOne")
String getString();
}
и Feign 2:
@FeignClient(name = "service-two", url = "http://localhost:8082/", fallback = Fallback.class)
public interface ServiceTwoFeignClient {
@GetMapping("/getStringFromServiceTwo")
String getString();
}
и Feign 3:
@FeignClient(name = "service-three", url = "http://localhost:8083/")
public interface ServiceThreeFeignClient {
@GetMapping("/getStringFromServiceThree")
String getString();
}
Основной класс:
@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
@EnableHystrix
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
и файл application.yml
server:
port: 8070
feign:
hystrix:
enabled: true
и здесь я создал класс Fallback
@Component
public class Fallback implements ServiceThreeFeignClient {
@Override
public String getString() {
System.out.println("Called MOVIE-SERVICE with Fallback class!");
return new String("FALLBACK STRING");
}
}
Здесь я хочу позвонить service-three , если service-two недоступен.
Но когда я запускаю свое приложение, я сразу получаю ошибка:
Caused by: java.lang.IllegalStateException: Incompatible fallback instance. Fallback/fallbackFactory of type class com.example.client.service.Fallback is not assignable to interface com.example.client.service.ServiceTwoFeignClient for feign client service-two
at org.springframework.cloud.openfeign.HystrixTargeter.getFromContext(HystrixTargeter.java:86) ~[spring-cloud-openfeign-core-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.cloud.openfeign.HystrixTargeter.targetWithFallback(HystrixTargeter.java:70) ~[spring-cloud-openfeign-core-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.cloud.openfeign.HystrixTargeter.target(HystrixTargeter.java:46) ~[spring-cloud-openfeign-core-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.cloud.openfeign.FeignClientFactoryBean.getTarget(FeignClientFactoryBean.java:284) ~[spring-cloud-openfeign-core-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.cloud.openfeign.FeignClientFactoryBean.getObject(FeignClientFactoryBean.java:247) ~[spring-cloud-openfeign-core-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171) ~[spring-beans-5.1.7.RELEASE.jar:5.1.7.RELEASE]
Я понимаю, что он пишет: я должен указать
implements ServiceTwoFeignClient
вместо
implements ServiceThreeFeignClient
, но я хочу вызвать службу три, если служба два недоступен.
Я не понимаю, как это сделать. Буду благодарен за вашу помощь. спасибо