ActiveMQ的安全机制和集群模式
- 20 ActiveMQ安全机制
- 20.1 Web 控制台安全
- 20.2 消息服务器Broker安全
- 21 ActiveMQ主从集群
- 21.1 使用集群的重要性
- 20.2 主从集群的方式
- 20.2.1 shared filesystem Master-Slave方式主从集群
- 20.2.2 shared database Master-Slave方式主从集群
- 20.2.3 Replicated LevelDB Store方式集群
- 21 Zookeeper集群
- 21.1 Zookeeper集群特点
- 21.2 Zookeeper集群配置
20 ActiveMQ安全机制
20.1 Web 控制台安全
1、Web 控制台安全
管理后台不要对外公开,不能让外网访问
设置后台访问的密码,密码要复杂一点,不要公开
2、如何设置密码
(1)、/conf/jetty.xml 将配置项authenticate值改为 true,现在ActiveMQ新版本默认activemq是设置的true,所以也不用改;
(2)、/conf/jetty-realm.properties 设置用户名和密码, 格式为--> 用户名:密码,角色名
<bean id="adminSecurityConstraint" class="org.eclipse.jetty.util.security.Constraint">
<property name="name" value="BASIC" />
<property name="roles" value="admin" />
<!-- set authenticate=false to disable login -->
<property name="authenticate" value="true" />
</bean>
# Defines users that can access the web (console, demo, etc.)
# username: password [,rolename ...]
admin: admin, admin
user: user, user
20.2 消息服务器Broker安全
主要是添加访问的用户名和密码:实现方式有两种:
方式1:添加访问密码,在conf/activemq.xml文件中的内加上:
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="system" password="123456" groups="users,admins"/>
<authenticationUser username="user" password="123456" groups="users"/>
<authenticationUser username="guest" password="123456" groups="guests"/>
</users>
</simpleAuthenticationPlugin>
</plugins>
在发送消息和接收消息时创建AcitveMQConnectFactory时就需要指定用户名和密码
在Springboot中应该指定
#activemq的连接地址
spring.activemq.broker-url=tcp://192.168.64.128:61616
spring.activemq.user=system
spring.activemq.password=123456
#消息的目的地
spring.jms.template.default-destination=springbootQueue
#退出main方法的主程序
spring.jms.cache.enabled=false
方式二:Java Authentication Authorization Service(JAAS,Java验证和授权服务),它可以通过插件的方式集成到你的应用程序中,提供验证和授权服务。
ActiveMQ加入JAAS身份验证,共4个文件配置:
1、activemq.xml
2、login.config,
3、groups.properties,
4、users.properties
1、在conf/activemq.xml文件中加上:
<plugins>
<!--use JAAS to authenticate using the login.config file on the classpath to configure JAAS -->
<jaasAuthenticationPlugin configuration="activemq" />
<!-- lets configure a destination based authorization mechanism -->
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<!-->表示通配符,例如USERS.>表示以USERS.开头的主题,>表示所有主题,read表示读的权限,write表示写的权限,admin表示角色组-->
<authorizationEntry queue=">" read="admins" write="admins" admin="admins" />
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<authorizationEntry queue="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />
<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
2、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";
};
3、groups.properties配置:
#group=userName
admins=system
4、users.properties配置:
#userName=password
system=123456
21 ActiveMQ主从集群
21.1 使用集群的重要性
集群就是将相同的程序、功能,部署在两台或多台服务器上,这些服务器对外提供的功能是完全一样的。集群是通过不断横向扩展增加服务器的方式,以提高服务的能力。
1、集群可以解决单点故障问题;
2、集群可以提高系统的可用性;
3、集群可以提高系统的服务能力;
20.2 主从集群的方式
20.2.1 shared filesystem Master-Slave方式主从集群
通过共享存储目录(kahaDB)来实现master和slave的主从信息同步;
所有ActiveMQ的broker都在不断地获取共享目录的控制权,哪个broker抢到了控制权,它就成为master,它将锁定该目录,其他broker就只能成为slave;
当master主出现故障后,剩下的slave从将再进行争夺共享目录的控制权,谁抢到共享目录的控制权,谁就成为主,其他没有抢到控制权的称为从;
由于他们是基于共享目录,所以当主出现故障后,其上没有被消费的消息在接下来产生的新的master主中可以继续进行消费;
1、安装多个activeMQ;
2、配置每个activeMQ的conf目录下的activemq.xml文件的共享目录及端口
(如果集群搭建在一台机器上需要改端口,如果搭建在多台上就不需要了);
3、更改activemq.xml配置文件
<persistenceAdapter>
<kahaDB directory="/opt/kahadb"/>
</persistenceAdapter>
4、一台机器需要更改网络端口
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
其中:
maximumConnections 最大连接数;
wireFormat.maxFrameSize 表示一个完整消息的最大数据量,单位byte;
4、修改jetty.xml文件的jetty服务器端口:
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="0.0.0.0"/>
<property name="port" value="8162"/>
</bean>
5、启动三台ActiveMQ,可以测试验证了
6、判断主从服务器依据:看web控制台,web控制台能访问的是 master,不能访问的是 slave
7、程序收发消息连接时使用
failover(tcp://192.168.65.128:61617,tcp://192.168.65.128:61618,tcp://192.168.65.128:61619)
failover:的意思时故障转移,消费者和生产者启动时,日志会打印当前连的是哪个mq,故障转移:停止一个mq服务,会自动连接另一个mq
这种方式需要三台服务器上的ActiveMQ使用同一个目录,需要通过磁盘挂载。
20.2.2 shared database Master-Slave方式主从集群
该方式与shared filesystem方式类似,只是共享的存储介质由文件系统改成了数据库。
1、安装多个activeMQ;
2、配置每个activeMQ的conf目录下的activemq.xml文件的持久化适配器是jdbc数据库方式,同时修改相关端口
(如果集群搭建在一台机器上需要改端口,如果搭建在多台上就不需要了);
<persistenceAdapter>
<jdbcPersistenceAdapter dataSource="#mysql-ds"/>
</persistenceAdapter>
<bean id="mysql-ds" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/activemq?useUnicode=true&characterEncoding=utf8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
注意1:上面的配置需要配置在<broker>的外面;
注意2:需要加入mysql的驱动包和数据库连接池Druid包,放入activeMQ的lib目录下;
注意3:启动好数据库,并创建好数据库名称
3、一台机器需要更改网络端口
<transportConnector name="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="amqp" uri="amqp://0.0.0.0:5672?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="stomp" uri="stomp://0.0.0.0:61613?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="mqtt" uri="mqtt://0.0.0.0:1883?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
<transportConnector name="ws" uri="ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/>
其中:
maximumConnections 最大连接数;
wireFormat.maxFrameSize 表示一个完整消息的最大数据量,单位byte;
4、修改jetty.xml文件的jetty服务器端口:
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="0.0.0.0"/>
<property name="port" value="8162"/>
</bean>
5、启动三台ActiveMQ,可以测试验证了
6、判断主从服务器依据:看web控制台,web控制台能访问的是 master,不能访问的是 slave
7、程序收发消息连接时使用
failover(tcp://192.168.65.128:61617,tcp://192.168.65.128:61618,tcp://192.168.65.128:61619)
failover:的意思时故障转移,消费者和生产者启动时,日志会打印当前连的是哪个mq,故障转移:停止一个mq服务,会自动连接另一个mq
20.2.3 Replicated LevelDB Store方式集群
基于可复制的LevelDB存储方式的集群
这种集群方式是ActiveMQ5.9版本以后新增的特性,它使用ZooKeeper从一组broker中协调选择一个broker作为master主,其他broker作为slave从的模式;
所有slave从节点通过复制master主节点的消息来实现消息同步,当主出现故障后,没有被消费的消息在从服务器上也同步了一份,所以不会有消息的丢失;
LevelDB 是 Google开发的一套用于持久化数据的高性能kv数据库,ActiveMQ利用该数据库进行数据的存储;
只有master 接受客户端连接,slave不接受客户端连接;
Master的所有存储操作都将被复制到slaves;
在这个模式中,需要有半数以上的broker是正常的,集群才是可用的,超过半数broker故障,zookeeper的选举算法将不能选择master,从而导致集群不可用;
1、配置
<persistenceAdapter>
<replicatedLevelDB
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="localhost:2181"/>
</persistenceAdapter>
参数说明:
replicas :集群中存在的节点的数目;
bind :当该节点成为master后,将使用该bind配置的ip和端口进行数据复制;0.0.0.0表示任何地址
zkAddress :zookeeper的地址;
验证集群:
1、依次启动一个ZooKeeper;
2、依次启动三个ActiveMQ;
3、程序使用:failover:(tcp://localhost:61617,tcp://localhost:61618,tcp://localhost:61619) 收发信息;
4、把其中的一台master关闭,留下两台运行,观察效果;
5、继续关闭下一台master,留下一台运行,观察效果;
6、启动其中一台,让两个运行,再观察效果;
这种方式,不适合集群太大,也就是activemq不能太多,因为多个activemq之间需要复制消息,
这个也会耗资源,占用网络,建议3、5台;
21 Zookeeper集群
Zookeeper作为一个服务,它本身也可能发生故障,所以我们也需要将Zookeeper进行集群,避免单点故障问题,以保证zookeeper本身的高可用性,那么我们需要搭建奇数台Zookeeper构成一个Zookeeper的集群;
21.1 Zookeeper集群特点
1、集群中只要有超过半数的机器是正常工作的,那么整个集群对外就是可用的;
2、也就是说如果有2个zookeeper,那么只要有1个故障了,zookeeper就不能用了,因为1没有过半,所以2个zookeeper不是高可用的,因为不能容忍任何1台发生故障;
3、同理,要是有3个zookeeper,一个故障了,还剩下2个正常的,过半数了,所以3个zookeeper才是高可用的,因为能容忍1台发生故障;
4、如果是4台呢?5台呢?6台呢? 那么分别能容忍1,2,2 台发生故障 (奇数台)
21.2 Zookeeper集群配置
1、下载安装3个Zookeeper
2、3个zookeeper中conf目录下的zoo_sample.cfg复制一份,改为zoo.cfg并配置:
dataDir=/usr/local/zookeeper-3.4.10_1/data (1)
clientPort=2181 (2)
server.1=localhost:2888:3888 (3)
server.2=localhost:2889:3889
server.3=localhost:2890:3890
格式:
server.A=B:C:D:
A是一个数字,表示这个是第几号服务器,
B是这个服务器的ip地址
C第一个端口用来集群成员的信息交换,表示的是这个服务器与集群中的Leader服务器交换信息的端口
D是在leader挂掉时专门用来进行选举leader所用
3、创建三个dataDir目录 (4)
/usr/local/zookeeper-3.4.10_1/data
/usr/local/zookeeper-3.4.10_2/data
/usr/local/zookeeper-3.4.10_3/data
4、每个data目录中都创建一个名为myid的文件
3个文件的内容分别写1、2、3;
这个1、2、3是对应前面的server.1、 server.2、 server.3
5、至此一个zookeeper的集群就搭建OK.可以查看哪个是leader哪个是follower
./ZkServer.sh status
6、配置mq
<persistenceAdapter>
<replicatedLevelDB
replicas="3"
bind="tcp://0.0.0.0:0"
zkAddress="localhost:2182,localhost:2183,localhost:2184"/>
</persistenceAdapter>