我有一个使用Spring Cloud Load Balancer (Spring Cloud version: Hoxton.SR6)的Spring Cloud Gateway (eureka client)应用程序,我还有一个spring boot应用程序的实例(spring boot 2.3,支持优雅关机) (eureka client)。
当我关闭spring启动服务并通过网关执行请求时,网关会抛出500错误(连接被拒绝),而不是503。503在1-2分钟后出现。
有人能澄清这是否是一种预期的行为吗?
问题似乎来自于eureka-client (在我的例子中是1.9.21版本) AtomicReference<Applications> localRegionApps不经常更新
谢谢!
更新:我决定更深入地检查这个500错误。结果是,如果端口未被使用,我的系统(ubuntu)会给出这个错误:
curl -v localhost:9722
Rebuilt URL to: localhost:9722/
Trying 127.0.0.1...
TCP_NODELAY set
connect to 127.0.0.1 port 9722 failed: Connection refused
Failed to connect to localhost port 9722: Connection refused
Closing connection 0所以我输入了我的application.yml:
spring:
cloud:
gateway:
routes:
- id: my_route
uri: http://localhost:9722/然后,当我的请求被路由到my_route,并且没有应用程序使用9722时,我会得到一个错误:
io.netty.channel.AbstractChannel$AnnotatedConnectException: finishConnect(..) failed: Connection refused: localhost/127.0.0.1:9722
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/internal/mail/internal/health-check" [ExceptionHandlingWebHandler]
Stack trace:
Caused by: java.net.ConnectException: finishConnect(..) failed: Connection refused
at io.netty.channel.unix.Errors.throwConnectException(Errors.java:124)
at io.netty.channel.unix.Socket.finishConnect(Socket.java:251)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.doFinishConnect(AbstractEpollChannel.java:672)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.finishConnect(AbstractEpollChannel.java:649)
at io.netty.channel.epoll.AbstractEpollChannel$AbstractEpollUnsafe.epollOutReady(AbstractEpollChannel.java:529)
at io.netty.channel.epoll.EpollEventLoop.processReady(EpollEventLoop.java:465)
at io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:378)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:834)这似乎是一个意想不到的异常,因为它不可能使用断路器或任何网关过滤器来处理它。
是否有可能正确处理此错误?在这种情况下,我想返回503。
发布于 2021-05-21 02:50:27
将特定异常映射到特定HTTP状态代码的最简单方法之一是提供org.springframework.boot.web.reactive.error.ErrorAttributes类型的自定义bean。下面是一个示例:
@Bean
public ErrorAttributes errorAttributes() {
return new CustomErrorAttributes(httpStatusExceptionTypeMapper);
}
public class CustomErrorAttributes extends DefaultErrorAttributes {
@Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {
Map<String, Object> attributes = super.getErrorAttributes(request, options);
Throwable error = getError(request);
MergedAnnotation<ResponseStatus> responseStatusAnnotation = MergedAnnotations
.from(error.getClass(), MergedAnnotations.SearchStrategy.TYPE_HIERARCHY).get(ResponseStatus.class);
HttpStatus errorStatus = determineHttpStatus(error, responseStatusAnnotation);
attributes.put("status", errorStatus.value());
return attributes;
}
private HttpStatus determineHttpStatus(Throwable error, MergedAnnotation<ResponseStatus> responseStatusAnnotation) {
if (error instanceof ResponseStatusException) {
return ((ResponseStatusException) error).getStatus();
}
return responseStatusAnnotation.getValue("code", HttpStatus.class).orElseGet(() -> {
if (error instanceof java.net.ConnectException) {
return HttpStatus.SERVICE_UNAVAILABLE;
}
return HttpStatus.INTERNAL_SERVER_ERROR;
}
}
}发布于 2020-10-22 17:11:44
请尝试定义您的自定义ErrorWebExceptionHandler。请参阅:org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler org.springframework.boot.autoconfigure.web.reactive.error.DefaultErrorWebExceptionHandler
发布于 2021-09-20 16:24:52
您应该使用Cloud Circuit Breaker。
要做到这一点:
org.springframework.cloud spring-cloud-starter-circuitbreaker-reactor-resilience4j
application.yaml中声明断路器forward:/inCaseOfFailureUseThis:cloud: gateway: routes:- id: my_route uri:http://localhost:9722/过滤器:- name: CircuitBreaker args: name: myCircuitBreaker fallbackUri: spring
@ Mono.just(ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("body (“/inCaseOfFailureUseThis”)公共Mono inCaseOfFailureUseThis() {返回服务失败案例的映射“);}
https://stackoverflow.com/questions/64440951
复制相似问题