Feign遇到的坑

在使用Feign进行服务调用时遇到了404状态码问题。错误信息显示为'status 404 reading EmployeeServiceINF#findAll()',并且日志中提到路径'/find/all'未找到。问题可能出在API路径与服务提供者的实际路径不匹配,或者是负载均衡配置问题。

负载均衡遇到的问题   路径错误(api路径与服务提供者提供服务的路径对应不起来)

status 404 reading EmployeeServiceINF#findAll()

ServerList:org.springframework.cloud.netflix.ribbon.eureka.DomainExtractingServerList@4d2c12ad
2019-02-26 15:01:40.202 INFO  [PollingServerListUpdater-0] com.netflix.config.ChainedDynamicProperty - Flipping property: EMPLOYEE-PROVIDER.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647
2019-02-26 15:01:46.333 ERROR [http-nio-8082-exec-1] o.a.c.c.C.[.[localhost].[/].[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is feign.FeignException: status 404 reading EmployeeServiceINF#findAll(); content:
{"timestamp":"Feb 26, 2019 3:01:46 PM","status":404,"error":"Not Found","message":"No message available","path":"/find/all"}] with root cause
feign.FeignException: status 404 reading EmployeeServiceINF#findAll(); content:
{"timestamp":"Feb 26, 2019 3:01:46 PM","status":404,"error":"Not Found","message":"No message available","path":"/find/all"}
    at feign.FeignException.errorStatus(FeignException.java:62)
    at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:91)
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:138)
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76)
    at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
    at com.sun.proxy.$Proxy110.findAll(Unknown Source)
    at lcxy.springcloud.micorserviceconsumer8082.micorserviceconsumerfeign8082.micorserviceconsumer8081.controller.EmployeeConsumerController.findAll(EmployeeConsumerController.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:635)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1457)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

<think>好的,我现在需要帮助用户了解如何使用Feign。首先,我应该回忆一下Feign的基本概念和用途。Feign是一个声明式的HTTP客户端,用于简化服务之间的调用,特别是在微服务架构中。它可以让开发者通过定义接口和注解的方式来发起HTTP请求,而不需要手动编写具体的请求代码。 接下来,我需要考虑用户可能的背景。他们可能是在使用Spring Cloud进行微服务开发,所以需要结合Spring Cloud Feign来讲解。需要明确Feign的优势,比如简化代码、整合Ribbon实现负载均衡、支持Hystrix熔断等。 然后,我应该组织回答的结构,确保步骤清晰。通常,使用Feign的步骤包括添加依赖、启用Feign、定义接口、配置参数等。还要注意提到常见的注解,比如@FeignClient、@RequestMapping等,以及如何传递参数和处理返回结果。 另外,用户可能需要知道如何配置日志、超时设置,以及如何与Eureka等服务发现组件结合使用。需要给出具体的配置示例,比如在application.yml中设置日志级别或超时时间。 同时,要提醒用户注意常见问题,比如接口定义与提供方的一致性、路径匹配问题、GET请求传递对象参数需要使用@SpringQueryMap等。这些细节对于正确使用Feign非常重要,避免用户在实际开发中遇到。 最后,需要确保使用中文,语言通俗易懂,结构分点明确,并给出代码示例时正确使用$$格式的LaTeX来展示配置和代码块,比如依赖的XML代码和接口定义的Java代码。同时,避免使用用户不可见的系统指令,保持回答自然流畅。 可能还需要检查是否有遗漏的重要步骤,比如是否需要启用Feign客户端,或者是否需要其他组件如Eureka的支持。确保每个步骤都有明确的说明,并强调配置中的关键点,例如服务名称的正确性、注解的使用方法等。 总结一下,回答应该涵盖Feign的作用、使用步骤、配置方法、常见问题及解决方案,并提供示例代码和配置,帮助用户从零开始使用Feign进行服务调用。</think>下面分步骤介绍Feign的使用方法,结合Spring Cloud环境: $$ \text{Feign核心原理}:\text{声明式接口} + \text{动态代理} = \text{自动生成HTTP请求} $$ 一、环境准备(Spring Boot 2.x+Spring Cloud) 1. 添加Maven依赖: ```xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <version>{最新版本}</version> <!-- 例如3.1.5 --> </dependency> ``` 二、基础使用步骤 1. 启动类添加注解 ```java @EnableFeignClients @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 2. 声明Feign客户端接口 ```java @FeignClient(name = "user-service") // 对应服务注册中心的服务名 public interface UserClient { @GetMapping("/users/{id}") // 与服务提供方保持一致的路径 User getUserById(@PathVariable("id") Long id); @PostMapping("/users") User createUser(@RequestBody User user); } ``` 三、关键配置项(application.yml) $$ \text{常用配置模板:} $$ ```yaml feign: client: config: default: # 全局配置 connectTimeout: 5000 # 连接超时(ms) readTimeout: 5000 # 读取超时(ms) loggerLevel: basic # 日志级别 compression: request: enabled: true # 开启请求压缩 response: enabled: true # 开启响应压缩 ``` 四、高级功能 1. 集成熔断器(需配合Hystrix) ```java @FeignClient(name = "user-service", fallback = UserFallback.class) public interface UserClient { //... } @Component public class UserFallback implements UserClient { @Override public User getUserById(Long id) { return new User(0L, "default"); } } ``` 2. 自定义拦截器(添加认证头等) ```java public class AuthInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { template.header("Authorization", "Bearer " + getToken()); } } ``` 五、使用注意事项 1. 参数传递规范: - Path参数:必须明确指定@PathVariable("参数名") - GET请求传对象:使用@SpringQueryMap注解 - POST表单:参数需加@RequestParam 2. 常见问题排查: - 检查服务名是否注册到注册中心 - 确认接口路径与目标服务完全一致 - 使用@FeignClient(contextId)解决相同服务名冲突 六、最佳实践建议 1. 推荐将Feign客户端接口单独存放在client模块中 2. 为每个Feign客户端配置独立的超时时间 3. 结合Swagger生成接口文档(需添加springfox-swagger2依赖) 示例调用代码: ```java @RestController public class UserController { private final UserClient userClient; public UserController(UserClient userClient) { this.userClient = userClient; } @GetMapping("/proxy/users/{id}") public User getProxyUser(@PathVariable Long id) { return userClient.getUserById(id); } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值