部署环境下AWS S3大文件上传失败:Connection reset by peer问题
测试环境Spring应用上传大文件至AWS S3失败问题
- 测试环境部署的Java Spring应用中,上传1MB及以上大小的文件至AWS S3时失败,报错信息:
com.amazonaws.SdkClientException exception: The HTTP request cannot be executed: The peer resets the connection.
- 本地环境所有文件上传均正常。
- 未配置
request.getRequestClientOptions().setReadLimit(custom buffer size);时,会触发如下报错:
The request to the service failed for a reason that can be repeated, but the reset of the request input stream failed. See exception.getExtraInfo or the debug log for information about the initial failure that caused this retry.; If the request includes an input stream, the maximum size of the stream buffer can be configured using request.getRequestClientOptions().setReadLimit(int)
- 本地无需任何额外配置即可正常运行。
- 此前曾因Bucket地址误设为HTTPS而非HTTP,导致仅能上传几KB大小的文件,上传100KB文件时会出现
<Remote end is closed>的HTTP错误。 - 本地与测试环境的AWS配置完全一致,上传方法及AwsConfig代码如下:
上传方法代码
public ResponseEntity uploadFile(String catalogId, MultipartFile file) { if (file == null || file.isEmpty()) { return ResponseEntity.status(400).body(new ErrorResponse("Файл не передан")); } if (file.getSize() > maxFileSize * 1024 * 1024) { return ResponseEntity.status(PAYLOAD_TOO_LARGE).contentType(MediaType.APPLICATION_JSON).body(new ErrorResponse("Размер файла не должен превышать: " + maxFileSize + " Мб")); } log.info("Начинаем загрузку файла: {}", file.getOriginalFilename()); String filePath = PathGenerator.generateFileUri(catalogId); try { // if (checkExists(filePath)) { // log.info("Такой файл уже есть, удаляем для создания нового"); // deleteFile(filePath); // } ObjectMetadata meta = new ObjectMetadata(); meta.setContentType(file.getContentType()); meta.setContentLength(file.getSize()); meta.addUserMetadata("originalFileName", URLEncoder.encode(requireNonNull(file.getOriginalFilename()), StandardCharsets.UTF_8)); PutObjectRequest request = new PutObjectRequest(bucketName, filePath, file.getInputStream(), meta); if (isCustomBufferSize) { request.getRequestClientOptions().setReadLimit(customBufferSize); } awsConfig.getAwsClient().putObject(request); log.info("Файл успешно загружен!"); HashMap<String, String> response = new HashMap<>(); response.put("fileUuid", filePath); return ResponseEntity.ok().body(response); } catch (Exception e) { log.error(e.getMessage(), e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(MediaType.APPLICATION_JSON).body(new ErrorResponse("Ошибка записи: " + e.getMessage())); } }
AwsConfig代码
public AmazonS3 getAwsClient() { String str = s3endpoint; String[] arr = str.split("://"); String endpoint; Protocol protocol; if (arr.length == 1) { protocol = Protocol.HTTP; endpoint = str; } else { protocol = (arr[0].equalsIgnoreCase(Protocol.HTTPS.name())) ? Protocol.HTTPS : Protocol.HTTP; endpoint = arr[1]; } ClientConfiguration clientConfig = new ClientConfiguration(); clientConfig.setProtocol(protocol); clientConfig.setSocketTimeout(60000); if (endpoint.contains("10.241.34.61")) { return AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))) .withClientConfiguration(clientConfig) .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, Region.EU_Ireland.getFirstRegionId())) .withPathStyleAccessEnabled(true) .build(); } else { return AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(new BasicAWSCredentials(accessKey, secretKey))) .withClientConfiguration(clientConfig) .withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(endpoint, Region.US_Standard.getFirstRegionId())) .withPathStyleAccessEnabled(true) .build(); } }
内容的提问来源于stack exchange,提问作者Mikhail Tarasov
相关产品推荐
相关产品推荐

