配置篇
下面我们来看看是JMS是在JBoss下如何配置的,首先JMS需要一个数据库来保存其持久化的消息,幸运的是JBoss自带有一个开源的JAVA数据库HSQL(www.hsqldb.org)
在这里简单地介绍一下这个数据库,它支持标准的SQL语法和JDBC接口,是一个用纯JAVA编写的数据库,其实它只有一个jar文件而已:hsqldb.jar,在%JBOSS_HOME%/server/default/lib目录下你能找到它。
启动这个数据库有三种模式:Server模式、进程模式和内存模式,在Server模式下,你可以用下面的命令让它启动起来:
$cd %JBOSS_HOME%/server/default/lib
$ java -cp hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 demoDB
其中mydb是数据库名,demoDB是数据库别名,我们用JDBC连它是就用这个别名,用户名是sa,密码默认是空,我们下列语句就能创建表、插入数据了
create table employee (
employee_id int,
employee_name varchar(50),
age int,
hiredate date
)
insert into employee values(1, 'linyufa', 33, '2007-12-17')
insert into employee values(2, 'scott', 25, '2008-11-23')
insert into employee values(3, 'larry', 35, '2004-11-23')
想进一步了解HSQL的知识,网上有很多学习资料,好了,回到我们讨论的JMS话题,有了这个数据库,那我们就不必去找其他数据库了,JMS默认是用内存模式来启动它的,所以我们基本上不用去关心它是如何工作的。
1) 在 %JBOSS_HOME%/server/default/deploy/jms目录下,
打开hsqldb-jdbc-state-service.xml文件,
<depends optional-attribute-name="ConnectionManager">
jboss.jca:service= DataSourceBinding, name=DefaultDS
</depends>
DefaultDS这个名字就是JMS连接数据库的数据源,可以让其保持默认值。
2) 再在同一目录打开hsqldb-jdbc2-service.xml 文件,
<depends optional-attribute-name="ConnectionManager">
jboss.jca:service=DataSourceBinding,name=DefaultDS
</depends>
DefaultDS这个名字保持和前面一致即可,也可以让其保持默认值。
3) 在同一目录打开jbossmq-destinations-service.xml文件,找到下面的代码段:
<mbean code="org.jboss.mq.server.jmx.Topic"
name="jboss.mq.destination:service=Topic,name=testTopic">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
<depends optional-attribute-name="SecurityManager">
jboss.mq:service=SecurityManager
</depends>
<attribute name="SecurityConf">
<security>
<role name="guest" read="true" write="true"/>
<role name="publisher" read="true" write="true" create="false"/>
<role name="durpublisher" read="true" write="true" create="true"/>
</security>
</attribute>
</mbean>
这是定义一个名叫testTopic的示例,如果你要定义一个新的topic,只需要复制这段代码,改一下name属性即可。
同样找到下面这段的代码,这是定义一个名叫testQueue的示例,如果要定义一个新的queue,复制这段代码,改一下名字即可。
<mbean code="org.jboss.mq.server.jmx.Queue"
name="jboss.mq.destination:service=Queue,name=testQueue">
<depends optional-attribute-name="DestinationManager">
jboss.mq:service=DestinationManager
</depends>
<depends optional-attribute-name="SecurityManager">
jboss.mq:service=SecurityManager
</depends>
<attribute name="MessageCounterHistoryDayLimit">-1</attribute>
<attribute name="SecurityConf">
<security>
<role name="guest" read="true" write="true"/>
<role name="publisher" read="true" write="true" create="false"/>
<role name="noacc" read="false" write="false" create="false"/>
</security>
</attribute>
</mbean>
4) 启动Jboss后在控制台看到如下输出,即说明JMS正常启动了
09:50:28,390 INFO [A] Bound to JNDI name: queue/A
09:50:28,406 INFO [B] Bound to JNDI name: queue/B
09:50:28,406 INFO [C] Bound to JNDI name: queue/C
09:50:28,406 INFO [D] Bound to JNDI name: queue/D
09:50:28,421 INFO [ex] Bound to JNDI name: queue/ex
09:50:28,437 INFO [testTopic] Bound to JNDI name: topic/testTopic
09:50:28,484 INFO [securedTopic] Bound to JNDI name: topic/securedTopic
09:50:28,484 INFO [testDurableTopic] Bound to JNDI name: topic/testDurableTopic
09:50:28,500 INFO [testQueue] Bound to JNDI name: queue/testQueue
5) 如果是Jboss4.2或以上的版本,在启动Jboss时必须指定 –b 0.0.0.0参数,否则本机之外的任何主机都无法连接JMS。可以修改run.bat或run.sh文件,也可以在运行命令时附带上这个参数,如下 sh run.sh –b 0.0.0.0
从上面介绍可以看出,在Jboss下配置JMS是非常简单的,仅需要copy一段代码,改个名字即可。如果在WebLogic下,你就要依次配置JMS Module, ConnectionFactory, Topic, Queue, Template,不过好在console都有向导,非常直观,所以配置起来也不是什么难事。
JMS编程其他注意事项
创建一个JMS Connection、查找ConnectionFactory和Destination都是需要很大的系统开销的操作,所以我们的应用程序应避免频繁地去做这些操作。一般情况下,我们可以把ConnectionFactory,Connection, Topic, Queue定义成类的成员变量,并在类的构造函数里初始化他们,避免在每次接收和发送JMS消息时去做这些工作。但是因此也带了一个问题,就是说当Connection不可用了(比如JMS Server重启了),我们的应用程序就会开始不工作了,所以我们要有一种机制去检测我们的Connection是否有效,如果已经断掉,应该试图去重新连接,并通知系统管理员。
JMS的Connection和JDBC的Connection类似,不再使用后应该关闭,不管是正常退出,还是异常退出,否则别的客户程序可能就再也取不到连接了。Session也是如此。
因为JMS工作模式是异步的,我们要意识到调用Connection.start()这个方法,系统已经启动了一个新的线程在工作,也就是说退出了这行语句所在的方法之后,这个线程还在工作,它会不断地去侦听有没有新的JMS消息,直到这个Connection被关闭或不可用。