首页 > 解决方案 > Spring Cloud Gateway 未返回下游服务给出的正确响应代码(用于文件上传)

问题描述

我有一个简单的文件上传下游服务。示例代码

@RestController
@RequestMapping("/file")
public class FileController {

    @PostMapping("/upload")
    public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file,
        @RequestParam(value = "delay", required = false, defaultValue = "0") int delay) throws Exception {

        System.out.println(String.join(System.getProperty("line.separator"),
            "File Name => " + file.getOriginalFilename(),
            "File Size => " + file.getSize() + "bytes",
            "File Content Type => " + file.getContentType()));

        TimeUnit.MILLISECONDS.sleep(delay);

        return ResponseEntity.ok(file.getName() + " uploaded");
    }

}

如果有 a 则返回CustomExceptionHandlera :BAD_REQUESTMultipartException

@Configuration
@ControllerAdvice
public class CustomExceptionHandler {
    @ExceptionHandler(MultipartException.class)
    public ResponseEntity<String> handleMultipartException(MultipartException ex) {
        return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
    }
}

application.yml 中的大小限制为 10MB:

spring:
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

如果我上传一个大文件,它会给我一个400预期的状态 文件服务响应 400

当我尝试通过spring cloud gateway访问相同的内容时,我得到以下结果:

在此处输入图像描述

日志显示如下:

2019-11-08 00:36:10.797 ERROR 21904 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [86e57f7e] 500 Server Error for HTTP POST "/product-service/file/upload"

reactor.netty.http.client.PrematureCloseException: Connection has been closed BEFORE response, while sending request body

请注意,网关配置为接收大文件大小,RequestSize全局过滤器设置为超过 10MB。

如何获得与下游服务提供的相同响应代码?

另外,我检查了传统的 Zuul,我500也得到了一个错误。

对于网关,对于这种特殊情况,我知道我们可以使用RequestSize过滤器,现在网关将返回错误代码,但是我们必须事先识别所有预期的路由。 此外,API 中的其他验证,如授权等,也会有同样的问题。由于这些验证而产生的响应代码不会向上传播

示例代码 spring-cloud-gateway/product-service/eureka - https://github.com/dhananjay12/spring-cloud/tree/master/spring-routing

标签: spring-bootspring-cloudnetflix-zuulspring-cloud-gatewayreactor-netty

解决方案


您可以尝试直接通过文件体积的非限制而不通过 getway 吗?尝试属性的值 -1 :

要上传文件的 MS 的属性文件

spring.servlet.multipart.max-file-size =-1

spring.servlet.multipart.max-request-size =-1

如果它很好,它可能会给 zuul 代理的功能区套接字大小带来问题,有针对这种情况的属性通知,如下:

getway 的属性文件:

ribbon.eager-load.enabled=true
hystrix.command.default.execution.timeout.enabled=false
hystrix.command.default.execution.isolation.strategy=THREAD

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=3999996
ribbon.ConnectTimeout=999999
ribbon.ReadTimeout=999999
ribbon.SocketTimeout=999999
zuul.host.socket-timeout-millis=999999
zuul.host.connect-timeout-millis=999999
zuul.sensitiveHeaders=Cookie,Set-Cookie

推荐阅读