日期:2014-05-16  浏览次数:20426 次

5.4JDBC消息仓库(一)
ActiveMQ插件式消息仓库API的灵活性允许许多不同的实现选择。最早和更普遍的消息持久化存储实现使用JDBC。
为什么许多组织选择JDBC消息仓库的普遍原因是他们已经有管理关系数据库的专业知识。在上述的消息仓库实现中JDBC持久化在性能上绝不优越。事情的事实是许多业务已经在使用关系数据库所以他们更倾向充分利用它们。
但是使用共享数据库尤其适用于建立多代理的一个多冗余的主从拓扑。当一组ActiveMQ代理被配置来使用共享数据库,它们会尝试连接和攫取锁表中的一个锁,但是只有一个能成功并成为主。其他的代理会成为从,并将处于等待状态,不接受客户端的连接,知道主代理挂掉了。这是ActiveMQ的一般的部署方案,这将在第10章中更详细地论述。
当使用JDBC消息仓库,在ActiveMQ中使用的默认的JDBC消息驱动是Apach Derby。但是支持许多其他关系数据库。
5.4.1JDBC消息仓库支持的数据库
差不多所有带JDBC驱动的数据库都可以使用。虽然这不是一个详尽的列表,但是JDBC仓库已经显示能操作下面的的关系数据库:
●Apache Derby
●MySQL
●PostgreSQL
●Oracle
●SQL Server
●Sybase
●Informix
●MaxDB
为消息持久化一些用户宁愿关系数据库仅仅是因为关系数据库通过查询检查消息的能力。下面的章节将讨论这个主题。
5.4.2JDBC消息仓库schema
JDBC消息仓库使用有三个表构成的schema。两个用于持有消息,第三个用作锁表来确保同一时间只有一个ActiveMQ代理能访问数据库。这里有一个这三个表的详细的分解。
显示在表5.3的消息表,被默认命名为ACTIVEMQ_MSGS并且如下定义:
表5.3 ACTIVEMQ_MSGS SQL表的列信息
列名默认类型描述
IDINTEGER用于检索消息序列ID
CONTAINERVARCHAR(250)消息的目标
MSGID_PRODVARCHAR(250)消息生产者的ID
MSGID_SEQINTEGER对应消息的生产者序列ID。它和MSGID_PROD一起等价于JMS-MessageID。
EXPIRATIONBIGINT以毫秒为单位的消息的过期时间
MSGBLOB序列化消息本身

无论是队列还是主题,消息被分解并存储于ACTIVEMQ_MSGS表。
这里有一个独立的表持有持久订阅者信息和对应持久订阅这收到的最后一条消息的ID。这个信息被持在表ACTIVEMQ_ACKS,它显示与表5.4
表5.4 ACTIVEMQ_ACKS SQL表列信息
列名默认值描述
CONTAINERVARCHAR(250)消息的目的
SUB_DESTVARCHAR(250)持久消息订阅者的目的(如果使用通配符可能和container不同)
CLIENT_IDVARCHAR(250)持久消息订阅者的客户端ID
SUB_NAMEVARCHAR(250)持久订阅者的持久名字
SELECTORVARCHAR(250)持久订阅者的选择器
LAST_ACKED_IDInteger订阅者收到的最后一条消息的序列ID

为持久订阅者,LAST_ACKED_ID序列被用作指向ACTIVEMQ_MSGS和特定消息订阅者的可用消息的简易指针,它事该消息能容易地从ACTIVEMQ_MSGS表中选取。
那个锁表(lock table),即ACTIVEMQ_LOCK,被用来保证同一时间只有一个ActiveMQ代理访问数据库。如果某个ActiveMQ代理不能得到数据库锁,那个代理将不会完全初始化,并将等待锁被释放,或自己被停止。锁表的表结构在表5.5中定义:
表5.5 ACTIVEMQ_LOCK SQL列信息:
列名默认值描述
IDINTEGER
SUB_DESTVARCHAR(250)持久消息订阅者的目的(如果使用通配符可能和container不同)

现在我们已经解释了JDBC仓库使用的数据库表的结构,我们能运行一些配置JDBC消息仓库的示例,让我们进入下一节。