Master Spring Cloud OpenFeign: Configuring URLs, Timeouts, Logging & Hystrix
This tutorial walks through setting up Spring Boot 2.3.8 with Spring Cloud Hoxton, adding OpenFeign dependencies, configuring service URLs, customizing Feign client defaults, enabling logging, setting request timeouts, and integrating Hystrix circuit breaker with fallbacks and factories.
Environment: Spring Boot 2.3.8.RELEASE + Spring Cloud Hoxton.SR8
Add the required Maven dependencies:
<code><dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</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></code>Configure the target service directly via URL
<code>@FeignClient(value = "mv", url = "${feign.url}")
public interface PersonWeb {
@GetMapping("/person/{id}")
String get(@PathVariable Integer id);
}</code> <code>feign:
url: http://localhost:8001</code>Target service implementation:
<code>@RestController
public class PersonController {
@GetMapping("/person/{id}")
Object get(@PathVariable Integer id) {
return "Person";
}
}</code>Note: The target service returns an
Object(actually a
String), so the Feign interface must declare
Stringas the return type.
Modify default configuration attributes of
@FeignClient <code>@FeignClient(value = "mv", url = "${feign.url}", configuration = FeignConfig.class)
public interface PersonWeb { ... }</code> <code>public class FeignConfig {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}</code>The above JavaConfig sets the default logger level; the same can be done via properties.
Logging level configuration (application.yml):
<code>logging:
level:
com.pack.controller.PersonWeb: debug</code>Set request timeout
<code>feign:
url: http://localhost:8001
httpclient:
enabled: true
client:
config:
mv:
connectTimeout: 2000
readTimeout: 2000</code>The
mvkey corresponds to the
value(or
name) defined in
@FeignClient.
Adjust the target service to delay response by 5 seconds:
<code>@GetMapping("/person/{id}")
public Object get(@PathVariable Integer id) {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Person";
}</code>The console shows timeout errors, confirming that the
readTimeoutsetting is effective.
Log level configuration
<code>feign:
logger-level: basic</code>This setting overrides the logger level defined in
FeignConfig.
Circuit‑breaker support
Supported circuit‑breaker implementations include Netfix Hystrix, Resilience4J, Sentinel, and Spring Retry. This example uses Hystrix.
<code>feign:
hystrix:
enabled: true</code> <code>@Component
public class PersonFallback implements PersonWeb {
@Override
public String get(Integer id) {
return "我是返回的默认值";
}
}</code> <code>@FeignClient(value = "mv", url = "${feign.url}", configuration = FeignConfig.class, fallback = PersonFallback.class)
public interface PersonWeb { ... }</code>Hystrix’s default timeout is 1 second, while the target service sleeps for 5 seconds.
Modify Hystrix timeout via configuration:
<code><dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency></code> <code>hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 3000
timeout:
enabled: true</code>Obtain exception details with a
FallbackFactory:
<code>@Component
public class PersonFallbackFactory implements FallbackFactory<PersonWeb> {
@Override
public PersonWeb create(Throwable cause) {
cause.printStackTrace();
return new PersonWeb() {
@Override
public String get(Integer id) {
return "fallback";
}
};
}
}
@FeignClient(value = "mv", url = "${feign.url}", configuration = FeignConfig.class, fallbackFactory = PersonFallbackFactory.class)
public interface PersonWeb { ... }</code>Feign inheritance support
<code>public interface BaseController {
@GetMapping("/person/{id}")
String get(@PathVariable Integer id);
}</code> <code>@RestController
@RequestMapping("/demo")
public class DemoController implements BaseController {
@Resource
private PersonWeb personWeb;
@GetMapping("/person/{id}")
public String get(@PathVariable Integer id) {
return personWeb.get(id);
}
}</code> <code>@FeignClient(value = "mv", url = "${feign.url}", configuration = FeignConfig.class, fallbackFactory = PersonFallbackFactory.class)
public interface PersonWeb extends BaseController { }
</code>Using inheritance in this way is generally not recommended.
Final application entry point:
<code>@SpringBootApplication
@EnableFeignClients
@EnableCircuitBreaker
public class SpringBootOpenfeignApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootOpenfeignApplication.class, args);
}
}
</code>Done!!
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.