Java 减少MDB JMS JAXB Hibernate组合应用程序的CPU使用

Java 减少MDB JMS JAXB Hibernate组合应用程序的CPU使用,java,hibernate,jaxb,jms,message-driven-bean,Java,Hibernate,Jaxb,Jms,Message Driven Bean,所以我有一个耳朵,可以从JMS队列中读取消息。根据要求,消息是XML数据。我从队列中读取数据,使用JAXB对其进行解组,并将xml数据保存到数据库中。但整个过程占用了我90-95%的CPU使用率。我跟进了本文中建议的更改,以减少CPU的使用。但即使在实现了这些之后,在处理队列中的所有消息之前,它仍然使用了90%的mu CPU 注意我已经创建了一个单独的hibernatePersistence.jar,在这里我实现了JAXB解组。hibernate.cfg.xml文件也在jar中。 这就是我认为高

所以我有一个耳朵,可以从JMS队列中读取消息。根据要求,消息是XML数据。我从队列中读取数据,使用JAXB对其进行解组,并将xml数据保存到数据库中。但整个过程占用了我90-95%的CPU使用率。我跟进了本文中建议的更改,以减少CPU的使用。但即使在实现了这些之后,在处理队列中的所有消息之前,它仍然使用了90%的mu CPU

注意我已经创建了一个单独的hibernatePersistence.jar,在这里我实现了JAXB解组。hibernate.cfg.xml文件也在jar中。 这就是我认为高使用率可能存在的问题吗

每次调用save()函数时,使用单独的jar进行持久化是否会建立并关闭数据库连接,这可能会导致CPU使用率过高或其他原因

这是密码

**MDB Listener Class**

/**
     * @see MessageListener#onMessage(Message)
     */
    public void onMessage(Message message) {
        try {
            if (message instanceof BytesMessage) {
                BytesMessage bytesMessage = (BytesMessage) message;
                StringBuffer buffer = new StringBuffer();
                for (int i = 0; i < (int) bytesMessage.getBodyLength(); i++) {
                    buffer.append((char) bytesMessage.readByte());
                }
                String cbeXml = buffer.toString().trim();
                persistAuditMessage(cbeXml);
            } else if (message instanceof TextMessage) {
                TextMessage textMessage = (TextMessage) message;
                persistAuditMessage(textMessage.getText());
            }

        } catch (JMSException e) {
            e.printStackTrace();
        } catch (Exception jmse) {
            jmse.printStackTrace();
        }
    }

    private void persistAuditMessage(String auditMessage) {
        // for without Session Bean Call
        count++;
        if (auditMessage != null && auditMessage.trim().length() != 0) {
            MarshalImpl impl = new MarshalImpl();
            impl.saveCbeXml(auditMessage);

        }


    }
**MDB侦听器类**
/**
*@see MessageListener#onMessage(Message)
*/
消息(消息消息)上的公共无效{
试一试{
if(字节消息的消息实例){
BytesMessage BytesMessage=(BytesMessage)消息;
StringBuffer=新的StringBuffer();
对于(int i=0;i<(int)bytesMessage.getBodyLength();i++){
append((char)bytesMessage.readByte());
}
字符串cbeXml=buffer.toString().trim();
持久化审核消息(cbeXml);
}else if(文本消息的消息实例){
text消息text消息=(text消息)消息;
persistAuditMessage(textMessage.getText());
}
}捕获(JME){
e、 printStackTrace();
}捕获(异常jmse){
printStackTrace();
}
}
私有void persistAuditMessage(字符串auditMessage){
//对于没有会话Bean调用的
计数++;
if(auditMessage!=null&&auditMessage.trim().length()!=0){
MarshalImpl impl=新的MarshalImpl();
impl.saveCbeXml(auditMessage);
}
}
持久化JAR中的类

public class MarshalImpl extends AbstractHibernateLayar<BaseEvent, Long> implements Marshal {

    private static Logger logger = LoggerFactory.getLogger(MarshalImpl.class);
    private static JAXBContext context = null;

    public static synchronized JAXBContext createJAXBContext() throws JAXBException {
        if (context == null) {
            System.out.println("Creating jaxb context");
            context = JAXBContext.newInstance(BaseEvents.class.getPackage().getName());
        }
        return context;
    }




    public MarshalImpl() {
        super();
    }


    @Override
    public void saveCbeXml(String auditMessage) {
        try {



            Unmarshaller unmarshaller = createJAXBContext().createUnmarshaller();
        @SuppressWarnings("unchecked")
        JAXBElement<BaseEvents> root = (JAXBElement<BaseEvents>) unmarshaller.unmarshal(new StreamSource(new StringReader(auditMessage)));
        List<BaseEvent> baseEvent = root.getValue().getCommonBaseEvent();
            // Persist BaseEvent one by one
            for (BaseEvent event : baseEvent) {
                event.setSequenceNumber(new Long(1));// Indicate Working Flag
                event.setCreationTimeItem(new Date());
                save(event);

            }

        } catch (Exception e) {
            logger.error("MarshalImpl::saveCbeXml::CBE Records not inserted!!::" + e.getMessage(), e);
        } finally {
            System.gc();

        }
    }
公共类MarshalImpl扩展抽象HibernateLayar实现封送{
私有静态记录器Logger=LoggerFactory.getLogger(marshalpimpl.class);
私有静态JAXBContext上下文=null;
公共静态同步JAXBContext createJAXBContext()抛出JAXBEException{
if(上下文==null){
println(“创建jaxb上下文”);
context=JAXBContext.newInstance(BaseEvents.class.getPackage().getName());
}
返回上下文;
}
公共marshampl(){
超级();
}
@凌驾
公共void saveCbeXml(字符串审核消息){
试一试{
Unmarshaller Unmarshaller=createJAXBContext().createUnmarshaller();
@抑制警告(“未选中”)
JAXBElement root=(JAXBElement)unmarshaller.unmarshal(新StreamSource(新StringReader(auditMessage));
List baseEvent=root.getValue().getCommonBaseEvent();
//逐个持久化BaseEvent
for(BaseEvent事件:BaseEvent){
event.setSequenceNumber(新长(1));//指示工作标志
event.setCreationTimeItem(新日期());
保存(事件);
}
}捕获(例外e){
logger.error(“MarshalImpl::saveCbeXml::CBE记录未插入!!::”+e.getMessage(),e);
}最后{
gc();
}
}

你知道些什么……我得到了问题本身的答案。问题中提到的注释也告诉我需要有特定的jaxb jar

给出我答案的评论

仅供参考,jaxb impl 2.2.4及更新版本不会出现此问题 (虽然不确定它到底是在哪个版本中被更改的) 可以使用最新的JDK 7u7(应该包含jaxb impl 2.2.4) 或者将jaxb impl 2.2.6添加到您的项目中 (根据第2.1.10节 ). 最后一条信息它不会发生在捆绑jaxb impl的JBoss 7.1.1上 2.2.4),然后您可以使用旧方法,无需为JAXBContext实现任何缓存,以避免重复加载类

我当时使用的是jaxb2.2.4 jar..因此包括jaxb2.2.6 jar解决了我的问题,猜猜看..它将我的CPU使用率降低到了30%,并且它在1分钟内处理了500个队列消息(