Spring Cloud教程三:Feign | Java提升营

Spring Cloud教程三:Feign

在上一篇文章,讲解了通过RestTemplate+Ribbon消费服务,今天主要讲述怎样通过Feign去消费服务。

Feign简介

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign.

Feign是一个声明式的web服务客户端,它使得写web客户端变得更简单。想要使用Feign,只需要创建一个接口并注解它。Feign具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解。Feign还支持可插拔的编码器和解码器。Spring Cloud添加了对Spring MVC注释的支持,并默认使用和Spring Web相同的HttpMessageConverters。当使用Feign时,Spring Cloud集成了Ribbon和Eureka以提供负载平衡的http客户端。

简而言之:

  • Feign 采用的是基于接口的注解
  • Feign 集成了ribbon,具有负载均衡的能力
  • 集成了Hystrix,具有熔断的能力

准备工作

继续在第一节项目的基础上,启动eureka-server,端口为9090;启动两个eureka-client, 端口为8040、8041。

创建一个Feign服务

使用Spring Initializr新建一个项目,取名为feign-service, 在Spring Cloud Discovery中勾选Eureka Discovery Client,在Spring Cloud Routing中勾选OpenFeign,在Web中勾选Spring Web:

创建成功后,项目pom.xml如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.noodles.mars</groupId>
<artifactId>feign-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>feign-service</name>
<description>Feign Service</description>

<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR3</spring-cloud.version>
</properties>

<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>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

feign-service配置服务中心地址、应用名、端口,配置文件内容:

1
2
3
4
5
6
7
8
9
10
11
server:
port: 8080

eureka:
client:
service-url:
defaultZone: http://localhost:9090/eureka/

spring:
application:
name: feign-client

在项目启动类上注解@EnableDiscoveryClient, 开启向服务中心注册;注解@EnableFeignClients开启Feign功能:

1
2
3
4
5
6
7
8
9
10
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class FeignServiceApplication {

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

}

定义一个feign接口,通过@FeignClient("服务应用名"),来指定调用哪个服务。比如在代码中调用了hello-erueka-client服务的/hello接口,代码如下:

1
2
3
4
5
6
@FeignClient(value = "hello-eureka-client")
public interface FeignService {

@GetMapping(value = "/hello")
String hello(@RequestParam(value = "name") String name);
}

定义一个Controller,对外提供一个”/hello”的Rest API接口, 通过上面定义的Feign来调用服务提供者:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
public class FeignController {

private final FeignService feignService;

@Autowired
public FeignController(FeignService feignService) {
this.feignService = feignService;
}

@GetMapping(value = "/hello")
public String hello(@RequestParam("name") String name) {
return feignService.hello(name);
}
}

在浏览器上多次访问 http://localhost:8080/hello?name=Mars :

1
2
Hello, My name is Mars, I'm from port: 8040
Hello, My name is Mars, I'm from port: 8041

这说明负载均衡器已经工作了。 下一节我们讲解熔断的能力,敬请期待!

点击进入源码仓库

给老奴加个鸡腿吧 🍨.