ResponseEntity를 사용하고 InputStream이 닫히는 지 확인하는 적절한 스트리밍 방법

두드러진

우리 애플리케이션 중 하나가 파일 핸들을 누출하고 아직 그 원인을 찾지 못했습니다.

코드에서 다음과 유사한 여러 기능을 볼 수 있습니다.

public ResponseEntity<InputStreamResource> getFoo( ... ) {
    InputStream content = getContent(...)
    InputStreamResource isr = new InputStreamResource(content);
    return ResponseEntity.status(HttpServletResponse.SC_OK).body(isr);
}

( 간결성을 위해 if확인 및 try/ catch제거)

JMeter로이 특정 코드를로드 테스트 할 getContent()때이 단계에서 실패 하는 것을 볼 수 있기 때문에이 섹션에서 문제가 발생 한다고 확신 합니다.

is = Files.newInputStream(f.toPath());

일반적으로 난을 닫을 것이다 InputStream그러나이 짧고 간단하게 코드 때문에 닫을 수 없습니다 스트림 전에 return또는 전화 body.

실행하면 lsof(코드가 Linux에서 실행 됨) 수천 개의 파일이 읽기 모드로 열려 있음을 알 수 있습니다. 따라서이 문제는 스트림이 닫히지 않아 발생한다고 확신합니다.

교환해야하는 모범 사례 코드가 있습니까?

ValerioMC

StreamingResponseBody를 사용해 볼 수 있습니다.

StreamingResponseBody

애플리케이션이 서블릿 컨테이너 스레드를 유지하지 않고 응답 OutputStream에 직접 쓸 수있는 비동기 요청 처리를위한 컨트롤러 메서드 반환 값 유형입니다.

별도의 스레드에서 작업하고 응답에 직접 작성하기 때문에 close()이전 에 호출 해야 할 문제 return가 해결됩니다.

아마도 다음 예제로 시작할 수 있습니다.

public ResponseEntity<StreamingResponseBody> export(...) throws FileNotFoundException {
    //...

    InputStream inputStream = new FileInputStream(new File("/path/to/example/file"));


    StreamingResponseBody responseBody = outputStream -> {

        int numberOfBytesToWrite;
        byte[] data = new byte[1024];
        while ((numberOfBytesToWrite = inputStream.read(data, 0, data.length)) != -1) {
            System.out.println("Writing some bytes..");
            outputStream.write(data, 0, numberOfBytesToWrite);
        }

        inputStream.close();
    };

    return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=generic_file_name.bin")
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(responseBody);
}

사용할 수도 있습니다 Files(Java 7부터)

그래서 당신은 관리 할 필요가 없습니다 InputStream

    File file = new File("/path/to/example/file");

    StreamingResponseBody responseBody = outputStream -> {
        Files.copy(file.toPath(), outputStream);
    };

@ Stackee007이 주석에서 설명했듯이 프로덕션 환경의 부하가 높은 경우 매개 변수를 조정하고 프로세스를 관리하기 @Configuration위해 클래스 를 정의하는 것도 좋은 방법 입니다.TaskExecutorAsync

@Configuration
@EnableAsync
@EnableScheduling
public class AsyncConfiguration implements AsyncConfigurer {

    private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);

    private final TaskExecutionProperties taskExecutionProperties;

    public AsyncConfiguration(TaskExecutionProperties taskExecutionProperties) {
        this.taskExecutionProperties = taskExecutionProperties;
    }

    //  ---------------> Tune parameters here
    @Override
    @Bean(name = "taskExecutor")
    public Executor getAsyncExecutor() {
        log.debug("Creating Async Task Executor");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(taskExecutionProperties.getPool().getCoreSize());
        executor.setMaxPoolSize(taskExecutionProperties.getPool().getMaxSize());
        executor.setQueueCapacity(taskExecutionProperties.getPool().getQueueCapacity());
        executor.setThreadNamePrefix(taskExecutionProperties.getThreadNamePrefix());
        return executor;
    }
    
    //  ---------------> Use this task executor also for async rest methods
    @Bean
    protected WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
                configurer.setTaskExecutor(getTaskExecutor());
            }
        };
    }

    @Bean
    protected ConcurrentTaskExecutor getTaskExecutor() {
        return new ConcurrentTaskExecutor(this.getAsyncExecutor());
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new SimpleAsyncUncaughtExceptionHandler();
    }
}

mockMvc로 테스트하는 방법

통합 테스트에서이 샘플 코드를 다음과 같이 간단히 따를 수 있습니다.

    .andExpect(request().asyncStarted())
    .andDo(MvcResult::getAsyncResult)
    .andExpect(status().isOk()).getResponse().getContentAsByteArray();

이 예제에서 의 내용 유형은 ResponseEntity<StreamingResponseBody>이며 MediaType.APPLICATION_OCTET_STREAMbyte [] ( .getContentAsByteArray())를 얻을 수 있지만 본문 응답 내용 유형에 따라 모든 항목의 String / Json / plaintext를 얻을 수 있습니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

C ++ select를 사용하여 소켓이 닫혔는지 확인하는 방법

포커스 이벤트가 프로그래밍 방식으로 트리거되는지 확인하는 방법

유성에서 여러 "페이지"를 처리하는 적절한 방법

ansible에서 확인되지 않은 적절한 설치를 처리하는 방법

Azure Active Directory 사용자가 이미 적절한 상태인지 확인하는 방법

boto3를 사용하여 AWS EC2 인스턴스 종료가 성공했는지 확인하는 적절한 방법은 무엇입니까?

Joi를 사용하여 사용자 이름이 고유한지 확인하는 방법은 무엇입니까?

사용자가 스트리밍 중인지 확인하고 표시하는 방법이 있습니까?

netflix zuul이 적절한 서비스로 요청을 리디렉션하는지 확인하는 방법

YouTube 채널이 현재 검색을 사용하지 않고 실시간 스트리밍 중인지 확인하는 방법은 무엇입니까?

"simple-peer.js 라이브러리를 사용하여 피어의 연결을 끊고 해당 피어 간의 스트리밍을 중지하는 적절한 방법은 무엇입니까?"

확인하는 방법, 해당 페이지가 적절한 블록으로 자동 스크롤됩니까?

FHIR : 노출 된 JSON이 적절한 FHIR 표준인지 확인하는 방법

웹 애플리케이션이 ReactJ를 사용하고 있는지 확인하는 방법

봇이 Lex에서 음성 또는 텍스트를 사용하고 있는지 확인하는 방법

JAX-RS로 텍스트 데이터를 지속적으로 스트리밍하는 방법

ISP가 토렌트 / 스트리밍 속도를 조절하고 있는지 확인하는 방법은 무엇입니까?

SQL 문이 true 또는 false를 반환하는지 확인하는 적절한 방법은 무엇입니까?

웹 사이트에서 비디오를 스트리밍하는 가장 비용 효율적인 방법

스레드를 해제하고 재사용하는 적절한 방법

C # wpf 애플리케이션을 사용하여 이미지를 스트리밍하는 방법

Rust 공유 라이브러리를 만들고 사용하는 적절한 방법?

하위 폴더에서 어셈블리를 확인하는 적절한 방법

웹 페이지가 동적 ID를 사용하고 있는지 확인하는 방법

이벤트 대리자의 무효를 확인하는 적절한 방법은 무엇입니까?

Django에서 성공적인 POST 요청 후 페이지를 리디렉션하는 가장 적절한 방법

FXML 컨트롤러에서 응용 프로그램이 닫히는 지 확인하는 방법

브로드 캐스트 관리자를 사용하지 않고 앱 내에서 인터넷이 꺼져 있거나 켜져 있는지 확인한 방법

거대한 페이지를 출시하는 적절한 방법?

TOP 리스트

  1. 1

    셀레늄의 모델 대화 상자에서 텍스트를 추출하는 방법은 무엇입니까?

  2. 2

    Webpack 4가 분할 모듈로 취급하는 원시 JSON 파일을 배포하는 방법은 무엇입니까?

  3. 3

    Windows에서 Apache Kafka 오류-주 클래스 QuorumPeerMain을 찾거나로드 할 수 없습니다.

  4. 4

    Zookeeper Cluster를 시작합니다. 오류 : 주 클래스 org.apache.zookeeper.server.quorum.QuorumPeerMain을 찾거나로드 할 수 없습니다.

  5. 5

    어떻게 reslove: InvalidArgumentError: 그래프 실행 오류가 발생합니까?

  6. 6

    PyCharm에서 프로젝트를 제거하는 방법은 무엇입니까?

  7. 7

    Python : 특정 범위를 초과하면 플롯의 선 색상을 변경할 수 있습니까?

  8. 8

    동적 링크 작동 방식, 사용법 및 dylib를 만드는 방법과 이유

  9. 9

    화살표와 테두리가있는 CSS 전용 툴팁

  10. 10

    웹 사이트 로딩 속도를 높이는 방법을 알려주세요.

  11. 11

    응답에 대한 JMESPath 필터링

  12. 12

    D3 JS에서 하프 도넛 원형 차트 값 표시

  13. 13

    Joomla 3의 단일 기사에서 소셜 미디어 아이콘을 게시 취소하는 방법은 무엇입니까?

  14. 14

    scipy.misc 이미지 함수의 AttributeError, ImportError (예 : imread, imresize, imsave, imshow 등)

  15. 15

    Xcode 6 Beta 4 Broke stringWithContentsOfURL : encoding : error :

  16. 16

    Java에서 HSSFCell의 최대 길이 늘리기

  17. 17

    Mac에서 python import nltk 오류

  18. 18

    오류 CS0019 : '<'연산자를 'string'및 'int'유형의 피연산자에 적용 할 수 없습니다.

  19. 19

    Libavformat은 RTP 스트림을 너무 빠르게 기록합니다(너무 높은 FPS).

  20. 20

    Linux 시스템에 대해 OPEN_MAX는 어디에 정의되어 있습니까?

  21. 21

    스프링 부트에서 application.properties 값을 동적으로 변경

뜨겁다태그

보관