Spring Boot Thread Pool metrics - spring

we have a Spring Boot application which, as the load increases, becomes unresponsive. We have checked the CPU, RAM and Database connections and we cannot see any peak for them.
However, there are about 200 threads with the same Stack Trace:
-Spring #Service invoked here
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:892)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
I think this could be a bottleneck in some thread pools. Which are the metrics that I should check? tomcat thread pool size ? anything more specific for mvc?
Thanks a lot

A good metric to begin with is probably the current thread count inside the JVM.
You can use:
//only own Threadgroup
Thread.activeCount();
// all Threads, using JMX API
ManagementFactory.getThreadMXBean().getThreadCount();
Or you can use an external tool like Java VisualVM
I suggest using thread dumps to home in on the issue. You could create thread dumps every 10 seconds or so and store them until the error occurs.
If you have storage issues with this, remove older dumps, as we are only interested in the dumps surrounding the incident.
Subsequently, you can analyze the dumps using JProfiler
I also found this article regarding thread dump analyzing and this article regarding thread counting very helpful.

Related

Usage of micrometer-registry-prometheus slow down my Spring Boot application

I have Spring Boot application 2.5.7 where I set up a micrometer to scrape metrics
runtimeOnly("io.micrometer:micrometer-registry-prometheus")
When I make a request locally http://localhost:8081/actuator/prometheus
There are no performance problems with my application
But when I make a request to the actuator on the server with a high load
https://myserver:8081/actuator/prometheus
it returns a lot more data in response and it also slows down all request that is currently running on my server.
The problem appears even after one request to /actuator/prometheus
Is there any way to optimize the micrometer work(while returning the same ammount of metrics), so it will not slow down my application?
Without sufficient data it is hard to give a recommendation. If the slowness is due to insufficient memory/garbage collection, try increasing the memory of your application.
Reviewing the metrics being returned may also give you some ideas, for example if you have a high thread count, I think there is a pause when Micrometer iterates over the thread statuses. You could look into disabling that metric.

Caused by: java.net.SocketTimeoutException: Read timed out

I have a spring boot 2.x application that is making a soap call using JaxWsProxyFactoryBean to make the calls. All of the calls are working flawlessly except for one that is getting "java.net.SocketTimeoutException: Read timed out". Things to note:
My application is having no problems with soap calls within my network.
The only soap call having an issue is outside of my network and the issue is sporadic
From network traces it also appears my application is reusing connections (connection pooling)
My application makes millions of calls per day to both the internal (working soap serivces) and the external service that is having the blips
Questions:
How do I configure http connection pooling in spring boot 2.0?
Is it likely the issue will go away if I disable HTTP connection pooling?
What type of performance hit (estimate in ms) am I looking at if I disable HTTP connection pooling?
What could the causes of my issue be if its not related to the connection pool?
If you need any other details please let me know.
Partial Stack Trace:
Caused by: java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.net.SocketInputStream.read(SocketInputStream.java:141)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
at sun.security.ssl.InputRecord.read(InputRecord.java:503)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:933)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:735)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:678)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1587)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1492)
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:347)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream$2.run(URLConnectionHTTPConduit.java:377)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream$2.run(URLConnectionHTTPConduit.java:373)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.cxf.transport.http.URLConnectionHTTPConduit$URLConnectionWrappedOutputStream.getResponseCode(URLConnectionHTTPConduit.java:373)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.doProcessResponseCode(HTTPConduit.java:1597)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1625)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1570)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1371) ...
Thanks,
Brian

Inifnispan server stop responding (near cache configured , clustered environment, client server configuration)

We have been facing infinispan server issue while we are testing our application with 100 concurrent active session each cluster node of our application.
Infinispan server configuration.
Two Domain with Two node
Near Cache is configured,INVALIDATE type , with no max entry limit.
our Application is having two cluster node as well.
Infinispan version : 8.2.3
Error we are finding in infinispan server:
2017-06-08 18:49:18,464 DEBUG [org.infinispan.server.hotrod.HotRodExceptionHandler] (HotRodServerWorker-8-7) Exception caught: java.io.IOException: An existing connection was forcibly closed by the remote host
at sun.nio.ch.SocketDispatcher.read0(Native Method)
at sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:223)
at sun.nio.ch.IOUtil.read(IOUtil.java:192)
at sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:380)
at io.netty.buffer.PooledUnsafeDirectByteBuf.setBytes(PooledUnsafeDirectByteBuf.java:221)
at io.netty.buffer.AbstractByteBuf.writeBytes(AbstractByteBuf.java:898)
at io.netty.channel.socket.nio.NioSocketChannel.doReadBytes(NioSocketChannel.java:242)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:119)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:528)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:485)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:399)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:371)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)
After getting this error, we tried disabling near cache with infinispan server. That configuration get the things correct but It also result in very slow performance which is not acceptable as we are using infinispan server for performance purpose only.
Our Template using which we are creating cache container in Infinispan
<distributed-cache-configuration name="OurTempateName" owners="2" segments="20" mode="SYNC" remote-timeout="30000" start="EAGER">
<locking striping="false" acquire-timeout="30000" concurrency-level="1000"/>
<transaction mode="NONE"/>
<security/>
</distributed-cache-configuration>
With Client server infinispan setup, Can anyone suggest configuration which can overcome this issue?
If you see that kind of messages, they might indicate that there is some problem with the client. Did you look into client logs?

Spring Integration is hanging WebSphere Liberty thread

I have a Spring + Spring Integration + Hibernate WebApp deployed in a WebSphere Liberty Application Server.
Sometimes, when i try to Stop the application, the server goes down.
I see this in the Log:
[12/16/15 9:27:27:146 CET] 00000096 webapp I com.ibm.ws.webcontainer.webapp.WebApp log SRVE0292I: Servlet Message - [CATAPP#web-0.0.1-SNAPSHOT.war]:.Destroying Spring FrameworkServlet 'IntegrationContext'
[12/16/15 9:39:36:112 CET] 000000f1 ThreadMonitor W WSVR0605W: Thread "Default : 2" (00000096) has been active for 729034 milliseconds and may be hung. There is/are 1 thread(s) in total in the server that may be hung.
And there is no more info. I need to restart the WebSphere node to start the application again.
I know it's difficult, but somebody knows what may be the problem ? Thanks.
When you hit this situation, take a thread dump (jstack, jvisualvm etc) and look to see what the thread is doing. For example, it might be reading from a socket with a long (or no) timeout. If you can't figure it out, post the thread dump someplace.

Spring data Neo4J does not create all the properties of a node for HAProxy cluster

We have created a Neo4J cluster which uses HAProxy as a load balancer using the documentation available at http://neo4j.com/docs/stable/ha-haproxy.html.
We are using Spring Data Neo4J graph repositories in our application server to create nodes on the Neo4J cluster.
We have separated the read and write Neo4J servers and trying to create a node on the Neo4J write server but when the application server sends a request to Neo4J write server it only creates node with only one property and throws following exception.We are sending write requests to Neo4j master and reads are from all instances.
Infrastructure used-
Neo4j instances on E2 servers.
HA proxy for load balancing on top of Neo4j servers.
Neo4j has no public IPs so it can be accessed only through app server.
java.lang.IllegalStateException: error adding labels, received org.neo4j.rest.graphdb.RequestResult#31ccc77f
at org.neo4j.rest.graphdb.ExecutingRestAPI.addLabels(ExecutingRestAPI.java:303)
at org.neo4j.rest.graphdb.RestAPIFacade.addLabels(RestAPIFacade.java:319)
at org.springframework.data.neo4j.rest.SpringRestGraphDatabase.createNode(SpringRestGraphDatabase.java:71)
at org.springframework.data.neo4j.support.mapping.EntityStateHandler.createNode(EntityStateHandler.java:151)
at org.springframework.data.neo4j.support.mapping.EntityStateHandler.useOrCreateState(EntityStateHandler.java:142)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityConverterImpl.write(Neo4jEntityConverterImpl.java:163)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister$CachedConverter.write(Neo4jEntityPersister.java:179)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:243)
at org.springframework.data.neo4j.support.mapping.Neo4jEntityPersister.persist(Neo4jEntityPersister.java:231)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:357)
at org.springframework.data.neo4j.support.Neo4jTemplate.save(Neo4jTemplate.java:351)
at org.springframework.data.neo4j.repository.AbstractGraphRepository.save(AbstractGraphRepository.java:91)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:442)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:427)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
You have to provide more details about your code, routing setup etc.
And how the routing is affecting the code (request) execution.
Also if you do reads after writes, you have to make sure that these requests are also routed to the server that you wrote to.
You might also want to try SDN 3.3.M1 with the new SpringCypherRestGraphDatabase which uses the transactional endpoint to create data over the wire transactionally. Just to see if it works better.

Resources