spring Sping Boot webclient多个post API调用:打开的文件太多

ss2ws0br  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(44)

我的spring Boot 应用程序处理计划的批处理作业,其中涉及到在一个批处理作业中对配置的api的数千个post API调用。这些调用在线程池中同时处理。
下面是用于每个API调用的方法。它与其他API调用没有任何共享资源。

private <T> String getResponseV2(String deviceConnection, String uri, T body, Consumer<HttpHeaders> headersConsumer) {
        SslContext sslContext = null;
        try {
            sslContext = SslContextBuilder
                    .forClient()
                    .trustManager(InsecureTrustManagerFactory.INSTANCE)
                    .build();
        } catch (SSLException e) {
            log.error("Error creating ssl context: {}",e.getLocalizedMessage());
            log.error("Error: ",e);
            return null;
        }

        SslContext finalSslContext = sslContext;
        TcpClient tcpClient = TcpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(finalSslContext));
        HttpClient httpClient = HttpClient.from(tcpClient).wiretap("reactor.netty.http.client.HttpClient",
                LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL).responseTimeout(Duration.ofSeconds(20));

        return WebClient.builder()
                .baseUrl(deviceConnection)
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build()
                .post().uri(uri)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .headers(headersConsumer)
                .body(Mono.just(body), body.getClass())
                .retrieve()
                /*.onStatus(HttpStatus::isError, res -> {
                    log.info("Webclient Response {}", res.bodyToMono(String.class));
                    return Mono.error(new IllegalStateException("Failed to Fetch Data"));
                })*/
                .bodyToMono(String.class).block();
    }

字符串
在每个单独的作业中,这个函数被调用两次,一次用于获取auth token,另一次用于实际的post API调用。
我的问题是我不完全熟悉webclient,不确定这是否是我使用webclient的正确方法,或者这是否会泄漏资源。
这是因为在一些测试运行后,我在我的服务中得到了以下异常:

Caused by: io.netty.channel.ChannelException: io.netty.channel.unix.Errors$NativeIoException: newSocketDgram(..) failed: Too many open files
    at io.netty.channel.unix.Socket.newSocketDgram0(Socket.java:442)
    at io.netty.channel.epoll.LinuxSocket.newSocketDgram(LinuxSocket.java:327)
    at io.netty.channel.epoll.EpollDatagramChannel.<init>(EpollDatagramChannel.java:84)
    at io.netty.channel.epoll.EpollDatagramChannel.<init>(EpollDatagramChannel.java:75)
    at reactor.netty.resources.DefaultLoopEpoll.getChannel(DefaultLoopEpoll.java:55)
    at reactor.netty.resources.LoopResources.onChannel(LoopResources.java:214)
    at reactor.netty.tcp.TcpResources.onChannel(TcpResources.java:208)
    at reactor.netty.transport.NameResolverProvider.lambda$newNameResolverGroup$0(NameResolverProvider.java:415)
    at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:310)
    at io.netty.bootstrap.AbstractBootstrap.register(AbstractBootstrap.java:227)
    at io.netty.resolver.dns.DnsNameResolver.<init>(DnsNameResolver.java:456)
    at io.netty.resolver.dns.DnsNameResolverBuilder.build(DnsNameResolverBuilder.java:476)
    at io.netty.resolver.dns.DnsAddressResolverGroup.newNameResolver(DnsAddressResolverGroup.java:114)
    at io.netty.resolver.dns.DnsAddressResolverGroup.newResolver(DnsAddressResolverGroup.java:92)
    at io.netty.resolver.dns.DnsAddressResolverGroup.newResolver(DnsAddressResolverGroup.java:77)
    at io.netty.resolver.AddressResolverGroup.getResolver(AddressResolverGroup.java:70)
    ... 12 common frames omitted


这些要么是伴随着这个

tack trace:
        at org.springframework.web.reactive.function.client.ExchangeFunctions$DefaultExchangeFunction.lambda$wrapException$9(ExchangeFunctions.java:137)
        at reactor.core.publisher.MonoErrorSupplied.subscribe(MonoErrorSupplied.java:70)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4046)
        at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:103)
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:221)
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:221)
        at reactor.core.publisher.FluxPeek$PeekSubscriber.onError(FluxPeek.java:221)
        at reactor.core.publisher.MonoNext$NextSubscriber.onError(MonoNext.java:93)
        at reactor.core.publisher.MonoFlatMapMany$FlatMapManyMain.onError(MonoFlatMapMany.java:204)
        at reactor.core.publisher.SerializedSubscriber.onError(SerializedSubscriber.java:124)
        at reactor.core.publisher.FluxRetryWhen$RetryWhenMainSubscriber.whenError(FluxRetryWhen.java:224)
        at reactor.core.publisher.FluxRetryWhen$RetryWhenOtherSubscriber.onError(FluxRetryWhen.java:273)
        at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:413)
        at reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onNext(FluxConcatMap.java:250)
        at reactor.core.publisher.EmitterProcessor.drain(EmitterProcessor.java:491)
        at reactor.core.publisher.EmitterProcessor.tryEmitNext(EmitterProcessor.java:299)
        at reactor.core.publisher.SinkManySerialized.tryEmitNext(SinkManySerialized.java:97)
        at reactor.core.publisher.InternalManySink.emitNext(InternalManySink.java:27)
        at reactor.core.publisher.FluxRetryWhen$RetryWhenMainSubscriber.onError(FluxRetryWhen.java:189)
        at reactor.core.publisher.MonoCreate$DefaultMonoSink.error(MonoCreate.java:189)
        at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect$ClientTransportSubscriber.onError(HttpClientConnect.java:306)
        at reactor.core.publisher.MonoCreate$DefaultMonoSink.error(MonoCreate.java:189)
        at reactor.netty.resources.DefaultPooledConnectionProvider$DisposableAcquire.onError(DefaultPooledConnectionProvider.java:166)
        at reactor.netty.internal.shaded.reactor.pool.AbstractPool$Borrower.fail(AbstractPool.java:427)
        at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.lambda$drainLoop$5(SimpleDequePool.java:310)
        at reactor.core.publisher.FluxDoOnEach$DoOnEachSubscriber.onError(FluxDoOnEach.java:186)
        at reactor.core.publisher.MonoCreate$DefaultMonoSink.error(MonoCreate.java:189)
        at reactor.netty.resources.DefaultPooledConnectionProvider$PooledConnectionAllocator$PooledConnectionInitializer.onError(DefaultPooledConnectionProvider.java:565)
        at reactor.core.publisher.Operators.error(Operators.java:196)
        at reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:134)
        at reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53)
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
        at reactor.netty.resources.DefaultPooledConnectionProvider$PooledConnectionAllocator.lambda$connectChannel$0(DefaultPooledConnectionProvider.java:525)
        at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4046)
        at reactor.core.publisher.Mono.subscribeWith(Mono.java:4161)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4017)
        at reactor.core.publisher.Mono.subscribe(Mono.java:3953)
        at reactor.core.publisher.Mono.subscribe(Mono.java:3925)
        at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:318)
        at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.drain(SimpleDequePool.java:261)
        at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:256)
        at reactor.netty.internal.shaded.reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:382)
        at reactor.netty.resources.DefaultPooledConnectionProvider$DisposableAcquire.onSubscribe(DefaultPooledConnectionProvider.java:206)
        at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:578)
        at reactor.netty.resources.PooledConnectionProvider.lambda$acquire$1(PooledConnectionProvider.java:120)
        at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
        at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.lambda$subscribe$0(HttpClientConnect.java:266)
        at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
        at reactor.core.publisher.FluxRetryWhen.subscribe(FluxRetryWhen.java:76)
        at reactor.core.publisher.MonoRetryWhen.subscribeOrReturn(MonoRetryWhen.java:46)
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
        at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:269)
        at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
        at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
        at reactor.core.publisher.Mono.subscribe(Mono.java:4046)
        at reactor.core.publisher.Mono.block(Mono.java:1702)
        at .service.AirLinkOSDeviceServiceWebClientImpl.getResponseV2(AirLinkOSDeviceServiceWebClientImpl.java:197)
        at .service.AirLinkOSDeviceServiceWebClientImpl.setConfigurationItemV2(AirLinkOSDeviceServiceWebClientImpl.java:119)
        at .service.DeviceScheduledJobAsyncService.processApi(DeviceScheduledJobAsyncService.java:71)
        at .service.DeviceScheduledJobAsyncService.processDeviceJob(DeviceScheduledJobAsyncService.java:44)
        at .service.DeviceScheduledJobAsyncService$$FastClassBySpringCGLIB$$ba9a8368.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
        at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:750)
    Suppressed: java.lang.Exception: #block terminated with an error
        at reactor.core.publisher.BlockingSingleSubscriber.blockingGet(BlockingSingleSubscriber.java:99)
        at reactor.core.publisher.Mono.block(Mono.java:1703)
        at .service.AirLinkOSDeviceServiceWebClientImpl.getResponseV2(AirLinkOSDeviceServiceWebClientImpl.java:197)
        at .service.AirLinkOSDeviceServiceWebClientImpl.setConfigurationItemV2(AirLinkOSDeviceServiceWebClientImpl.java:119)
        at .service.DeviceScheduledJobAsyncService.processApi(DeviceScheduledJobAsyncService.java:71)
        at .service.DeviceScheduledJobAsyncService.processDeviceJob(DeviceScheduledJobAsyncService.java:44)
        at .service.DeviceScheduledJobAsyncService$$FastClassBySpringCGLIB$$ba9a8368.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
        at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
        at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:750)
Caused by: io.netty.channel.ChannelException: io.netty.channel.unix.Errors$NativeIoException: newSocketStream(..) failed: Too many open files
    at io.netty.channel.unix.Socket.newSocketStream0(Socket.java:430)
    at io.netty.channel.epoll.LinuxSocket.newSocketStream(LinuxSocket.java:319)
    at io.netty.channel.epoll.LinuxSocket.newSocketStream(LinuxSocket.java:323)
    at io.netty.channel.epoll.EpollSocketChannel.<init>(EpollSocketChannel.java:45)
    at reactor.netty.resources.DefaultLoopEpoll.getChannel(DefaultLoopEpoll.java:49)
    at reactor.netty.resources.LoopResources.onChannel(LoopResources.java:214)
    at reactor.netty.tcp.TcpResources.onChannel(TcpResources.java:208)
    at reactor.netty.transport.TransportConfig.lambda$connectionFactory$0(TransportConfig.java:265)
    at reactor.netty.transport.TransportConnector.doInitAndRegister(TransportConnector.java:171)
    at reactor.netty.transport.TransportConnector.connect(TransportConnector.java:102)
    at reactor.netty.resources.DefaultPooledConnectionProvider$PooledConnectionAllocator.lambda$connectChannel$0(DefaultPooledConnectionProvider.java:524)
    at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4046)
    at reactor.core.publisher.Mono.subscribeWith(Mono.java:4161)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4017)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3953)
    at reactor.core.publisher.Mono.subscribe(Mono.java:3925)
    at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.drainLoop(SimpleDequePool.java:318)
    at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.drain(SimpleDequePool.java:261)
    at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool.doAcquire(SimpleDequePool.java:256)
    at reactor.netty.internal.shaded.reactor.pool.AbstractPool$Borrower.request(AbstractPool.java:382)
    at reactor.netty.resources.DefaultPooledConnectionProvider$DisposableAcquire.onSubscribe(DefaultPooledConnectionProvider.java:206)
    at reactor.netty.internal.shaded.reactor.pool.SimpleDequePool$QueueBorrowerMono.subscribe(SimpleDequePool.java:578)
    at reactor.netty.resources.PooledConnectionProvider.lambda$acquire$1(PooledConnectionProvider.java:120)
    at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
    at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.lambda$subscribe$0(HttpClientConnect.java:266)
    at reactor.core.publisher.MonoCreate.subscribe(MonoCreate.java:57)
    at reactor.core.publisher.FluxRetryWhen.subscribe(FluxRetryWhen.java:76)
    at reactor.core.publisher.MonoRetryWhen.subscribeOrReturn(MonoRetryWhen.java:46)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:57)
    at reactor.netty.http.client.HttpClientConnect$MonoHttpConnect.subscribe(HttpClientConnect.java:269)
    at reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64)
    at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52)
    at reactor.core.publisher.Mono.subscribe(Mono.java:4046)
    at reactor.core.publisher.Mono.block(Mono.java:1702)
    at .service.AirLinkOSDeviceServiceWebClientImpl.getResponseV2(AirLinkOSDeviceServiceWebClientImpl.java:197)
    at .service.AirLinkOSDeviceServiceWebClientImpl.setConfigurationItemV2(AirLinkOSDeviceServiceWebClientImpl.java:119)
    at .service.DeviceScheduledJobAsyncService.processApi(DeviceScheduledJobAsyncService.java:71)
    at .service.DeviceScheduledJobAsyncService.processDeviceJob(DeviceScheduledJobAsyncService.java:44)
    at .service.DeviceScheduledJobAsyncService$$FastClassBySpringCGLIB$$ba9a8368.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: io.netty.channel.unix.Errors$NativeIoException: newSocketStream(..) failed: Too many open files


或本

org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:467)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.startTransaction(AbstractPlatformTransactionManager.java:400)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:373)
    at sun.reflect.GeneratedMethodAccessor78.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:128)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
    at com.sun.proxy.$Proxy152.getTransaction(Unknown Source)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSupport.java:595)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:382)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:174)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215)
    at com.sun.proxy.$Proxy149.save(Unknown Source)
    at .service.DeviceScheduledJobAsyncService.processApi(DeviceScheduledJobAsyncService.java:99)
    at .service.DeviceScheduledJobAsyncService.processDeviceJob(DeviceScheduledJobAsyncService.java:44)
    at .service.DeviceScheduledJobAsyncService$$FastClassBySpringCGLIB$$ba9a8368.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:771)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:750)
Caused by: org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:111)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getPhysicalConnection(LogicalConnectionManagedImpl.java:138)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.getConnectionForTransactionManagement(LogicalConnectionManagedImpl.java:273)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.begin(LogicalConnectionManagedImpl.java:281)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.begin(JdbcResourceLocalTransactionCoordinatorImpl.java:246)
    at org.hibernate.engine.transaction.internal.TransactionImpl.begin(TransactionImpl.java:83)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.beginTransaction(HibernateJpaDialect.java:164)
    at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:421)
    ... 36 common frames omitted
Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:315)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:51)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:225)
    at org.postgresql.Driver.makeConnection(Driver.java:465)
    at org.postgresql.Driver.connect(Driver.java:264)
    at java.sql.DriverManager.getConnection(DriverManager.java:664)
    at java.sql.DriverManager.getConnection(DriverManager.java:208)
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriverManager(DriverManagerDataSource.java:155)
    at org.springframework.jdbc.datasource.DriverManagerDataSource.getConnectionFromDriver(DriverManagerDataSource.java:146)
    at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnectionFromDriver(AbstractDriverBasedDataSource.java:205)
    at org.springframework.jdbc.datasource.AbstractDriverBasedDataSource.getConnection(AbstractDriverBasedDataSource.java:169)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
    at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:38)
    at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:108)
    ... 43 common frames omitted
Caused by: java.net.SocketException: Too many open files
    at java.net.Socket.createImpl(Socket.java:478)
    at java.net.Socket.connect(Socket.java:605)
    at org.postgresql.core.PGStream.createSocket(PGStream.java:231)
    at org.postgresql.core.PGStream.<init>(PGStream.java:95)
    at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213)
    ... 56 common frames omitted
2023-12-13 08:13:51,459  WARN [b7403dc2-fc7c-4249-9b61-dbb98cb96e8d] org.hibernate.engine.jdbc.spi.SqlExceptionHelper [FunctionThread-9] SQL Error: 0, SQLState: 08001
2023-12-13 08:13:51,459  ERROR [b7403dc2-fc7c-4249-9b61-dbb98cb96e8d] org.hibernate.engine.jdbc.spi.SqlExceptionHelper [FunctionThread-9] The connection attempt failed.


无论哪种方式,罪魁祸首似乎是太多的打开文件。
我有点失落,因为我不能确切地指出问题是什么,我能做些什么来解决它。
我在Docker容器中运行我的应用程序。
增加文件描述符限制是唯一的解决办法吗?

f3temu5u

f3temu5u1#

你的应用程序在每个HTTP调用上都要创建大量的基本资源。例如,SSL上下文之类的东西在整个应用程序中几乎是固定的。如果这些资源中的一些包括连接池之类的东西,那么你就在每个请求上创建了一个新的连接池;这将导致你看到的资源耗尽。
在非常普遍的意义上,你会希望在应用程序中只创建一次像SslContextHttpClient这样的对象,然后在需要的时候将它们传递到对象中。Spring的核心功能之一是依赖注入系统,它提供了一种标准的方法来创建这些对象一次,并在需要的时候将它们注入到对象中。
但更具体地说,Sping Boot 已经包含了自己创建大部分这些东西的逻辑。你根本不需要创建任何这些对象。要求Sping Boot 将WebClient.Builder传递给你的对象的构造函数,它会照办的。

@Component
public class MyService {
  private final WebClient.Builder webClientBuilder;

  public MyService(WebClient.Builder webClientBuilder) {
    this.webClientBuilder = webClientBuilder;
  }

 private <T> String getResponseV2(
    String deviceConnection,
    String uri,
    T body,
    Consumer<HttpHeaders> headersConsumer
  ) {
    // without creating any of the other objects
    return WebClient.builder()
      .clone()
      .baseUrl(deviceConnection)
      .build()
      .post().uri(uri)
      ...;
  }
}

字符串
Sping Boot 文档提供了有关注入和配置WebClient的更多信息。如果您确实需要自定义TLS配置,例如,有一个Spring特定的路径,您可以在其中提供WebClientSsl对象,而无需从头开始构建整个对象堆栈。

相关问题