Как вы очищаете Spring WebClient? - PullRequest
0 голосов
/ 18 марта 2020

Когда я использую WebClient в не загружаемом устаревшем приложении JEE, работающем на Tomcat. Похоже, я получаю это при завершении работы

Mar 17, 2020 8:46:25 PM org.apache.catalina.loader.WebappClassLoaderBase clearReferencesThreads
WARNING: The web application [ROOT] appears to have started a thread named [reactor-http-epoll-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 io.netty.channel.epoll.Native.epollWait(Native Method)
 io.netty.channel.epoll.Native.epollWait(Native.java:129)
 io.netty.channel.epoll.Native.epollWait(Native.java:122)
 io.netty.channel.epoll.EpollEventLoop.epollWaitNoTimerChange(EpollEventLoop.java:290)
 io.netty.channel.epoll.EpollEventLoop.run(EpollEventLoop.java:347)
 io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
 io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
 io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
 java.base@11.0.4/java.lang.Thread.run(Thread.java:834)

Однако я не могу найти какой-либо способ "очистки" или завершения процесса netty, который он использует.

У меня уже есть следующее в методе @PreDestroy, но, похоже, не помогает.

FastThreadLocal.removeAll();
Class.forName("io.netty.util.internal.InternalThreadLocalMap").getMethod("destroy").invoke(null);

Я использовал WebClient для передачи файла во внешнюю конечную точку сервиса миниатюр с помощью данных формы, но оттуда я не Не вижу точки утечки.

public Path createThumbnail(final Path src) {

        final MultipartBodyBuilder bodyBuilder = new MultipartBodyBuilder();
        bodyBuilder.part("file", new PathResource(src));

        Path thumbnailPath = computeThumbnailPath(src);

        final WebClient webClient = WebClient.create("http://thumbnail-generator:8080/api/upload/file");
        webClient.post()
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData(bodyBuilder.build()))
            .exchange()
            .flatMap(r -> r.bodyToMono(ByteArrayResource.class))
            .map(r -> {
                try (final InputStream s = r.getInputStream()) {
                    return Files.copy(s, thumbnailPath);
                } catch (IOException e) {
                    throw new UncheckedIOException(e);
                }
            })
            .block();
        return thumbnailPath;
    }
...