基于消息Bean的EJB异步通信Bromon原创 请尊重版权
异步通信是一个提升程序执行效率的很重要的手段,而性能问题又是EJB诞生以来一直都很受关注的话题。EJB执行效率不高的原因是客户端需要查询和调用远程接口,而本身在处理数据是很快的,毕竟EJB有比较完善的缓冲机制,几十万的app server也不是白吃内存的。客户端程序如果能够采用异步通信,只负责以消息的形式发送请求和需要处理的数据,不用等待系统查询、调用远程接口,可以节省大量时间,这也是EJB 2.0中引入消息驱动Bean的一个重要原因。J2EE的消息机制允许你以消息的形式传递对象,我们可以利用它实现很多应用。
在最近正在写的一个考试系统中,系统把学生对每一个题目的回答都实时记录到数据库,这样做会有比较频繁的数据库操作,对性能有比较大的影响,但是可以让学生的每一次答题都得到永久性保存,避免因为意外死机或异常退出造成学生提交的答案丢失。毫无疑问,数据的安全可靠是第一位的,但是上百个学生并发操作,这个负载也是很巨大的。为了在稳定和性能上谋求平衡,我们考虑这样一种模型:
◆在服务器端建立一个永久性的队列,该队列可以保证数据安全,即使服务器意外重启,里面的对象也不丢失。并且有一种机制保证队列中的对象只会被处理一次。
◆客户端把答案数据封装成javabean,然后提交到这个队列中,提交之后不必等待数据处理完成,直接进行以后的操作,产生新的数据后继续往队列里存放,不必去关心数据什么时候会被处理。
◆服务器以FIFO的顺序处理队列中的数据包。
结构大致如下图:
很明显,这里只提供一种单向通信,但是并非被迫,完全可以在建立另外一个队列,存放返回的消息,对应的消息通过消息ID进行关联。以消息bean为核心的java消息服务(JMS)实际上就是这样一个框架。
首先设计一个操作答案数据表的类:
它包含增加答案的方法和修改已有答案的方法,在实际的项目中,它由一个映射数据表的CMP Entity Bean和一个封装程序逻辑的SessionBean构成,是一个典型的session facade模式。实际的系统大致是这样:
在一个系统中同时使用CMP和Hibernate来做映射,是一个非常怪异的设计,这样做只是为了使系统更有研究和讨论的价值,实际应用中恐怕我自己也要仔细考虑是否采用BMP代替Hibernate。
编写消息bean之前,首先定义消息中要传递的是什么对象:
下面是消息Bean的代码:
消息如何保障安全呢?有两个手段,一是使用消息验证,客户必须提供匹配的帐号密码才能访问消息中的数据。二是对消息中的对象加密,客户必须持有对应的密钥才能获得对象。