一、概述
OpenFeign是springcloud在Feign的基础上支持了SpringMVC的注解,整合了hystrix,同时,可以和Eureka和ribbon配合使用,如@RequestMapping等等。OpenFeign的@FeignClient可以解析SpringMVC的@RequestMapping注解下的接口,并通过动态代理的方式产生实现类,实现类中做负载均衡并调用其他服务。
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 }
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 多克; 官方旗舰店:首页-Doker 多克官方旗舰店 全品8.5折优惠,购前请和店小二说明来自阿里云!!!