spring cloud day03 【feign】

来源:互联网 发布:淘宝大件物流怎么设置 编辑:程序博客网 时间:2024/05/19 19:41

一、feign的概念

 Feign是一个声明式的Web服务客户端。这使得Web服务客户端的写入更加方便 要使用Feign创建一个界面并对其进行注释。它具有可插入注释支持,包括Feign注释和JAX-RS注释。Feign还支持可插拔编码器和解码器。Spring Cloud增加了对Spring MVC注释的支持,并使用Spring Web中默认使用的HttpMessageConverters。Spring Cloud集成Ribbon和Eureka以在使用Feign时提供负载均衡的http客户端。

下面我们通过一小段代码看看feign做了什么

使用feign调用服务端@Autowiredprivate UserFeignClient userFeignClient;@GetMapping("/movie/{id}")public User findById(@PathVariable Long id) {return userFeignClient.getById(id);}@FeignClient(name="zw-provider-user")public interface UserFeignClient {  @RequestMapping(method = RequestMethod.GET, value = "/simple/{id}")  User getById(@PathVariable("id") Long id);}

 通过上面我们发现feign取代了org.springframework.web.client.RestTemplate;调用服务端代码。是的这就是feign的作用。

二、使用feign

1、添加maven 依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-feign</artifactId></dependency>

2、启动类上加注解

@EnableFeignClients

3、客户端调用,如上面代码所示


三、自定义feign

1、要实现自定义feign,首先我们需要研究下feign的组成

Spring Cloud Netflix默认为feign(BeanType beanName:ClassName)提供以下bean:

  • Decoder feignDecoder:ResponseEntityDecoder(其中包含SpringDecoder

  • Encoder feignEncoder:SpringEncoder

  • Logger feignLogger:Slf4jLogger

  • Contract feignContract:SpringMvcContract

  • Feign.Builder feignBuilder:HystrixFeign.Builder

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

通过上面的配置我们知道feign默认采用的契约是springmvc,通过上面feign接口我们也发现是springmvc风格

2、下面我们通过自定义feign 采用feign自带的契约,实现代码如下

@Configurationpublic class CustomeCofiguration {/** * 配置自定义契约,默认契约是springmvc,因此在feignClient调用可以使用springmvc注解,当修改为feign契约时,不能够使用springmvc注解。 * @return */@Bean    public Contract feignContract() {        return new feign.Contract.Default();    }/** * 配置日志记录 * @return */  @Bean  Logger.Level feignLoggerLevel() {    return Logger.Level.FULL;  }}

我们定义了自己的契约,该如何调用它呢,调用方式如下

@FeignClient(name="zw-provider-user",configuration=CustomeCofiguration.class)public interface UserFeignCustomeClient { @RequestLine("GET /simple/{id}") User getById(@Param("id") Long id);}

我们发现当我们需要调用自定义的feign时,通过configuration=CustomeCofiguration.class这个配置,取代默认的feign。


3、当我们调用的接口是eureka时,我们需要自定义feign,设置授权bean,代码如下

@Configurationpublic class CustomeCofiguration2 {/** * 当配置的是eureka服务端的时候,要进行授权,通过通过一个客户端配置两个自定义feign,测试相互间有影响。 * @return */ @Bean    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {        return new BasicAuthRequestInterceptor("user", "123");    }}

三、feign注意事项,留下的坑

直接代码演示,不做解释了

  @RequestMapping(method = RequestMethod.GET, value = "/simple/{id}")  User getById(@PathVariable("id") Long id);// 两个坑:1. @GetMapping不支持   2. @PathVariable得设置value    @RequestMapping(method = RequestMethod.POST, value = "/user")  User getUser(@RequestBody User user);// post请求      // 该请求不会成功,只要参数是复杂对象,即使指定了是GET方法,feign依然会以POST方法进行发送请求。可能是我没找到相应的注解或使用方法错误。  @RequestMapping(value = "/get-user", method = RequestMethod.GET)  public User UserBug(User user);


2、客户端超时问题,因为默认hystrix只有一秒钟

可以通过下面方式,解决第一次超时问题

# 解决第一次请求报超时异常的方案:# hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000# 或者:# hystrix.command.default.execution.timeout.enabled: false# 或者:feign.hystrix.enabled: false ## 索性禁用feign的hystrix# 超时的issue:https://github.com/spring-cloud/spring-cloud-netflix/issues/768# 超时的解决方案: http://stackoverflow.com/questions/27375557/hystrix-command-fails-with-timed-out-and-no-fallback-available# hystrix配置: https://github.com/Netflix/Hystrix/wiki/Configuration#execution.isolation.thread.timeoutInMilliseconds