1 安全认证
ActiveMQ
提供了安全认证。 就是用户名密码登录规则
。 ActiveMQ
如果需要使用安全认 证 的 话 , 必 须 在 activemq
的 核 心 配 置 文 件 中 开 启 安 全 配 置 。
1.1 添加插件
配 置 文 件 就 是conf/activemq.xml
在 conf/activemq.xml
配置文件的 broker
标签中增加下述内容:
<jaasAuthenticationPlugin configuration="activemq" />
指定了使用JAAS
插件管理权限,至于configuration="activemq"
是在login.conf
文件里定义的<authorizationEntry topic="名字" read="用户组名" write="用户组名" admin="用户组名"/>
指定了具体的Topic/Queue
与用户组的授权关系<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
这个是必须的配置, 不能少
<plugins>
<!-- use JAAS to authenticate using the login.config file on the classpath to
configure JAAS -->
<!-- 添加 jaas 认证插件 activemq 在 login.config 里面定义,详细见 login.config-->
<jaasAuthenticationPlugin configuration="activemq" />
<!-- lets configure a destination based authorization mechanism -->
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<!-- 这里面的大于号是指所有的连接,不管是consumer还是provider都需要认证,其后是 读写管理的权限,其中 admins是用户组的名字 -->
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<!-- 此处的ActiveMQ.Advisory.>大于号之前是指的系统级别的 -->
<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
<authorizationEntry queue="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
1.2 其他配置
开启认证后, 认证使用的用户信息由其他配置文件提供:conf/login.config
activemq {
org.apache.activemq.jaas.PropertiesLoginModule required
org.apache.activemq.jaas.properties.user="users.properties"
org.apache.activemq.jaas.properties.group="groups.properties";
};
user
代表用户信息配置文件, group
代表用户组信息配置文件。 寻址路径为相对当前配置文件所在位置开始寻址。
conf/users.properties
#用户名=密码
admin=admin
conf/groups.properties
#用户组名=用户名, 用户名(多个用户名用逗号分隔开来)
admins=admin
1.3 开启效果
因为只配置了admin
,因此当使用guest
时在java中
就无法通过此用户访问服务器了,就算访问网页管理网站也是只能用admin
,而不能用guest
2 ActiveMQ的持久化
ActiveMQ
中, 持久化是指对消息数据的持久化。 在 ActiveMQ
中, 默认的消息是保存在内存中的。 当内存容量不足的时候, 或ActiveMQ
正在关闭的时候, 会将内存中的未处理的消息持久化到磁盘中。
具体的持久化策略由配置文件中的具体配置决定
ActiveMQ
的默认存储策略是 kahadb
。 如果使用 JDBC
作为持久化策略, 则会将所有的需要持久化的消息保存到数据库中。
所有的持久化配置都在 conf/activemq.xml
中配置, 配置信息都在 broker
(代理) 标签内部定义。
2.1 kahadb方式
kahadb
方式是 ActiveMQ
默认的持久化策略。 kahadb
是一个文件型数据库。
是使用内存+文件
保证数据的持久化的。 kahadb
可以限制每个数据文件的大小。 不代表总计数据容量。
<persistenceAdapter>
<!-- directory:保存数据的目录; journalMaxFileLength:保存消息的文件大小 -->
<kahaDB directory="${activemq.data}/kahadb" journalMaxFileLength="16mb"/>
</persistenceAdapter>
特性是:
- 日志形式存储消息;
- 消息索引以
B-Tree
结构存储, 可以快速更新; - 完全支持
JMS
事务; - 支持多种恢复机制;
2.2 AMQ 方式
AMQ
方式只适用于 5.3
版本之前。
AMQ
也是一个文件型数据库, 消息信息最终是存储在文件中。 内存中也会有缓存数据。
<persistenceAdapter>
<!-- directory:保存数据的目录 ; maxFileLength:保存消息的文件大小 -->
<amqPersistenceAdapter directory="${activemq.data}/amq" maxFileLength="32mb"/>
</persistenceAdapter>
AMQ
优点:
- 性能高于
JDBC
, 写入消息时, 会将消息写入日志文件, 由于是顺序追加写, 性能很高。为了提升性能, 创建消息主键索引
, 并且提供缓存机制, 进一步提升性能。 - 每个日志文件的大小都是有限制的(默认
32m
, 可自行配置)。当超过这个大小, 系统会重新建立一个文件。 当所有的消息都消费完成, 系统会删除这个文件或者归档。
AMQ
缺点: AMQ Message
会为每一个Destination
创建一个索引, 如果使用了大量的Queue
, 索引文件的大小会占用很多磁盘空间。- 且由于索引巨大, 一旦
Broker
(ActiveMQ
应用实例) 崩溃, 重建索引的速度会非常慢。 - 虽然
AMQ
性能略高于Kaha DB
方式, 但是由于其重建索引时间过长, 而且索引文件占用磁盘空间过大, 所以已经不推荐使用。
2.3 JDBC持久化方式
ActiveMQ
将数据持久化到数据库中。 不指定具体的数据库。 可以使用任意的数据库中。
以下以使用 MySQL
数据库为例
下述文件为 activemq.xml
配置文件部分内容
- 首先定义一个
mysql-ds
的MySQL
数据源, 然后在<broker>
标签中的persistenceAdapter
节点中配置jdbcPersistenceAdapter
并且引用刚才定义的数据源。 dataSource
指定持久化数据库的bean
,createTablesOnStartup
是否在启动的时候创建数据表, 默认值是true
, 这样每次启动都会去创建数据表了, 一般是第一次启动的时候设置为true
, 之后改成false
,如果要反复重启的话就要改为false
- 在
<broker>
标签之外配置<bean>
标签 - 在
activemq
的lib
目录里面增加连接数据库的jar包
<broker brokerName="test-broker" persistent="true" xmlns="http://activemq.apache.org/schema/core">
<persistenceAdapter>
<!-- 此处的true或false要特别注意 -->
<jdbcPersistenceAdapter dataSource="#mysql-ds" createTablesOnStartup="false"/>
</persistenceAdapter>
</broker>
<bean id="mysql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/activemq?relaxAutoCommit=true"/>
<property name="username" value="activemq"/>
<property name="password" value="activemq"/>
<property name="maxActive" value="200"/>
<property name="poolPreparedStatements" value="true"/>
</bean>
配置成功后, 需要在数据库中创建对应的 database
, 否则无法访问。 表格ActiveMQ
可以自动创建。
activemq_msgs
用于存储消息, Queue
和 Topic
都存储在这个表中:
ID
: 自增的数据库主键CONTAINER
: 消息的Destination
MSGID_PROD
: 消息发送者客户端的主键MSG_SEQ
: 是发送消息的顺序,MSGID_PROD+MSG_SEQ
可以组成JMS
的MessageID
EXPIRATION
: 消息的过期时间, 存储的是从1970-01-01
到现在的毫秒数MSG
: 消息本体的Java
序列化对象的二进制数据PRIORITY
: 优先级, 从0-9
, 数值越大优先级越高
activemq_acks
用于存储订阅关系。 如果是持久化 Topic
, 订阅者和服务器的订阅关系在这个表保存:
主要的数据库字段如下:
CONTAINER
: 消息的Destination
SUB_DEST
: 如果是使用Static
集群, 这个字段会有集群其他系统的信息CLIENT_ID
: 每个订阅者都必须有一个唯一的客户端ID
用以区分SUB_NAME
: 订阅者名称SELECTOR
: 选择器, 可以选择只消费满足条件的消息。 条件可以用自定义属性实现,可支持多属性AND
和OR
操作LAST_ACKED_ID
: 记录消费过的消息的ID
。
表 activemq_lock
在集群环境中才有用, 只有一个Broker
可以获得消息, 称为Master Broker
,其他的只能作为备份等待 Master Broker
不可用, 才可能成为下一个 Master Broker
。这个表用于记录哪个 Broker
是当前的Master Broker
。
只有在消息必须保证有效, 且绝对不能丢失的时候。 使用JDBC
存储策略。
如果消息可以容忍丢失, 或使用集群/主备模式保证数据安全的时候, 建议使用levelDB
或 Kahadb