Java Feign клиента Fallback - не может вызвать fallback - PullRequest
1 голос
/ 14 апреля 2020

Я пытаюсь разобраться с работой 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

, но я хочу вызвать службу три, если служба два недоступен.

Я не понимаю, как это сделать. Буду благодарен за вашу помощь. спасибо

1 Ответ

0 голосов
/ 14 апреля 2020

Я решил это в своем классе Fallback:

@Component
public class Fallback implements ServiceTwoFeignClient {

    @Autowired
    private ServiceThreeFeignClient serviceThreeFeignClient;

    @Override
    public String getString() {
        return serviceThreeFeignClient.getString();
    }

}
...