JBoss AS7 hängt nach dem MDB-lock
Ich bin derzeit immer eine intermittierende Ausnahme in JBoss AS7, dass ich leider noch nicht reproduzieren.
Sind wir derzeit betreiben von zwei Anwendungen, die im wesentlichen als Produzent/Verbraucher der JMS-Nachrichten. Wir sind mit der Standard-Konfiguration HornetQ und einen pool von 5 MDBs.
Beide Anwendungen beginnt dabei ok, senden und empfangen von Nachrichten, wie erwartet. Aber nach einer Weile, alle MDB-Dateien gesperrt werden (Sie erhalten jeweils eine Meldung, aber nicht mit der Bearbeitung fertig) und JBoss hängt einige Zeit nach, zeigt die folgende Meldung alle zehn Minuten:
[org.jboss.ejb3.invocation] (Thread-21081 (HornetQ-client-global-threads-1636833629)) JBAS014134: EJB Invocation failed on component MyMessageListener for method public abstract void javax.jms.MessageListener.onMessage(javax.jms.Message): javax.ejb.EJBException: JBAS014516: Failed to acquire a permit within 10 MINUTES
Vom JBoss-code in jarvana, es scheint, als ob dieser Fehler wird gesetzt, wenn ein semaphor kann nicht erworben werden:
/**
* Get an instance without identity.
* Can be used by finders,create-methods, and activation
*
* @return Context /w instance
*/
public T get() {
try {
boolean acquired = semaphore.tryAcquire(timeout, timeUnit);
if (!acquired)
throw new EJBException("Failed to acquire a permit within " + timeout + " " + timeUnit);
} catch (InterruptedException e) {
throw new EJBException("Acquire semaphore was interrupted");
}
...
Die Sache ist die, warum die multilateralen Entwicklungsbanken gesperrt? Sollten Sie nicht timeout und weiter verarbeiten? Ich habe den timeout auf 5 Minuten standalone.xml Datei, aber Sie nie, nie scheinen, um timeout.
<session-bean>
<stateless>
<bean-instance-pool-ref pool-name="slsb-strict-max-pool"/>
</stateless>
<stateful default-access-timeout="5000" cache-ref="simple"/>
<singleton default-access-timeout="5000"/>
</session-bean>
Weiß jemand, was könnte passiert sein?
Ich würde auch sehr gerne, akzeptieren Vorschläge zu simulieren, oder das problem auf andere Weise zu setzen MDBs timeout.
Jede mögliche Hilfe würde geschätzt.
Vielen Dank für Ihre Zeit.
Edit:
So, ich war endlich in der Lage zu reproduzieren Sie das problem ganz einfach, indem Sie die MessageListener zum schlafen für mehr als die Instanz-acquisition-timeout. Im folgenden ist der test-code:
<!-- standalone.xml -->
<strict-max-pool name="mdb-strict-max-pool" max-pool-size="5" instance-acquisition-timeout="30" instance-acquisition-timeout-unit="SECONDS"/>
MDB:
@MessageDriven(name = "TestMDB", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/myQueue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")//,
})
public class TestMDB implements MessageListener {
private final static Logger LOGGER = Logger.getLogger(TestMDB.class
.toString());
@Resource
private MessageDrivenContext ctx;
private final static int sleepingTime = MyProperties.SLEEP_MILLISECS;
/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message rcvMessage) {
ObjectMessage msg = null;
Future<String> future = null;
MyResource res = null;
try {
if (rcvMessage instanceof ObjectMessage) {
msg = (ObjectMessage) rcvMessage;
res = (MyResource)msg.getObject();
LOGGER.info("Received resource: " + res);
Thread.sleep(sleepingTime);
LOGGER.info("Released resource: " + res);
} else {
LOGGER.warning("Message of wrong type: "
+ rcvMessage.getClass().getName());
}
} catch (JMSException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
- related post auf jboss (ungelösten) ,developer.jboss.org/message/794455
Du musst angemeldet sein, um einen Kommentar abzugeben.
Scheint es, als ob dieses Verhalten zu erwarten und das Problem ist wahrscheinlich die Anwendung im Zusammenhang.
Unten ist eine Zusammenfassung des Problems:
Wäre die ideale Lösung, um herauszufinden, warum die multilateralen Entwicklungsbanken gesperrt, aber bis dahin, da die Anwendung bereits in der Produktion, wir müssen einen fall-back-plan.
Ich glaube, eine Lösung wäre, zu unterbrechen, die MDB-thread nach, den wir erreichen Hornet warten timeout (oder auf transaction-Timeout - @ActivationConfigProperty(propertyName = "transactionTimeout", propertyValue = "30")), aber es scheint nicht, eine einfache Konfiguration (noch) dazu in JBoss AS7.
Den traurigen Weg wäre, um mal die MDB-thread-Ausführung und-Kraft einer Unterbrechung innerhalb der onMessage-Methode. Dies kann leicht erreicht werden mit einem ExecutorService (http://stackoverflow.com/questions/6460664/how-can-i-interrupt-method-execution-by-time)
Für jemand die gleichen Probleme, ich fand einige ähnliche Diskussionen im Internet:
http://bryanpendleton.blogspot.com.br/2009/05/timertask-exception-handling.html
https://community.jboss.org/thread/162822
Hoffe, das hilft.
Und hoffe, dass ich erkennen kann, was falsch ist mit der Anwendung.
Habe ich auch festgestellt, das Problem, und wir fanden die Ursache schließlich überprüfen Sie die Fäden unter JBoss bereit, indem Sie den folgenden Befehl.
Und wir fanden ein thread-deadlock. nachdem wir fix den Stillstand, JBoss nicht halt nicht mehr.