Mastering Spring Cloud OpenFeign: From Setup to Fault Tolerance
This article introduces Spring Cloud OpenFeign, explains its declarative service call features, walks through creating a feign-service module with Maven dependencies, configuring Eureka and Ribbon, defining Feign clients, demonstrating load balancing, implementing Hystrix fallback, and enabling detailed logging for robust microservice communication.
Feign Introduction
Feign is a declarative service‑call tool; by defining an interface and annotating it you can invoke remote services without using RestTemplate directly. Spring Cloud integrates Ribbon and Eureka for load‑balanced calls and Hystrix for circuit‑breaker protection.
Create a feign-service Module
We create a feign-service module to demonstrate common Feign features.
Add Maven Dependencies
<code><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-web</artifactId>
</dependency></code>Configure application.yml
<code>server:
port: 8701
spring:
application:
name: feign-service
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8001/eureka/</code>Enable Feign Clients
<code>@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class FeignServiceApplication {
public static void main(String[] args) {
SpringApplication.run(FeignServiceApplication.class, args);
}
}</code>Define UserService Interface
Using @FeignClient(value="user-service") creates a Feign client for the user-service service.
<code>@FeignClient(value = "user-service")
public interface UserService {
@PostMapping("/user/create")
CommonResult create(@RequestBody User user);
@GetMapping("/user/{id}")
CommonResult<User> getUser(@PathVariable Long id);
@GetMapping("/user/getByUsername")
CommonResult<User> getByUsername(@RequestParam String username);
@PostMapping("/user/update")
CommonResult update(@RequestBody User user);
@PostMapping("/user/delete/{id}")
CommonResult delete(@PathVariable Long id);
}</code>Implement UserFeignController
<code>@RestController
@RequestMapping("/user")
public class UserFeignController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public CommonResult getUser(@PathVariable Long id) {
return userService.getUser(id);
}
@GetMapping("/getByUsername")
public CommonResult getByUsername(@RequestParam String username) {
return userService.getByUsername(username);
}
@PostMapping("/create")
public CommonResult create(@RequestBody User user) {
return userService.create(user);
}
@PostMapping("/update")
public CommonResult update(@RequestBody User user) {
return userService.update(user);
}
@PostMapping("/delete/{id}")
public CommonResult delete(@PathVariable Long id) {
return userService.delete(id);
}
}</code>Load‑Balancing Demonstration
Start
eureka-service, two instances of
user-service, and
feign-service. The registry shows all services.
Repeatedly call
http://localhost:8701/user/1; the requests are distributed between the two
user-serviceinstances, as seen in the logs.
Feign Service Degradation (Fallback)
Feign makes service degradation easy: just provide an implementation of the Feign client interface that supplies fallback logic.
Add Fallback Implementation UserFallbackService
The class implements UserService and returns default responses for each method.
<code>@Component
public class UserFallbackService implements UserService {
@Override
public CommonResult create(User user) {
User defaultUser = new User(-1L, "defaultUser", "123456");
return new CommonResult<>(defaultUser);
}
@Override
public CommonResult<User> getUser(Long id) {
User defaultUser = new User(-1L, "defaultUser", "123456");
return new CommonResult<>(defaultUser);
}
@Override
public CommonResult<User> getByUsername(String username) {
User defaultUser = new User(-1L, "defaultUser", "123456");
return new CommonResult<>(defaultUser);
}
@Override
public CommonResult update(User user) {
return new CommonResult("调用失败,服务被降级", 500);
}
@Override
public CommonResult delete(Long id) {
return new CommonResult("调用失败,服务被降级", 500);
}
}</code>Configure Fallback in @FeignClient
Set the fallback attribute to UserFallbackService.class .
<code>@FeignClient(value = "user-service", fallback = UserFallbackService.class)
public interface UserService { }</code>Enable Hystrix in application.yml
<code>feign:
hystrix:
enabled: true</code>Service Degradation Demo
Stop both
user-serviceinstances and restart
feign-service.
Calling
http://localhost:8701/user/1returns the fallback response.
Logging Feature
Feign provides configurable logging levels to inspect HTTP request details.
Logging Levels
NONE – no logs.
BASIC – method, URL, status, time.
HEADERS – BASIC plus request/response headers.
FULL – HEADERS plus body and metadata.
Enable Full Logging via Java Config
<code>@Configuration
public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}</code>Set Logging Level for Specific Client in application.yml
<code>logging:
level:
com.macro.cloud.service.UserService: debug</code>View Logs
Calling http://localhost:8701/user/1 shows detailed request/response logs.
<code>2019-10-04 15:44:03.248 DEBUG ... [UserService#getUser] --> GET http://user-service/user/1 HTTP/1.1
... (full log omitted for brevity)</code>Common Feign Configurations
Feign‑specific Settings
<code>feign:
hystrix:
enabled: true
compression:
request:
enabled: false
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
response:
enabled: false
logging:
level:
com.macro.cloud.service.UserService: debug</code>Ribbon Configuration in Feign
Feign can use Ribbon’s load‑balancing settings directly; refer to Spring Cloud Ribbon documentation.
Hystrix Configuration in Feign
Hystrix settings are the same as in Spring Cloud Hystrix; refer to its documentation.
Modules Used
<code>springcloud-learning
├── eureka-server // Eureka registry
├── user-service // Provides CRUD APIs for User objects
└── feign-service // Demonstrates Feign service calls</code>macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.