SpringCloud 学习笔记系列02--Feign 客户端

Feign 声明性REST客户端

  • Feign是一个声明式的WEB服务客户端。
  • Feign具有可插入注释支持:
    • Feign注释
    • JAX-RS注释
    • 可插拔编码器和解码器
  • SpringCloud 集成Ribbon和Eureka以在使用Feign时提供负载均衡的http客户端
引入Feign
  • 开启Feign客户端注解:@EnableFeignClients

  • 开启Feign客户端

    •  @Configuration
       @ComponentScan
       @EnableAutoConfiguration
       @EnableEurekaClient
       @EnableFeignClients
       public class Application {
      
           public static void main(String[] args) {
               SpringApplication.run(Application.class, args);
           }
      
       }
      
      
  • 远程调用方式:

    •  @FeignClient("ORDER-SERVER")
       public interface StoreClient {
           @RequestMapping(method = RequestMethod.GET, value = "/orders")
           List<Order> getOrders();
      
           @RequestMapping(method = RequestMethod.POST, value = "/orders/{orderId}", consumes = "application/json")
           Store update(@PathVariable("orderId") String orderId, Order order);
       }
      
  • 使用Feign core提供的@RequestLine 注解

    •     @RequestLine("GET /api/documents/{contentType}")
          @Headers("Accept {contentType}")
          String getDocumentByType(@Param("contentType") String type);
      
    • 注意:
      • 启动报错: Method getLinksForTrack not annotated with HTTP method type (ex. GET, POST)
      • 原因: feign 默认使用的是spring mvc 注解(就是RequestMapping 之类的), 所以需要配置feign的Configuration
      • 解决:
      •   @Configuration
          public class MyFeignConfiguration {
              @Bean
              public Contract feignConfiguration(){
                  return new feign.Contract.Default();
              }
          }
        
      • 注意:网上说如果命名为FeignConfiguration可能会导致启动失败,原因是springcloud有一个FeignConfiguration类
      • 默认情况下,@RequestLine和@QueryMap模板不编码斜杠/字符。要更改此行为,请将@RequestLine上的decodeSlash属性设置为false
  • Feign 接口注释

    • AnnotationInterface TargetUsage
      @RequestLineMethod为请求定义HttpMethod和UriTemplate。表达式,用花括号{表达式}包装的值使用它们对应的@Param带注释的参数进行解析。
      @ParamParameter根据名称定义模板变量,其值将用于解析相应的模板“表达式”。
      @HeadersMethod, Type定义了一个“HeaderTemplate”;“UriTemplate”的变体。它使用“@Param”注释值来解析相应的“表达式”。当用于“类型”时,模板将应用于每个请求。当在“方法”上使用时,模板将只应用于带注释的方法。
      @QueryMapParameter定义名称-值对(或POJO)的“映射”,以展开为查询字符串。
      @HeaderMapParameter定义名称-值对的“映射”,以展开为“Http Header”
      @BodyMethod定义一个“模板”,类似于“UriTemplate”和“HeaderTemplate”,它使用“@Param”注释值来解析相应的“表达式”
配置Feign
  • Spring Cloud 根据需要,可以使用FeignClientConfiguration为每个已命名的客户端创建一个新的ApplicationContext。

    • 其中包含feign.Decoder,feign.Encoder 和feign.Contract
  • 具体配置

    • @FeignClient(name=“ORDER-SERVER”,configuration = FeignConfiguration.class)
  • 注意:

    • FeignConfiguration不需要使用@Configuration注释。
    • 如果使用,则需要将其从任何@ComponentScan中排除
      • 因为feign.Decoder,feign.Encoder,feign.Contract的默认来源
    • 指定时。这可以通过将其放置在任何@ComponentScan或@SpringBootApplication的单独的不重叠的包中,或者可以在@ComponentScan中明确排除。
  • 支持占位符:

    • @FeignClient(name = “ f e i g n . n a m e &quot; , u r l = &quot; {feign.name}&quot;, url = &quot; feign.name",url="{feign.url}”)
  • Decoder: feignDecoder: ResponseEntityDecoder(其中包含SpringDecoder)

  • Encoder:feignEncoder:SpringEncoder

  • Logger:feignLogger: Slf4jLogger

  • Contract: feignContract: SpringMvcContract

  • Feign.Builder: feignBuilder: HystrixFeign.Builder

  • Client: feignClient: 如果Ribbon启用,则为LoadBalancerFeignClient,否则将使用默认的feign客户端

  • feign.okhttp.enabled: true或feign.httpclient.enabled: true

    • 将他们放在类路径上来使用OkHttpClient和ApacheHttpClient feign客户端
  • 代码示例

    •   @Configuration
        public class FeignConfiguration {
            @Bean
            public Contract feignContract() {
                return new feign.Contract.Default();
            }
      
            @Bean
            public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
                return new BasicAuthRequestInterceptor("user", "password");
            }
        }
      
    • 这将SpringMvcContract替换为feign.Contract.Default,并将RequestInterceptor添加到RequestInterceptor的集合中。
Feign Hystrix
  • 开启熔断器:
    • feign.hystrix.enabled: true
  • Feign Hystrix Fallbacks
    • Hystrix支持回退的概念:当执行断路或传错误时执行的默认代码路径
    •   @FeignClient(name = "hello", fallback = HystrixClientFallback.class)
        protected interface HystrixClient {
            @RequestMapping(method = RequestMethod.GET, value = "/hello")
            Hello iFailSometimes();
        }
      
        static class HystrixClientFallback implements HystrixClient {
            @Override
            public Hello iFailSometimes() {
                return new Hello("当前并发太高,请稍后再试!");
            }
        }
      
    • 如果需要方位导致回退的触发原因,可以使用@FeignClient内的fallbackFactory属性
      •   @FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
          protected interface HystrixClient {
          	@RequestMapping(method = RequestMethod.GET, value = "/hello")
          	Hello iFailSometimes();
          }
        
          @Component
          static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
          	@Override
          	public HystrixClient create(Throwable cause) {
          		return new HystrixClientWithFallBackFactory() {
          			@Override
          			public Hello iFailSometimes() {
          				return new Hello("fallback; reason was: " + cause.getMessage());
          			}
          		};
          	}
          }
        
    • 在Feign中执行回退以及Hystrix回退的工作方式存在局限性。当前返回com.netflix.hystrix.HystrixCommand和rx.Observable的方法目前不支持回退。
Feign 和 @Primary
  • 当使用Feign与Hystrix回退时,在同一类型的ApplicationContext中有多个bean。
    这将导致@Autowired不起作用,因为没有一个bean,或者标记为主。要解决这个问题,
    Spring Cloud Netflix将所有Feign实例标记为@Primary,所以Spring Framework
    将知道要注入哪个bean。在某些情况下,这可能是不可取的。要关闭此行为,
    将@FeignClient的primary属性设置为false。

Ribbon 配置

  • 常用application.yml配置
    •   # 设置连接超时时间
        ribbon.ConnectTimeout=600
        # 设置读取超时时间
        ribbon.ReadTimeout=6000
        # 对所有操作请求都进行重试
        ribbon.OkToRetryOnAllOperations=true
        # 切换实例的重试次数
        ribbon.MaxAutoRetriesNextServer=2
        # 对当前实例的重试次数
        ribbon.MaxAutoRetries=1
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值