我有一个无状态的ejb,并且我与jms队列建立连接并向其发送消息。
我执行此操作的部分代码:
@Resource(mappedName = "jms/abcd")
private ConnectionFactory abcd;
@Resource(mappedName = "jms/xyz")
private Queue xyz;
@Override
public void saveCounter(String protocolName, String serialNumber, String counterName,CounterAction action)
{
Connection connection = null;
Session session=null;
try
{
connection = abcd.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(xyz);
Message message = session.createMessage();
message.setStringProperty("serialNumber", serialNumber);
producer.send(message);
}
catch (Exception e)
{
logger.error("Sending message to queue", e);
}
finally
{
try
{
if(session!=null){
session.close();
}
if (connection != null)
{
connection.close();
}
}
catch (JMSException e)
{
logger.warn(e);
}
}
}
我正在使用MDB。消费者代码如下所示:
@MessageDriven(name = "XXMessageDrivenBean", activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Queue") }, mappedName = "jms/xyz")
public class CounterMessageDrivenBean {
...
@Override
public void onMessage(Message message){
System.out.println("got message: " + message);
log.debug("got message: " + message);
}
.....
}
我使用来自其他ejb的ejb的功能,通过执行此ejb的依赖注入并调用其方法。它适用于某些请求
但是当我尝试对我的代码进行负载测试时,经过一些像千元的请求之后,代码的crateConnection部分开始失败,异常:
Thread 64518 "httpWorkerThread-38080-1": (state = BLOCKED)
at com.sun.enterprise.resource.AbstractResourcePool.getResourceFromPool(AbstractResourcePool.java:788)
at com.sun.enterprise.resource.AbstractResourcePool.getUnenlistedResource(AbstractResourcePool.java:682)
at com.sun.enterprise.resource.AbstractResourcePool.internalGetResource(AbstractResourcePool.java:624)
at com.sun.enterprise.resource.AbstractResourcePool.getResource(AbstractResourcePool.java:470)
at com.sun.enterprise.resource.PoolManagerImpl.getResourceFromPool(PoolManagerImpl.java:248)
at com.sun.enterprise.resource.PoolManagerImpl.getResource(PoolManagerImpl.java:176)
at com.sun.enterprise.connectors.ConnectionManagerImpl.internalGetConnection(ConnectionManagerImpl.java:323)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:245)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:175)
at com.sun.enterprise.connectors.ConnectionManagerImpl.allocateConnection(ConnectionManagerImpl.java:168)
at com.sun.messaging.jms.ra.ConnectionFactoryAdapter._allocateConnection(ConnectionFactoryAdapter.java:179)
at com.sun.messaging.jms.ra.ConnectionFactoryAdapter.createConnection(ConnectionFactoryAdapter.java:166)
at com.sun.messaging.jms.ra.ConnectionFactoryAdapter.createConnection(ConnectionFactoryAdapter.java:148)
显示上面的代码:saveCounter:createConnection
请帮助我理解为什么我的代码开始失败。 我是glassfish应用服务器。
提前致谢
答案 0 :(得分:1)
人士Himanshu,
首先想到的是为什么你使用无状态ejb来实现这个功能而不是MDB。
关于代码的负面信息是您正在处理JMS连接的打开和关闭。
如果您使用的是MDB,则JMS连接处理由MDB本身处理。 此外,您将打开一个JMS连接池,可以轻松调整。 因此,您不应该遇到报告的相同问题。
答案 1 :(得分:1)
您可以尝试关闭MessageProducer对象。您的代码看起来非常适合关闭会话和连接,但您实际上并没有关闭生产者。 MessageProducer javadoc建议调用close()。您可以在producer.close();
之后立即拨打producer.send(message);
。
另外,关于finally块的小建议 - 如果session.close()抛出异常,你将无法关闭连接。您也可以尝试在try / catch块中包装该调用:
finally
{
try
{
if(session!=null){
try {
session.close();
} catch(JMSException e) { }
}
if (connection != null)
{
connection.close();
}
}
catch (JMSException e)
{
logger.warn(e);
}
}
希望这有帮助!
答案 2 :(得分:1)
我使用非常相似的代码每天处理200,000-300,000 trx并且没有遇到任何问题。我在这里分享代码: ...
Connection connection;
Session session = null;
MessageProducer messageProducer;
try {
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
messageProducer = session.createProducer(queue);
TextMessage message = session.createTextMessage();
for (String msgKey : messages.keySet()) {
message.setText(messages.get(msgKey));
// logger.debug("Sending message to Queue: "
// + message.getText());
messageProducer.send(message);
}
} catch (JMSException e) {
logger.info("Error " + e);
e.printStackTrace();
}
...
我可以从您的代码中看到的唯一区别是我在try块之外声明了MessageProducer。试着看看它是否有所作为。
答案 3 :(得分:0)
我发现关闭连接,也关闭了会话和制作人。因此,没有与开放资源相关的问题。
我发现的问题是,我们对jms施加了太大的负担,就像每小时缺少一次。因此,jms服务无法处理如此多的负载。