Cloud Native 12 min read

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.

macrozheng
macrozheng
macrozheng
Mastering Spring Cloud OpenFeign: From Setup to Fault Tolerance

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>&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-netflix-eureka-client&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-openfeign&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
    &lt;artifactId&gt;spring-boot-starter-web&lt;/artifactId&gt;
&lt;/dependency&gt;</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-service

instances, as seen in the logs.

Service registry
Service registry

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

instances and restart

feign-service

.

Calling

http://localhost:8701/user/1

returns the fallback response.

Fallback response
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>
JavamicroservicesSpring CloudOpenFeignHystrixFeign Client
macrozheng
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.