In this series of previous article, demonstrate how to use Hystrix’s circuit breaker function. In this article, I will demonstrate how to use OpenFeign to simplify the development of the Rest client.

OpenFeign is a calling library for the service consumer in spring cloud. It is usually used in combination with ribbon, hystrix, etc., to simplify the code and configuration of accessing services.

Create a new microservice project

Create a new ordinary maven project in IDEA, name its groupId: cn.com.hohistar.tutorial and artifactId: springcloud-openfeign-client, and then replace the pom.xml of the project with the following:

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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>cn.com.hohistar.tutorial</groupId>
<artifactId>springcloud-openfeign-client</artifactId>
<version>1.0-SNAPSHOT</version>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
</properties>

<dependencies>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

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

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</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>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>

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

</project>

New data class

Create a new package named: cn.com.hohistar.cloud.model in src/main/java, and add a class named: Todo in it, the code is as follows:

1
2
3
4
5
6
7
8
9
10
@Data
public class Todo {

private Long id;

private String title;

private String desc;

}

Because all service returns are not standardized to the format of ApiResult, it is also necessary to add the definition of the ApiResult class in the model package. code show as below:

1
2
3
4
5
6
7
8
9
10
11
@Data
public class ApiResult<T> {

private Boolean succ;

private String code;

private String msg;

private T data;
}

Create Feign instance

Create a new package named: cn.com.hohistar.cloud.service in src/main/java, and then create a new interface in the package named: TodoClient. The code is as follows:

1
2
3
4
5
6
7
@FeignClient(value = "cloud-todo-service")
public interface TodoClient {

@RequestMapping(method = RequestMethod.GET, value = "/todo")
ApiResult<List<Todo>> getTodos();

}

Create a Rest API

Create a new package named: cn.com.hohistar.cloud.api in src/main/java, and then create a new class in the package named: FeignClientApi:

1
2
3
4
5
6
7
8
9
10
11
12
13

@RestController
public class FeignClientApi {

@Autowired
private TodoClient client;

@GetMapping("/f/todo")
public ApiResult<List<Todo>> getTodos() {

return client.getTodos();
}
}

Create application startup class

Create a new class named: FeignClientApplication in the package cn.com.hohistar.cloud as the startup class, the code is as follows:

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

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

Add configuration information to the application

Create a new configuration file named application.yml in src/main/resource and add the following content:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server:
port: 9091


spring:
application:
name: cloud-feign-client

eureka:
instance:
leaseRenewalIntervalInSeconds: 1
leaseExpirationDurationInSeconds: 2
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
healthcheck:
enabled: true
lease:
duration: 5

Run program inspection results

After launching the application, visit with a browser:

1
http://localhost:9091/f/todo

You can see similar results:

1
{"succ":true,"code":null,"msg":null,"data":[{"id":1,"title":"Call Metting","desc":""},{"id":2,"title":"Print File","desc":""},{"id":3,"title":"Call Metting","desc":""},{"id":4,"title":"Print File","desc":""}]}

Add fuse function

Add the dependency library for hystrix in the pom.xml file。

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>

Add the following training information in application.xml to allow fusing

1
2
3
feign:
hystrix:
enabled: true

In order to use the custom fallback method, you need to modify the TodoClient interface as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

@FeignClient(value = "cloud-todo-service", fallback = TodoClient.TodoClientFallback.class)
public interface TodoClient {

@RequestMapping(method = RequestMethod.GET, value = "/todo")
ApiResult<List<Todo>> getTodos();


@Component
static class TodoClientFallback implements TodoClient {

@Override
public ApiResult<List<Todo>> getTodos() {

ApiResult<List<Todo>> res = new ApiResult<>();
res.setSucc(false);

return res;
}
}
}