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

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

Configure application.yml

server:
  port: 8701
spring:
  application:
    name: feign-service
eureka:
  client:
    register-with-eureka: true
    fetch-registry: true
    service-url:
      defaultZone: http://localhost:8001/eureka/

Enable Feign Clients

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

Define UserService Interface

Using @FeignClient(value="user-service") creates a Feign client for the user-service service.
@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);
}

Implement UserFeignController

@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);
    }
}

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.
@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);
    }
}

Configure Fallback in @FeignClient

Set the fallback attribute to UserFallbackService.class .
@FeignClient(value = "user-service", fallback = UserFallbackService.class)
public interface UserService { }

Enable Hystrix in application.yml

feign:
  hystrix:
    enabled: true

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

@Configuration
public class FeignConfig {
    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }
}

Set Logging Level for Specific Client in application.yml

logging:
  level:
    com.macro.cloud.service.UserService: debug

View Logs

Calling http://localhost:8701/user/1 shows detailed request/response logs.
2019-10-04 15:44:03.248 DEBUG ... [UserService#getUser] --> GET http://user-service/user/1 HTTP/1.1
... (full log omitted for brevity)

Common Feign Configurations

Feign‑specific Settings

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

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

springcloud-learning
├── eureka-server   // Eureka registry
├── user-service   // Provides CRUD APIs for User objects
└── feign-service  // Demonstrates Feign service calls
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

javaOpenFeignHystrixFeign 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

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.