zoukankan      html  css  js  c++  java
  • Spring Cloud Netflix子模块综合整理-Feign

     声明性REST客户端:Feign

    Feign是一个声明性的Web服务客户端。 它使编写Web服务客户端变得更容易。 要使用Feign需要创建一个接口并添加相应的注释。 它具有可插入的注释支持,包括Feign注释和JAX-RS注释。 Feign还支持可插拔编码器和解码器。 Spring Cloud增加了对Spring MVC注释的支持,并使用了Spring Web中默认使用的相同HttpMessageConverters【重点】。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。

    如何添加Feign

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

    应用实例

      springboot启动类

    @Configuration
    @ComponentScan
    @EnableAutoConfiguration
    @EnableEurekaClient
    //启动feign
    @EnableFeignClients
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    
    }

    调用接口

    //stores 被调用方无名名
    @FeignClient("stores")
    public interface StoreClient {
        //添加调用路径,具体需要调用那个方法
        @RequestMapping(method = RequestMethod.GET, value = "/stores")
        List<Store> getStores();
    
        @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
        Store update(@PathVariable("storeId") Long storeId, Store store);
    }

    在上面@FeignClient注解中,(“stores”)是一个任意客户端名称,用于创建Ribbon负载均衡器, 您还可以使用url属性指定URL(绝对值或仅指定主机名)。 应用程序上下文中bean的名称是接口的完全限定名称。 要指定自己的别名值,可以使用限定符@FeignClient注释的值。

    上面的Ribbon客户端将要发现“stores”服务的物理地址。 如果您的应用程序是Eureka客户端,那么它将解析Eureka服务注册表中的服务(从注册中心获取具体的"stores"服务调用地址)。 如果您不想使用Eureka,则只需在外部配置中配置服务器列表即可

    覆盖默认的Feign配置

    Spring Cloud的Feign支持的核心概念是指定客户端的概念。 每个feign客户端都是一组组件的一部分,这些组件一起工作以按需联系远程服务器,并且该集合具有一个名称,您可以使用@FeignClient注释将其作为应用程序开发人员提供。 Spring Cloud根据需要为每个命名客户端创建一个新的集合作为ApplicationContext FeignClientsConfiguration。 这包含(除其他外)feign.Decoder,feign.Encoder和feign.Contract。【Feign的默认配置是FeignClientsConfiguration,该类定义了Feign默认使用的编码器、解码器、所有使用的契约】

    Spring Cloud允许您通过使用@FeignClient的configuration属性自定义Feign的配置,自定义的优先级会比默认的FeignClientsConfiguration优先极高。

    例如:

    //FooConfiguration 自定义配置
    @FeignClient(name = "stores", configuration = FooConfiguration.class)
    public interface StoreClient {
      //..
    }

    注意:

    FooConfiguration不需要使用@Configuration注释。 但是,如果是,则注意将其从任何包含此配置的@ComponentScan中排除,因为该配置会被所有@FeignClient共享。 这可以通过将它放在来自任何@ComponentScan或@SpringBootApplication的单独的非重叠包中来避免,或者可以在@ComponentScan中明确排除它

    在@FeignClient中推荐使用name属性,serviceId属性已经过期不推荐了。

    以前可能使用url属性,写具体调用服务的物理地址,现在只需写name属性填写具体的服务名称,将会自动解析。

    @FeignClient注解中还支持name和url属性值得占位符。

    @FeignClient(name = "${feign.name}", url = "${feign.url}")
    public interface StoreClient {
    //..
    }

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

    • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder ) //相应编码
    • Encoder feignEncoder: SpringEncoder //采用的编码
    • Logger feignLogger: Slf4jLogger   //采用的日志
    • Contract feignContract: SpringMvcContract  //默认请求调用方式采用springmvc注解方式 即就是@RequestMapping
    • Feign.Builder feignBuilder: HystrixFeign.Builder
    • Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient , otherwise the default feign client is used  //如果没有禁用ribbon,服务调用将通过负载均衡调用

    创建其中一种类型的bean并将其放在@FeignClient配置中(例如下面的FooConfiguration)允许您覆盖默认。

    @Configuration
    public class FooConfiguration {
      @Bean
      public Contract feignContract() {
       return new feign.Contract.Default();
      }
      @Bean
     public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
       return new BasicAuthRequestInterceptor("user", "password");
      }
    }

    上面讲使用feign原生的默认契约去掉springmvc,这样就可以使用feign自带的注解了。而且配置基于用户认证,只有通过认证才能调用。

    @FeignClient相关配置还可通过配置文件配置

    application.yml

    如果您更喜欢使用配置属性来配置所有@FeignClient,则可以使用默认的Feign name创建配置属性。

    如果同时创建@Configuration bean和属性配置文件,则配置属性优先级高。 它将覆盖@Configuration值。 但是,如果要将优先级更改为@Configuration,则可以将feign.client.default-to-properties更改为false。

    注意:

    如果你需要使用ThreadLocal绑定变量,需要进行如下设置。

    在feign调用中禁用断路器和膝盖修改线程隔离策略。

    在feign用使用Hystrix

    如果Hystrix在类路径上并且feign.hystrix.enabled = true,则Feign将使用断路器包装所有方法(这是一个全局的配置).

    如果不想设置全局的关闭hystrix,而只是针对某个服务关闭Hystrix需要如下配置:

     @Configuration
    public class FooConfiguration {
      @Bean
      @Scope("prototype")
     public Feign.Builder feignBuilder() {
      return Feign.builder();
     }
    }

    Feign服务降级配置

    Hystrix支持回退的概念:在电路打开或出现错误时执行的默认代码路径。 要为给定的@FeignClient启用回退,请将fallback属性设置为实现回退的类名。 您还需要将实现声明为Spring bean。

    实例代码:

    @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("fallback");
        }
    }

    如果需要访问导致回退触发器的原因,可以使用@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 HystrixClient() {
                @Override
                public Hello iFailSometimes() {
                    return new Hello("fallback; reason was: " + cause.getMessage());
                }
            };
        }
    }

    Feign and @Primary

    在Feign使用Hystrix做服务降级时,ApplicationContext中有多个相同类型的bean。 这将导致@Autowired无法工作,因为没有一个bean或一个标记为primary的bean。 为了解决这个问题,Spring Cloud Netflix将所有Feign实例标记为@Primary,因此Spring Framework将知道要注入哪个bean。 在某些情况下,这可能并不理想。 要关闭此行为,请将@FeignClient的主要属性设置为false。

    @FeignClient(name = "hello", primary = false)
    public interface HelloClient {
     // methods here
    }

    Feign对继承的支持

    Feign支持单接口继承,这样可以将常用的进行接口封装。

    列如:

    UserService.java

    public interface UserService {
    
        @RequestMapping(method = RequestMethod.GET, value ="/users/{id}")
        User getUser(@PathVariable("id") long id);
    }

    UserResource.java

    @RestController
    public class UserResource implements UserService {
    
    }

    UserClient.java

    package project.user;
    
    @FeignClient("users")
    public interface UserClient extends UserService {
    
    }

    通常不建议在服务器和客户端之间共享接口因为增强了耦合,并且实际上也不能以其当前形式使用Spring MVC(方法参数映射不会被继承)

    Feign请求和响应压缩

    您可以考虑为您的Feign请求启用请求或响应GZIP压缩。 您可以通过启用以下属性之一来执行此操作:

    feign.compression.request.enabled=true
    feign.compression.response.enabled=true

    Feign请求压缩为您提供类似于您为Web服务器设置的设置:

    feign.compression.request.enabled=true
    feign.compression.request.mime-types=text/xml,application/xml,application/json
    feign.compression.request.min-request-size=2048

    通过这些属性,您可以选择压缩介质类型和最小请求阈值长度

    Feign 日志

    为每个创建的Feign客户端创建一个日志记录器。 默认情况下,日志记录器的名称是用于创建Feign客户端的接口的完整类名。 Feign日志记录仅响应DEBUG级别。

    application.yml.

    logging.level.project.user.UserClient: DEBUG

    您可以为每个客户端配置的Logger.Level对象告诉Feign记录日志级别,支持四种日志级别:

    • NONE , No logging (DEFAULT).// 默认不打印日志
    • BASIC , Log only the request method and URL and the response status code and execution time.//仅记录请求方法和URL以及响应状态代码和执行时间
    • HEADERS , Log the basic information along with request and response headers.//记录基本信息以及请求和响应标头
    • FULL , Log the headers, body, and metadata for both requests and responses.//记录请求和响应的标题,正文和元数据。

    例如配置打印所有日志,设置Logger.Level 为FULL

    @Configuration
    public class FooConfiguration {
        @Bean
        Logger.Level feignLoggerLevel() {
            return Logger.Level.FULL;
        }
    }

     微信公众号

     

     

  • 相关阅读:
    C
    A
    L
    G
    关于html()、val()、text()
    EL表达式
    JSON书写格式示例
    Servlet获取项目名的方法
    修改完Servlet后不用重启项目的设置方法
    浮动
  • 原文地址:https://www.cnblogs.com/niugang0920/p/12190305.html
Copyright © 2011-2022 走看看