简体   繁体   English

我在springboot中有一个兔子amqp监听器,它在没有关闭应用程序的情况下卡住了

[英]I have an rabbit amqp listener in springboot, It stucks without closing the application

I have the following code snippet in my actual code. 我在实际代码中有以下代码段。 I have mutiple consumers listening to a queue. 我有多个消费者在听队列。

 @RabbitListener
 private void abc(ETLConfigDTO config){
  try{
   log.info("load started");
   loadService.loadData(config);
  }
  catch(Exception e){
   log.error("Load failed"):
  }
  finally{
   log.info("finished processing"):
  }
 }

loadData() takes few minutes to few hours of processing. loadData()需要几分钟到几个小时的处理。 Its kind of etl processing. 它的etl处理类型。 There is intensove logging inside this method, so i know in which state the process is. 此方法内部有强化记录,因此我知道该过程处于哪种状态。 The problem is that the process is kind of stuck inside loadPlans() method. 问题是该进程有点卡在loadPlans()方法中。 The message in the queue is in unacknowledged state since it is still processing which i need in that way. 队列中的消息处于未确认状态,因为它仍然以这种方式处理我需要的状态。 There is no exception since catch is not printing anything or even the finally block. 没有例外,因为catch没有打印任何东西甚至是finally块。 I also have a spring cron (5 minutes interval) in the same class which is also running fine and doing its tasks. 我在同一个班级也有一个弹簧cron(间隔5分钟),它也运行正常并完成任务。

The point to note is that this is running fine if I not use rabbit amqp. 需要注意的是,如果我不使用兔子amqp,这个运行正常。

Is there any connection/network drop? 是否有任何连接/网络丢失? Or any timeout? 还是超时? Or the main thread is hung/dead? 或主线程挂/死? I am really not understanding what is happening here. 我真的不明白这里发生了什么。

Thanks in advance. 提前致谢。

UPDATE: Thanks Gary , I see this in jstack 19 : 更新:谢谢Gary ,我在jstack 19看到了这个:

"SimpleAsyncTaskExecutor-1" #25 prio=5 os_prio=0 tid=0x00007f5615b3d800 nid=0x2f runnable [0x00007f56703cd000]
   java.lang.Thread.State: RUNNABLE
        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:983)
        - locked <0x000000067a6bada8> (a java.lang.Object)
        at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:940)
        at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
        - locked <0x000000067a6baea0> (a sun.security.ssl.AppInputStream)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
        - locked <0x000000067a717cb8> (a java.io.BufferedInputStream)
        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:1569)
        - locked <0x000000067a6b4b60> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1474)
        - locked <0x000000067a6b4b60> (a sun.net.www.protocol.https.DelegateHttpsURLConnection)
        at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)
        at org.springframework.http.client.SimpleClientHttpResponse.getRawStatusCode(SimpleClientHttpResponse.java:48)
        at org.springframework.http.client.AbstractClientHttpResponse.getStatusCode(AbstractClientHttpResponse.java:33)
        at org.springframework.web.client.DefaultResponseErrorHandler.getHttpStatusCode(DefaultResponseErrorHandler.java:56)
        at org.springframework.web.client.DefaultResponseErrorHandler.hasError(DefaultResponseErrorHandler.java:50)
        at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:602)
        at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:570)
        at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:530)
        at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:448)
..
...
...
...


Please advise.

NEW UPDATE: I have increase memory -XX:MaxMetaspaceSize=1024M -Xms4096M -Xmx4096M 新更新:我增加了内存-XX:MaxMetaspaceSize = 1024M -Xms4096M -Xmx4096M

The thread is being stuck on oracle connection now. 该线程现在卡在oracle连接上。

"SimpleAsyncTaskExecutor-1" #25 prio=5 os_prio=0 tid=0x00007ff6102c8800 nid=0x33 runnable [0x00007ff619ad9000]
   java.lang.Thread.State: RUNNABLE
        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 oracle.net.ns.Packet.receive(Packet.java:300)
        at oracle.net.ns.DataPacket.receive(DataPacket.java:106)
        at oracle.net.ns.NetInputStream.getNextPacket(NetInputStream.java:315)
        at oracle.net.ns.NetInputStream.read(NetInputStream.java:260)
        at oracle.net.ns.NetInputStream.read(NetInputStream.java:185)
        at oracle.net.ns.NetInputStream.read(NetInputStream.java:102)
        at oracle.jdbc.driver.T4CSocketInputStreamWrapper.readNextPacket(T4CSocketInputStreamWrapper.java:124)
        at oracle.jdbc.driver.T4CSocketInputStreamWrapper.read(T4CSocketInputStreamWrapper.java:80)
        at oracle.jdbc.driver.T4CMAREngine.unmarshalUB1(T4CMAREngine.java:1137)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:290)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
        at oracle.jdbc.driver.T4CStatement.doOall8(T4CStatement.java:193)
        at oracle.jdbc.driver.T4CStatement.executeForRows(T4CStatement.java:1033)
        at oracle.jdbc.driver.OracleStatement.executeBatch(OracleStatement.java:4536)
        - locked <0x00000007b01c6b20> (a oracle.jdbc.driver.T4CConnection)
        at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
        at org.springframework.jdbc.core.JdbcTemplate$1BatchUpdateStatementCallback.doInStatement(JdbcTemplate.java:572)
        at org.springframework.jdbc.core.JdbcTemplate$1BatchUpdateStatementCallback.doInStatement(JdbcTemplate.java:559)
        at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:405)
        at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:611)
...
...

Your listener is rather unusual; 你的听众很不寻常; in most cases it would be void listen(SomeObject) where the listener processes the object and exits and the message is acknowledged. 在大多数情况下,它将是void listen(SomeObject) ,其中侦听器处理对象并退出并且消息被确认。

You appear to be ignoring the contents of the message and simply using its presence to trigger loadData() . 您似乎忽略了消息的内容,只是使用其存在来触发loadData()

Regardless, by default, the message won't be acknowledged until the method exits; 无论如何,默认情况下,在方法退出之前不会确认消息; the container thread will remain in the listener method until it exits. 容器线程将保留在侦听器方法中,直到它退出。

The default acknowledge mode for the container is AUTO which means the container will automatically acknowledge (or reject) the message when the method exits. 容器的默认确认模式为AUTO,这意味着容器将在方法退出时自动确认(或拒绝)消息。

You can change the acknowledge mode to NONE which means RabbitMQ does not require an acknowledgment at all and will remove the message immediately. 您可以将确认模式更改为NONE,这意味着RabbitMQ根本不需要确认,并将立即删除该消息。

However, the container thread will still run in the method until the method exits. 但是,容器线程仍将在方法中运行,直到该方法退出。

The message will be lost if the application crashes. 如果应用程序崩溃,该消息将丢失。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM