本文目录导读:

- Spring Boot/WebFlux 异步请求超时
- RestTemplate HTTP 请求超时
- WebClient 响应式超时
- Servlet 容器配置(Tomcat)
- Spring Cloud OpenFeign 超时
- 数据库查询超时
- 全局超时异常处理
- 最佳实践建议
在Java中处理请求超时通常涉及以下几个方面,具体实现取决于你使用的框架和技术栈,以下是几种常见场景及处理方案:
Spring Boot/WebFlux 异步请求超时
使用 @Async 配合 Future
import java.util.concurrent.*;
@Service
public class AsyncService {
@Async
public Future<String> slowOperation() {
// 模拟耗时操作
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return new AsyncResult<>("完成");
}
}
// 控制器中处理超时
@RestController
public class TimeoutController {
@Autowired
private AsyncService service;
@GetMapping("/timeout-demo")
public String handleTimeout() {
Future<String> future = service.slowOperation();
try {
// 设置2秒超时
return future.get(2, TimeUnit.SECONDS);
} catch (TimeoutException e) {
future.cancel(true);
return "请求超时";
} catch (Exception e) {
return "处理异常:" + e.getMessage();
}
}
}
使用 CompletableFuture
@GetMapping("/completable-timeout")
public String handleCompletableTimeout() {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return "完成";
});
try {
return future.orTimeout(2, TimeUnit.SECONDS)
.exceptionally(ex -> "请求超时")
.get();
} catch (Exception e) {
return "处理失败";
}
}
RestTemplate HTTP 请求超时
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
// 连接超时
factory.setConnectTimeout(3000);
// 读取超时
factory.setReadTimeout(5000);
return new RestTemplate(factory);
}
}
// 使用
@Service
public class HttpService {
@Autowired
private RestTemplate restTemplate;
public String callExternalApi() {
try {
return restTemplate.getForObject(
"https://example.com/slow-api",
String.class
);
} catch (ResourceAccessException e) {
return "外部服务超时:" + e.getMessage();
}
}
}
WebClient 响应式超时
@Service
public class ReactiveService {
public Mono<String> callWithTimeout() {
return WebClient.create("https://example.com")
.get()
.uri("/slow-api")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(3)) // 整体超时
.onErrorResume(TimeoutException.class, e ->
Mono.just("请求超时(响应式)"))
.onErrorResume(Exception.class, e ->
Mono.just("其他错误:" + e.getMessage()));
}
}
// 控制器
@RestController
public class WebClientController {
@Autowired
private ReactiveService service;
@GetMapping("/reactive-timeout")
public Mono<String> handleReactiveTimeout() {
return service.callWithTimeout();
}
}
Servlet 容器配置(Tomcat)
application.yml
server:
tomcat:
connection-timeout: 3000 # 连接超时(毫秒)
max-connections: 10000 # 最大连接数
max-threads: 200 # 最大线程数
servlet:
session:
timeout: 30m # Session超时
全局 Filter 处理
@Component
public class TimeoutFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
long timeout = 5000; // 5秒
// 设置请求超时
httpRequest.startAsync();
httpRequest.getAsyncContext().setTimeout(timeout);
chain.doFilter(request, response);
}
}
Spring Cloud OpenFeign 超时
配置类
feign:
client:
config:
default:
connectTimeout: 3000 # 连接超时
readTimeout: 5000 # 读取超时
loggerLevel: basic
specific-service: # 特定服务配置
connectTimeout: 5000
readTimeout: 10000
代码配置
@Configuration
public class FeignConfig {
@Bean
public Request.Options options() {
return new Request.Options(
3000, // 连接超时
TimeUnit.MILLISECONDS,
5000, // 读取超时
TimeUnit.MILLISECONDS,
true // 跟随重定向
);
}
}
@FeignClient(name = "example-service", configuration = FeignConfig.class)
public interface ExampleClient {
@GetMapping("/api/data")
String getData();
}
数据库查询超时
JDBC 超时设置
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setConnectionTimeout(3000); // 连接超时
config.setConnectionTestTimeout(3000); // 连接测试超时
config.setMaxLifetime(1800000); // 连接最大生命周期
return new HikariDataSource(config);
}
}
// JPA 查询超时设置
@Repository
public class UserRepository {
@PersistenceContext
private EntityManager entityManager;
public List<User> findUsersWithTimeout() {
Query query = entityManager.createQuery("SELECT u FROM User u");
query.setHint("javax.persistence.query.timeout", 5000); // 5秒
return query.getResultList();
}
}
全局超时异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(TimeoutException.class)
@ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
@ResponseBody
public Map<String, Object> handleTimeout(TimeoutException e) {
Map<String, Object> result = new HashMap<>();
result.put("code", 408);
result.put("message", "请求超时");
result.put("timestamp", System.currentTimeMillis());
return result;
}
@ExceptionHandler(ResourceAccessException.class)
@ResponseStatus(HttpStatus.REQUEST_TIMEOUT)
@ResponseBody
public Map<String, Object> handleResourceTimeout(ResourceAccessException e) {
Map<String, Object> result = new HashMap<>();
result.put("code", 408);
result.put("message", "外部服务超时:" + e.getMessage());
return result;
}
}
最佳实践建议
- 分层设置超时:对不同层级设置不同的超时时间(网络层>服务层>数据库层)
- 合理设置超时值:
- 连接超时:3000-5000ms
- 读取超时:5000-10000ms
- 业务处理超时:根据业务复杂度设定
- 使用断路器:结合 Hystrix/Resilience4j 防止雪崩效应
- 超时后处理:
- 返回默认值或缓存数据
- 异步补偿处理
- 记录日志用于监控
// Resilience4j 断路器示例
@CircuitBreaker(name = "externalService", fallbackMethod = "fallback")
@TimeLimiter(name = "externalService", fallbackMethod = "fallback")
public CompletableFuture<String> callExternalService() {
return CompletableFuture.supplyAsync(() -> {
// 调用外部服务
return restTemplate.getForObject("...", String.class);
});
}
public CompletableFuture<String> fallback(TimeoutException e) {
return CompletableFuture.completedFuture("服务超时,使用降级数据");
}
选择哪种方案取决于你的应用架构、性能要求和业务场景,建议在生产环境中结合监控系统(如Prometheus)来动态调整超时参数。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播