Feign

- Feign Spring Cloud

什么是Feign

特点

工作原理

(1)接口定义

(2)动态代理

(3)请求处理

(4)集成 Ribbon 和 Hystrix

Feign 的配置

(1)基本配置

@FeignClient(name = "service-name", url = "http://localhost:8080")
public interface MyFeignClient {
    @GetMapping("/endpoint")
    String getResponse();
}

(2)负载均衡

* Feign 默认集成了 Ribbon,无需额外配置

* 可以通过配置文件自定义 Ribbon 的负载均衡策略:

service-name:
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

(3)熔断和降级

@FeignClient(name = "service-name", fallback = MyFeignClientFallback.class)
public interface MyFeignClient {
    @GetMapping("/endpoint")
    String getResponse();
}

@Component
public class MyFeignClientFallback implements MyFeignClient {
    @Override
    public String getResponse() {
        return "Fallback response";
    }
}

(4)自定义配置

@Configuration
public class FeignConfig {
    @Bean
    public Encoder feignEncoder() {
        return new JacksonEncoder();
    }

    @Bean
    public Decoder feignDecoder() {
        return new JacksonDecoder();
    }

    @Bean
    public RequestInterceptor feignRequestInterceptor() {
        return template -> template.header("Authorization", "Bearer token");
    }
}

Feign 的使用场景

(1)微服务调用

(2)负载均衡

(3)熔断和降级

(4)自定义 HTTP 客户端

Feign 的底层原理

(1)动态代理

(2)请求模版

(3)编码器和解码器

(4)拦截器

graph TD A[客户端调用 Feign 接口方法] --> B[ReflectiveFeign.newInstance 创建动态代理] B --> C[InvocationHandler.invoke 拦截方法调用] C --> D[SynchronousMethodHandler.invoke 处理请求] D --> E[RequestTemplate.Factory.create 生成请求模板] E --> F[RequestInterceptor.apply 应用拦截器] F --> G[Encoder.encode 编码请求体] G --> H[LoadBalancerFeignClient.execute 选择服务实例] H --> I[Client.execute 发送 HTTP 请求] I --> J[Decoder.decode 解析响应] J --> K[返回结果给客户端]