文档章节

[Spring Cloud] 4.6 Declarative REST Client:Feign

秋雨霏霏
 秋雨霏霏
发布于 2016/12/10 19:23
字数 2041
阅读 626
收藏 3
点赞 0
评论 0

4.6 Declarative REST Client: Feign

REST客户端:Feign

Feign是一个Web服务的客户端框架。它让Web服务的客户端开发变得更容易。 只需要使用Feign创建一个接口加上一个注解就行了。Feign和JAX-RS提供一整套插件化的注解配置方式。在Feign中还可以使用插件化的编码器和解码器。

Spring Cloud 还提供一个HttpMessageConverters,这样当使用Spring Web环境时,就可以支持Spring MVC。 在使用Feign时,Spring Cloud还可以整合Ribbon和Eureka,为http客户端提供负载均衡的能力。

4.6.1 How to Include Feign 如何引入Feign

在工程中引入Feign只需要引入依赖就行:group :org.springframework.cloud artifact id : spring-cloud-starter-feign。详情见Spring Cloud相关文档

例如:

@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableEurekaClient
@EnableFeignClients
public class Application {

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

}

StoreClient.java

@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。 在Spring容器中会使用全限定名作为这个Bean的名称。同样,可以通过name属性进行自定义。 在上例中,通过@Qualifier("storesFeignClient")就可以引用到这个Bean。 如果需要改变默认引用名称,可以在@FeignClient中配置qualifier属性。

Ribbon客户端将会查找"stores"服务的物理地址。 如果是一个Eureka客户端应用,那么将会自动注册到Eureka中。 如果不想使用Eureka,可以简单的配置一个服务列表,手动指定服务。

4.6.2 Overriding Feign Defaults 覆盖Feign默认配置

Spring Cloud 的 Feign有一个核心概念,那就是客户端命名。每一个Feign客户端都是集群中一组@FeignClient标记的可用服务区域中的一部分。

Spring Cloud会为每一个命名的Feign客户端中的FeignClientsConfiguration创建一个新的ApplicationContext。 这其中会包括一个feign.Decoder,一个feign.Encoder,以及一个feign.Contract

Spring Cloud运行开发者通过@FeignClient对Feign客户端进行完全的控制。例如:

@FeignClient(name = "stores", configuration = FooConfiguration.class)
public interface StoreClient {
    //..
}

在这个例子中,客户端使用一个自定义的FooConfiguration整合到FeignClientsConfiguration的配置过程。

警告:

需要确保FooConfiguration不会被@Configuration或者@ComponentScan扫描到,否则,就会被所有@FeignClient共享了(自动注入)。如果使用@ComponentScan或者@SpringBootApplication时,也需要避免FooConfiguration被自动扫描。

注意:

serviceId属性已经丢弃,不建议使用,改用name属性进行配置。

警告:

以前使用url属性时,不需要name。现在不行了,name必须指定。

nameurl属性时,可以使用占位符进行配置。例如:

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

Spring Cloud Netflix 默认会创建下列Bean

类型Bean名称类名备注
DecoderfeignDecoderResponseEntityDecoder包装了SpringDecoder
EncoderfeignEncoderSpringEncoder
LoggerfeignLoggerSlf4jLogger
ContractfeignContractSpringMvcContract
Feign.BuilderfeignBuilderHystrixFeign.Builder
ClientfeignClientLoadBalancerFeignClient如果启用Ribbon则是LoadBalancerFeignClient,否则使用Feign默认客户端

还可以通过feign.okhttp.enabled或者feign.httpclient.enabled来开启OkHttpClientApacheHttpClient,当然前提是classpath中必须有这些相关依赖。

默认情况下,Spring Cloud Netflix不会为Feign提供下列的Bean,但是仍然可以在spring上下文中通过类型找到它们来创建Feign客户端。

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection<RequestInterceptor>

可以在@FeignClient的配置类中,自行创建这些Bean来订制Feign客户端。例如:

@Configuration
public class FooConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("user", "password");
    }
}

这个例子中,使用feign.Contract.Default来替换SpringMvcContract,同时加上一个RequestInterceptor

默认配置可以通过@EnableFeignClientsdefaultConfiguration属性来制定。这些配置,会被应用到所有的Feign客户端上。

4.6.3 Creating Feign Clients Manually 手动创建Feign客户端

在某些场景中,通过上述方法,还是不能得到一个想要的Feign客户端。 那这个时候,就需要自己通过Feign Builder API来手动创建客户端。 下面这个例子就展现了为同一个接口创建两个不同配置的客户端。

@Import(FeignClientsConfiguration.class)
class FooController {

	private FooClient fooClient;

	private FooClient adminClient;

    @Autowired
	public FooController(
			ResponseEntityDecoder decoder, SpringEncoder encoder, Client client) {
		this.fooClient = Feign.builder().client(client)
				.encoder(encoder)
				.decoder(decoder)
				.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
				.target(FooClient.class, "http://PROD-SVC");
		this.adminClient = Feign.builder().client(client)
				.encoder(encoder)
				.decoder(decoder)
				.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
				.target(FooClient.class, "http://PROD-SVC");
    }
}

注意: 上例中FeignClientsConfiguration.class是Spring Cloud Netflix提供的默认配置类。

注意: PROD-SVC是服务的客户端请求时标记的名称。

4.6.4 Feign Hystrix Support :Feign断路器

如果在classpath中加入了Hystrix,那默认Feign就会为所有方法都包装上一个断路器。也会返回一个com.netflix.hystrix.HystrixCommand。这就会导致可以使用正则匹配(如:调用.toObservable() or .observe())或者异步请求(如:调用.queue())。

如果不想在Feign使用Hystrix,可以配置:feign.hystrix.enabled=false

如果想让每个客户端都不使用Hystrix,可以在prototype作用域中创建一个普通的Feign.Builder实现。例如:

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

4.6.5 Feign Hystrix Fallbacks : Feign降级

Hystrix中的降级概念:当链路中发生错误是,执行一个默认的代码逻辑。 可以在@FeignClient中配置fallback属性,来开启Feign降级处理。例如:

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

如果想在降级操作中处理抛出的异常,可以使用@FeignClientfallbackFactory属性。例如:

@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.HystrixCommandrx.Observable

4.6.6 Feign Inheritance Support 继承

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版本中也不支持这种方式(共用接口)。

4.6.7 Feign request/response compression 数据压缩

可以考虑对Feign的request和response开启GZIP压缩处理。可以在配置文件中通过如下配置开启:

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

在web服务中进行更详细的配置:

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

上例中,指定了Media type和压缩的最小大小进行了指定。

4.6.8 Feign logging 日志

对于创建的每个Feign客户端都会创建一个Logger。默认情况下,使用客户端全类名作为日志名,Feign日志只能设置为DEBUG级别。

application.yml

logging.level.project.user.UserClient: DEBUG

可以为每个客户端配置一个Logger.Level对象,来告诉Feign如何输出日志。可以选择以下级别:

  • NONE,无日志(默认
  • BASIC,仅输出请求的方法、URL、response status code 以及执行时间
  • HEADERS,带上request和response的header信息
  • FULL,包括requset和response的header,body以及元数据

例如:

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

4.7 External Configuration: Archaius 使用Archaius进行外部扩展配置

Archaius是一个Netflix客户端配置的类库。这个类库可以被用于所有的Netflix OSS组件的配置。Archaius是在Apache Commons Configuration的基础山进行扩展出来的。Archaius允许客户端轮询自动发现配置的改动变化。Archaius通过Dynamic<Type>Property类来处理各种配置属性。

Archaius Example

class ArchaiusTest {
    DynamicStringProperty myprop = DynamicPropertyFactory
            .getInstance()
            .getStringProperty("my.prop");

    void doSomething() {
        OtherClass.someMethod(myprop.get());
    }
}

Archaius有自己的配置文件集以及预先加载机制。Spring应用通常不会直接使用Archaius,而是通过Netflix原生的配置工具进行使用。Spring Cloud提供一个Spring Environment来对Archaius属性进行桥接使用。这样就可以让Spring Boot应用能像使用普通配置属性一样使用Archaius。

© 著作权归作者所有

共有 人打赏支持
秋雨霏霏
粉丝 143
博文 90
码字总数 160569
作品 0
杭州
CTO(技术副总裁)
springcloud 学习-eureka搭建

组件名:Netflix Eureka 作用:支撑微服务的自注册、自发现,提供负载均衡能力 开发环境使用IDEA,jdk1.8 一、搭建eureka服务 1.新建maven项目,配置pom.xml文件 org.springframework.cloud ...

gaofeng36599 ⋅ 2017/07/14 ⋅ 0

springCloud(9):使用Feign实现声明式REST调用-为消费者整合Feign与自定义Feign配置

一、简介 前面我们是使用RestTemplate实现rest api调用的,代码如下: @GetMapping("/user/{id}")public User findById(@PathVariable Long id) throws Exception { return this.restTempla......

我爱大金子 ⋅ 2017/07/17 ⋅ 0

Spring Cloud 1.0.0 正式发布

Spring Cloud 1.0.0.RELEASE 现已提供在 Maven Central (和 repo.spring.io),相比 RC3 版本并没有太大改进,修复了一些 bug。 Spring Cloud 为开发者提供了在分布式系统(如配置管理、服务发...

oschina ⋅ 2015/03/05 ⋅ 3

spring cloud 建一个服务消费者client-feign(最好用这种方式)

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只需要创建一个接口并注解。它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign默认集成了Ribbon,...

lsjlgo ⋅ 05/28 ⋅ 0

J360-cloud SpringCloud系列二:服务发现Discovery Service

j360开源博客之 ---------------------------------------------------------- J360-Cloud系列 spring-cloud快速入门工程之j360-cloud-all:(欢迎star、fork) https://github.com/xuminwl......

Hi徐敏 ⋅ 2015/10/10 ⋅ 3

《Spring Cloud Netflix官方文档》7.声明式 REST 客户端: Feign

原文链接 Feign 是一个声明式的web服务客户端。它使得编写web服务客户端更简单,创建一个接口并加上注解就能使用Feign了,它还支持JAX-RS类型的注解,可插入式的编码和解码,Spring cloud 为他...

floder ⋅ 2017/01/05 ⋅ 0

Spring Cloud--Honghu Cloud分布式微服务云系统—组件化

Spring Cloud集成项目有很多,下面我们列举一下和Spring Cloud相关的优秀项目,我们的企业架构中用到了很多的优秀项目,说白了,也是站在巨人的肩膀上去整合的。在学习Spring Cloud之前大家必...

itcloud ⋅ 04/26 ⋅ 0

基于Spring Cloud的微服务落地

微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务。但如果要将微服务架构运用到生产项目上,并且能够发挥该架构模式的重要作用,则需要微服务框架的支持。 在Java生态圈,目...

烂猪皮 ⋅ 04/20 ⋅ 0

【Spring Cloud】分布式必学springcloud(七)——声明式服务调用Feign

一、前言 在上篇博客中,小编带大家接触了断路器Hystrix,是不是很好玩。分布式服务之间有了Hystrix,可以很好的提高容错性能。 但是在实际开发中,项目中会有很多的服务间的调用,对于服务的...

kisscatforever ⋅ 04/23 ⋅ 0

Spring Cloud 1.0.0.RC1 发布

Spring Cloud 1.0.0.RC1 发布,此版本现已提供在 http://repo.spring.io 和 Maven 库。 值得关注的新特性如下: 通过一个注解 和 支持 Hystrix 指标聚合 (for an AMQP-based collector) 新增...

oschina ⋅ 2014/12/20 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

从零开始搭建Risc-v Rocket环境---(1)

为了搭建Rocke环境,我买了一个2T的移动硬盘,安装的ubuntu-16.04 LTS版。没有java8,gcc是5.4.0 joe@joe-Inspiron-7460:~$ java -version程序 'java' 已包含在下列软件包中: * default-...

whoisliang ⋅ 22分钟前 ⋅ 0

大数据学习路线(自己制定的,从零开始学习大数据)

大数据已经火了很久了,一直想了解它学习它结果没时间,过年后终于有时间了,了解了一些资料,结合我自己的情况,初步整理了一个学习路线,有问题的希望大神指点。 学习路线 Linux(shell,高并...

董黎明 ⋅ 28分钟前 ⋅ 0

systemd编写服务

一、开机启动 对于那些支持 Systemd 的软件,安装的时候,会自动在/usr/lib/systemd/system目录添加一个配置文件。 如果你想让该软件开机启动,就执行下面的命令(以httpd.service为例)。 ...

勇敢的飞石 ⋅ 30分钟前 ⋅ 0

mysql 基本sql

CREATE TABLE `BBB_build_info` ( `community_id` varchar(50) NOT NULL COMMENT '小区ID', `layer` int(11) NOT NULL COMMENT '地址层数', `id` int(11) NOT NULL COMMENT '地址id', `full_......

zaolonglei ⋅ 39分钟前 ⋅ 0

安装chrome的vue插件

参看文档:https://www.cnblogs.com/yulingjia/p/7904138.html

xiaoge2016 ⋅ 41分钟前 ⋅ 0

用SQL命令查看Mysql数据库大小

要想知道每个数据库的大小的话,步骤如下: 1、进入information_schema 数据库(存放了其他的数据库的信息) use information_schema; 2、查询所有数据的大小: select concat(round(sum(da...

源哥L ⋅ 今天 ⋅ 0

两个小实验简单介绍@Scope("prototype")

实验一 首先有如下代码(其中@RestController的作用相当于@Controller+@Responsebody,可忽略) @RestController//@Scope("prototype")public class TestController { @RequestMap...

kalnkaya ⋅ 今天 ⋅ 0

php-fpm的pool&php-fpm慢执行日志&open_basedir&php-fpm进程管理

12.21 php-fpm的pool pool是PHP-fpm的资源池,如果多个站点共用一个pool,则可能造成资源池中的资源耗尽,最终访问网站时出现502。 为了解决上述问题,我们可以配置多个pool,不同的站点使用...

影夜Linux ⋅ 今天 ⋅ 0

微服务 WildFly Swarm 管理

Expose Application Metrics and Information 要公开关于我们的微服务的有用信息,我们需要做的就是将监视器模块添加到我们的pom.xml中: 这将使在管理和监视功能得到实现。从监控角度来看,...

woshixin ⋅ 今天 ⋅ 0

java连接 mongo伪集群部署遇到的坑

部署mongo伪集群 #创建mongo数据存放文件地址mkdir -p /usr/local/config1/datamkdir -p /usr/local/config2/data mkdir -p /usr/local/config3/data mkdir -p /usr/local/config1/l......

努力爬坑人 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部