Java Feign 客户端后备 - 无法调用后备
Posted
技术标签:
【中文标题】Java Feign 客户端后备 - 无法调用后备【英文标题】:Java Feign client Fallback - can't call fallback 【发布时间】:2020-07-27 05:54:27 【问题描述】:我正在尝试理解Feign客户端在Java中的工作,并在出现错误时调用Fallback,我遇到了一些困难。 我写了一个最简单的例子来理解它是如何工作的,但似乎我很困惑。 请帮助我了解我的错误在哪里。
我还在 github 上发布了这个示例,以使其更方便: https://github.com/ksereda/feign-fallback-example
client通过Feign调用service-one,收到字符串“Get String from SERVICE-ONE”。
сlient也通过Feign调用service-two,得到字符串“Get String from SERVICE-TWO”。
先决条件: 在 service-two 不可用的情况下,client 必须调用指示对 service-three 的调用的 Fallback 类,而不是“从 SERVICE-TWO 获取字符串”,客户端应该从 service-3 获取“从 SERVICE-THREE 获取字符串”。
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";
服务二代码:
@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;
假装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-two 不可用,我想在这里调用 service-three。
但是当我启动我的应用程序时,我立即得到一个错误:
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】:我是在我的 Fallback 课程中决定的:
@Component
public class Fallback implements ServiceTwoFeignClient
@Autowired
private ServiceThreeFeignClient serviceThreeFeignClient;
@Override
public String getString()
return serviceThreeFeignClient.getString();
【讨论】:
以上是关于Java Feign 客户端后备 - 无法调用后备的主要内容,如果未能解决你的问题,请参考以下文章