Springcloud OpenFeign 详解
  K7LqrGr7LV69 2023年11月02日 64 0

 一、概述

OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,整合了hystrix,同时,可以和Eureka和ribbon配合使用,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

官网:Spring Cloud OpenFeign

OpenFegin中的两个常用注解

@FeignClient: 用于通知Feign组件对该接口进行代理(不需要编写接口实现),使用者可直接通过@Autowired注入。

@FeignClient标签的常用属性如下:

  • name/value:指定的是调用服务的微服务名称,如果项目使用了Ribbon,name属性会作为微服务的名称,用于服务发现
  • contextId:指定beanID
  • url: url指定调用服务的全路径,一般用于调试,可以手动指定@FeignClient调用的地址
  • decode404:当发生http 404错误时,如果该字段位true,会调用decoder进行解码,否则抛出FeignException
  • configuration: Feign配置类,可以自定义Feign的Encoder、Decoder、LogLevel、Contract
  • fallback: 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback指定的类必须实现@FeignClient标记的接口
  • fallbackFactory: 工厂类,用于生成fallback类示例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码
  • path: 定义当前FeignClient的统一前缀

@EnableFeignClients: Spring Cloud应用在启动时,Feign会扫描标有@FeignClient注解的接口,生成代理,并注册到Spring容器中。

二、Feign和openFeign有什么区别?

Feign

openFiegn

Feign是SpringCloud组件中一个轻量级RESTful的HTTP服务客户端,Feign内置了Ribbon,用来做客户端负载均衡,去调用服务注册中心的服务。Feign的使用方式是:使用Feign的注解定义接口,调用这个接口,就可以调用服务注册中心的服务

OpenFeign是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。

三、代码实现:

1、POM文件引入依赖:

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

2、添加注解@EnableFeignClients开启openFeign功能

@SpringBootApplication
@EnableFeignClients
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

3、 新建openFeign接口

新建一个openFeign接口,使用@FeignClient注解标注,如下

@FeignClient("stores")
public interface StoreClient {
    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    List<Store> getStores();

    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    Page<Store> getStores(Pageable pageable);

    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    Store update(@PathVariable("storeId") Long storeId, Store store);

    @RequestMapping(method = RequestMethod.DELETE, value = "/stores/{storeId:\\d+}")
    void delete(@PathVariable Long storeId);
}

3、openFeign如何传参

1. 传递JSON数据

如果是 POST 请求,而且是对象集合等参数,在Spring Boot 中通过@RequestBody标识入参

@PostMapping("createOrder")
public String createOrder(@RequestBody Order order ){
    System.out.println(order);
    
    return "ok";
}

2. POJO表单传参

Spring Cloud OpenFeign 提供了一个等效的注释,它 用于将 POJO 或 Map 参数注释为查询参数映射。@SpringQueryMap

Order createOrder(@SpringQueryMap Order order);

下图是官方给出的实例

// Params.java
public class Params {
    private String param1;
    private String param2;

    // [Getters and setters omitted for brevity]
}

以下假装客户端通过注释使用该类:Params@SpringQueryMap

@FeignClient("demo")
public interface DemoTemplate {

    @GetMapping(path = "/demo")
    String demoEndpoint(@SpringQueryMap Params params);
}

3.URL中携带参数

通过 URL 传参数,GET 请求,参数列表使用@PathVariable(“”)

服务提供者代码如下:

@RestController
@RequestMapping("/openfeign/orderprovider")
public class OpenFeignOrderProviderController {

    @GetMapping("/getOrder/{id}")
    public String getOrder(@PathVariable("id")Integer id){
        return "accept one msg id="+id;
}

consumer消费者openFeign接口如下:

@FeignClient(value = "openFeign-orderprovider")
public interface OpenFeignService {

    @GetMapping("/openfeign/orderprovider/getOrder/{id}")
    String getOrder(@PathVariable("id")Integer id);
}

4、超时如何处理

ReadTimeout: 值的是建立链接所用的时间,适用于网络状况正常的情况下, 两端链接所用的时间

ConectTimeout: 指的是建立链接后从服务器读取可用资源所用的时间

openFeign设置超时时间非常简单,只需要在配置文件中配置,如下:

feign:
  client:
    config:
      ## default 设置的全局超时时间,指定服务名称可以设置单个服务的超时时间
      default:
        connectTimeout: 1000
        readTimeout: 1000

5、Feign logging

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

openFeign的日志级别如下:

NONE:默认的,不显示任何日志;

BASIC:仅记录请求方法、URL、响应状态码及执行时间;

HEADERS:除了BASIC中定义的信息之外,还有请求和响应的头信息;

FULL:除了HEADERS中定义的信息之外,还有请求和响应的正文及元数据。

配置方式:

1. 配置文件application.yml:

logging.level.project.user.UserClient: DEBUG

2.自定义一个配置类,在其中设置日志级别

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

6、对@RefreshScope支持

如果启用了 Feign 客户端刷新,则使用以下命令创建每个 Feign 客户端:

  • feign.Request.Options作为刷新范围的 Bean。这意味着像connectTimeout and readTimeout 等属性可以针对任何 Feign 客户端实例刷新。
  • 在 下换行的网址org.springframework.cloud.openfeign.RefreshableUrl。这意味着 Feign 客户端的 URL(如果已定义)spring.cloud.openfeign.client.config.{feignName}.url 属性,可以针对任何 Feign 客户端实例刷新。

可以通过 刷新这些属性。POST /actuator/refresh

默认情况下,Feign 客户端中的刷新行为处于禁用状态。使用以下属性启用刷新行为:

spring.cloud.openfeign.client.refresh-enabled=true

7、假请求/响应压缩

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

spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.response.enabled=true

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

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

这些属性允许您选择压缩媒体类型和最小请求阈值长度。

8、Feign Spring Cloud CircuitBreaker Fallbacks

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

@FeignClient(name = "test", url = "http://localhost:${server.port}/", fallback = Fallback.class)
    protected interface TestClient {

        @RequestMapping(method = RequestMethod.GET, value = "/hello")
        Hello getHello();

        @RequestMapping(method = RequestMethod.GET, value = "/hellonotfound")
        String getException();

    }

    @Component
    static class Fallback implements TestClient {

        @Override
        public Hello getHello() {
            throw new NoFallbackAvailableException("Boom!", new RuntimeException());
        }

        @Override
        public String getException() {
            return "Fixed response";
        }

    }

如果需要访问导致回退触发的原因,可以在@FeignClient中使用fallbackFactory属性:

@FeignClient(name = "testClientWithFactory", url = "http://localhost:${server.port}/",
            fallbackFactory = TestFallbackFactory.class)
    protected interface TestClientWithFactory {

        @RequestMapping(method = RequestMethod.GET, value = "/hello")
        Hello getHello();

        @RequestMapping(method = RequestMethod.GET, value = "/hellonotfound")
        String getException();

    }

    @Component
    static class TestFallbackFactory implements FallbackFactory<FallbackWithFactory> {

        @Override
        public FallbackWithFactory create(Throwable cause) {
            return new FallbackWithFactory();
        }

    }

    static class FallbackWithFactory implements TestClientWithFactory {

        @Override
        public Hello getHello() {
            throw new NoFallbackAvailableException("Boom!", new RuntimeException());
        }

        @Override
        public String getException() {
            return "Fixed response";
        }

    }

9、Feign and @Primary

当将Feign与Spring Cloud CircuitBreaker回退一起使用时,ApplicationContext中存在多个相同类型的bean。这将导致@Autowired无法工作,因为没有确切的一个bean,或者一个被标记为primary。为了解决这个问题,Spring Cloud OpenFeign将所有Feign实例标记为@Primary,这样Spring Framework就会知道要注入哪个bean。在某些情况下,这可能是不可取的。若要关闭此行为,请将@FeignClient的主属性设置为false:

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

Springcloud OpenFeign 详解_客户端

10、Feign Caching

如果使用@EnableCaching annotation,则会创建并注册CachingCapability bean,以便您的Feign客户端在其接口上识别@Cache*annotations:

public interface DemoClient {

    @GetMapping("/demo/{filterParam}")
    @Cacheable(cacheNames = "demo-cache", key = "#keyParam")
    String demoEndpoint(String keyParam, @PathVariable String filterParam);
}

您也可以通过属性spring.cloud.openfacy.cache.enabled=false禁用该功能。



Doker 技术人的数码品牌!!!

文章下方有交流学习区!一起学习进步!也可以前往官网,加入官方微信交流群!!!
你的支持和鼓励是我创作的动力❗❗❗

官网:Doker 多克官方旗舰店首页-多克创新官方店-淘宝网 全品8.5折优惠,购前请和店小二说明来自《51cto》!!!




【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
K7LqrGr7LV69