当前位置: 首页 > 知识库问答 >
问题:

实例关闭时的Spring Cloud Gateway 500

锺离昂然
2023-03-14

我有一个Spring Cloud Gateway(eureka client)应用程序,它使用Spring Cloud Load Balancer(Spring Cloud Version:hoxton.sr6),我有一个Spring boot应用程序的实例(Spring Boot2.3支持优雅关机(eureka client)。

当我关闭一个spring boot服务并通过网关执行一个请求时,网关会抛出500个错误(连接被拒绝),而不是503。503在1-2分钟后出现。

有人能澄清一下这是否是一种预期的行为吗?

问题似乎来自于eureka-client(在我的例子中是1.9.21版本)AtomicReference LocalRegionApps 不经常更新

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

所以我把我的应用程序。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

共有1个答案

齐高寒
2023-03-14

将特定异常映射到特定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;
        }
    }
}
 类似资料:
  • 本文向大家介绍C#定时关闭窗体实例,包括了C#定时关闭窗体实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#定时关闭窗体的方法,分享给大家供大家参考。具体方法如下: 希望本文所述对大家的C#程序设计有所帮助。

  • 使用Spring-cloud Angel.sr6: 下面是我使用@enablezuulproxy的Spring-boot应用程序的配置: 我有2个实例在随机端口上运行。这些实例以及Zuul实例都成功注册到Eureka中,我可以通过访问http://localhost:8765/service-id/访问2实例上的RESTfulendpoint....并发现它们是以循环方式平衡的。 我想杀死其中一个

  • 我试图把我单独的Java文件在1类。它看起来像这样。 但是我遇到了一个错误 "异常在线程"main"java.lang.错误:未解决的编译问题:没有封闭的实例类型oneClass是可访问的。必须用问题2类型的封闭实例来限定分配(例如x.newA()其中x是问题2的实例)。 发生什么事?

  • 我是Java新手,最近我学习类和对象主题。但是,我无法继续执行此代码: 在主要方法上,我得到了学生的错误,但没有得到老师的错误。我不知道我是否犯了什么错误,或者我看不见。必须做什么? 我得到的错误是: 未使用局部变量学生的值 没有类研究类型的封闭实例是可访问的。必须用类研究类型的封闭实例来限定分配(例如x.newA(),其中x是类研究的实例)。 换行断点:ClassResearch[line: 4

  • 方法一:常规启动关闭数据库方式(推荐) 常规方法启动数据库 启动MySQL命令 [root@localhost ~]# /etc/init.d/mysql start Starting MySQL.. [确定] 查看MySQL端口 [root@localhost ~]# netstat -tunpl|grep mysql tcp 0 0 0.0.0.0:3306 0.0

  • 使用“Camden.sr5”处理spring-cloud-dependencies,使用Spring Boot“1.5.2.Release”。 在我当前的设置中,我有 尤里卡服务器 配置服务器(运行在随机端口上) Zuul网关服务器 和服务的2个实例(运行在随机端口上) service的2个实例使用唯一的实例ID运行 您能帮助我使用zuul&instances配置吗,这样当一个实例关闭时,请求就会