SpringCloud - 声明式服务调用组件Feign使用详解1(基本用法)
我们知道 Spring Cloud Ribbon 和 Spring Cloud Hystrix 被作为基础工具类框架广泛地应用在各个微服务的实现。由于这两个框架的使用几乎是同时出现的,因此便诞生了 Spring Cloud Feign,它提供了更高层次的封装来整合这两个基础工具以简化开发。
(2)接着编辑项目的 application.properites 文件,添加如下配置为服务命名,并指定服务注册中心的地址:
(3)在主类上添加 @EnableDiscoveryClient 注解(激活 Eureka 中的 DiscoveryClient 实现),添加 @EnableFeignClients 注解开启 Spring Cloud Feign 的支持功能:
(4)定义 HelloService 接口,通过 @FeignClient 注解指定服务名来绑定服务,然后使用 Spring MVC 的注解来绑定具体该服务提供的 REST 接口。
(5)接着创建一个 ConsumerController 来实现对 Feign 客户端的调用,我们直接注入签名定义的 HelloService 实例,然后调用这个绑定了 hello-service 服务接口的客户端来像该服务发起 /hello 接口的调用。
一、基本用法
1,Spring Cloud Feign 介绍
(1)Spring Cloud Feign 是基于 Netflix feign 实现,整合了 Spring Cloud Ribbon 和 Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的 Web 服务客户端定义的方式。
声明式的 Web 服务客户端定义的方式:通过编写简单的接口和注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。Feign 会完全代理 HTTP 的请求,在使用过程中我们只需要依赖注入 Bean,然后调用对应的方法传递参数即可。
(2)Feign 有如下特性:
- 可插拔的注解支持,包括 Feign 注解和 AX-RS 注解。
- 支持可插拔的 HTTP 编码器和解码器。
- 支持 Hystrix 和它的 Fallback。
- 支持 Ribbon 的负载均衡。
- 支持 HTTP 请求和响应的压缩。
2,准备一个服务提供者
(1)首先参考我之前写的文章创建并注册一个服务提供者 hello-service:
(2)这个服务提供者提供如下接口,后面我们会通过 Feign 来实现对该服务接口的调用:
@RestController public class HelloController { @Value("${server.port}") private String serverPort; @GetMapping("/hello") public String hello() throws Exception { System.out.println(serverPort); return serverPort; } }
3,服务消费
(1)创建一个 Spring Boot 基础工程,取名为 feign-consumer,在 pom.xml 中引入相关依赖:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
(2)接着编辑项目的 application.properites 文件,添加如下配置为服务命名,并指定服务注册中心的地址:
#为服务命名
spring.application.name=feign-consumer
#设置服务端口
server.port=9001
#指定服务注册中心的地址
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
(3)在主类上添加 @EnableDiscoveryClient 注解(激活 Eureka 中的 DiscoveryClient 实现),添加 @EnableFeignClients 注解开启 Spring Cloud Feign 的支持功能:
@SpringBootApplication @EnableDiscoveryClient @EnableFeignClients public class FeignConsumerApplication { public static void main(String[] args) { SpringApplication.run(FeignConsumerApplication.class, args); } }
(4)定义 HelloService 接口,通过 @FeignClient 注解指定服务名来绑定服务,然后使用 Spring MVC 的注解来绑定具体该服务提供的 REST 接口。
注意:这里的服务名不区分大小写,所以使用 hello-service 和 HELLO-SERVICE 都是可以的。
@FeignClient("hello-service") public interface HelloService { @RequestMapping("/hello") String hello(); }
(5)接着创建一个 ConsumerController 来实现对 Feign 客户端的调用,我们直接注入签名定义的 HelloService 实例,然后调用这个绑定了 hello-service 服务接口的客户端来像该服务发起 /hello 接口的调用。
@RestController public class ConsumerController { @Autowired HelloService helloService; @GetMapping(value = "/feign-consumer") public String helloConsumer() { return helloService.hello(); } }
4,运行测试
(1)我们启动服务中心、HELLO-SERVICE、FEIGN-CONSUMER,此时在 Eureka 信息面板中可以看到如下内容:
(2)发送GET请求到 http://localhost:9001/feign-consumer,可以得到如之前 Ribbon 实现时的一样效果,正确请求 HELLO-SERVICE 服务并返回数据。不同的是通过 Feign 我们只需要定义服务绑定接口,以声明式的方法,优雅而简单地实现了服务调用。
注意:如果我们启动了多个 HELLO-SERVICE 实例,Feign 同样会通过轮询实现客户端负载均衡。因为其内部依然是利用 Ribbon 维护针对了 HELLO-SERVICE 的服务列表信息。