ActiveMQ的高可用与负载均衡配置1.1 高可用配置(Master/Slave) 当一个应用被部署于生产环境,灾备计划是非常重要的,以便从网络故障,硬件故障,软件故障或者电源故障中恢复。通过合理的配置ActiveMQ,可以解决上诉问题。最典型的配置方法是运行多个Broker,一旦某台机器或者某个broker失效,其他broker能够顶上去。这种方式叫做Master/Slave,一个broker作为Master提供服务,而其他broker则作为slave等待master失效从而顶上。客户端需使用failover transport方式来连接broker。 目前activemq提供2种master/slave配置方式: 1) Sharing nothing:各broker拥有自己唯一的消息存储 2) Sharing storage:各broker之间共享一个消息存储设备,比如关系数据库,共享文件系统等。但是一个时间段内只能有一个broker占据他们。 1、 不共享式Master/Slave 该模式下,Master与Slave拥有各自独立的消息存储设备。他是最简单的提供高可用性的消息Broker。Slave需要额外的配置,而Master不需要。所有的消息命令如消息、反馈、订阅、事务等会被从master复制到slave,如图所示,她发生在master收到这些消息之前。 file:///C:\Users\PC\AppData\Local\Temp\ksohtml\wps16F0.tmp.png slave启动后会连接到master,所以master要先启动起来。slave只有在master失效后才会建立通信连接以顶替master。客户端给master发送消息后,master会首先将他转发到slave,等待slave反馈存储完毕后,master才开始处理这个消息。当master失效后,slave有2个选择: 1) 关闭slave:管理员重新配置这个slave作为master,然后再配置一个slave作为替补,并将之前存储的消息数据复制一份给slave,以同步。 2) 开启通信端口并初始化网络连接slave自动升级为master 该模式的缺点: 1) master只会把slave连接后的消息传给他,而连接master之前的消息,不会被复制过去。不过你可以通过配置waitForSlave属性来让master一直等待slave启动才开始工作。 2) master只允许一个slave,而slave不能再有slave 何时使用: 当master失效后,用户可接受服务器维护时间,以及管理手工部署新的master和slave 2、 共享存储式Master/Slave
不共享式的MasterSlave让各个broker保持了相对独立性,而共享式则是让所有broker共享同一个存储器,这个存储器一定时间内只能被一个broker占有。相比非共享式,优点是一旦master失效,无需手工恢复,而且也不限制slave broker数量。 共享式目前分为2种,共享数据库和共享文件系统。值得一提的是,另外新的一种是基于zookeeper的,将会在5.9版中发布。 1) 基于数据库的共享:原理是把消息命令都存储在数据库中,并且在数据库中加锁,一旦master失效后,slave获得该锁后继续服务。只要你拥有数据库,并且不在意使用数据库而造成的性能相对其他方式有所降低的话,可以考虑。 file:///C:\Users\PC\AppData\Local\Temp\ksohtml\wps16F1.tmp.png 2) 基于共享文件系统的方式:其实就是把数据库换成了一个共享文件系统如SAN等。 3) ReplicatedLevelDB Store(version 5.9之后) 使用ZooKeeper协调选择一个node作为master。被选择的master broker node开启并接受客户端连接。其他node转入slave模式,连接master并同步他们的存储状态。slave不接受客户端连接。所有的存储操作都将被复制到连接至Master的slaves。 如果master死了,得到了最新更新的slave被允许成为master。fialed node能够重新加入到网络中并连接master进入slave mode。所有需要同步的disk的消息操作都将等待存储状态被复制到其他法定节点的操作完成才能完成。所以,如果你配置了replicas=3,那么法定大小是(3/2)+1=2. Master将会存储并更新然后等待(2-1)=1个slave存储和更新完成,才汇报success。至于为什么是2-1,熟悉Zookeeper的应该知道,有一个node要作为观擦者存在。 单一个新的master被选中,你需要至少保障一个法定node在线以能够找到拥有最新状态的node。这个node将会成为新的master。因此,推荐运行至少3个replica nodes,以防止一个node失败了,服务中断。 file:///C:\Users\PC\AppData\Local\Temp\ksohtml\wps1702.tmp.png PS: l LevelDB是Google开源的持久化KV单机数据库( NOSQL),具有很高的随机写,顺序读/写性能,但是随机读的性能很一般,也就是说,LevelDB很适合应用在查询较少,而写很多的场景。 3、 使用方式(以共享文件系统为例) 1) 部署Active MQ 将ActiveMQ的整个安装文件(如apache-activemq-5.11.1-bin.zip)解压多份(此处为3份),分别放置在不同的IP的服务器上。 2) Active MQ配置 l 分别在上述三份ActiveMQ文件夹中的配置文件activemq.xml中进行持久化配置,如下例(这个位置必须为一个网络文件系统,如SAN,这样不同的机器上的ActiveMQ才能访问这个文件系统): <persistenceAdapter> <kahaDB directory=""/sharedFileSystem/sharedBrokerData"/> </persistenceAdapter> l 修改各自的IP及端口 <transportConnectors> <transportConnectorname="openwire"uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> 3) 客户端配置示例(要使用failover并指定多个activemqURL) 1.2 负载均衡(Network of Brokers)Broker-Cluster部署方式中,各个broker通过网络互相连接并共享queue。这在一定程度上可视为负载均衡的一种方法。有两种实现方式:静态发现和动态发现。 1、 The StaticTransport(静态发现,broker之间的协议,与client无关) 静态发现协议使用硬编码的形式,使得broker可以发现其他的broker,并共享queue。消息消费者可以从其中任意一个broker收到发给自己的消息。 示例如下: [1]. 将ActiveMq拷贝2份,分别命名: apache-activemq-5.10.0_M1,apache-activemq-5.10.0_M2,放在一台机器上(测试而已) [2]. M1做如下配置: <!—配置静态发现,使本broker可发现本机上61617端口的broker--> <networkConnector uri="static:(tcp:// localhost:61617)"/> </networkConnectors> <transportConnectors> <transportConnectorname="openwire" uri="tcp://0.0.0.0:61616?maximumConnectio ns=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> M2做如下配置: <!—配置静态发现,使本broker可发现本机上61616端口的broker--> <networkConnectors> <networkConnectoruri="static:(tcp://localhost:61616)"/> </networkConnectors> <transportConnectors> <transportConnectorname="openwire" uri="tcp://0.0.0.0:61617?maximumConnectio ns=1000&wireFormat.maxFrameSize=104857600"/> </transportConnectors> 通过以上配置使M1和M2这两个 broker通过网络互相连接,并共享queue,
启动M1和M2,可以看到如下启动日志: file:///C:\Users\PC\AppData\Local\Temp\ksohtml\wps1703.tmp.png file:///C:\Users\PC\AppData\Local\Temp\ksohtml\wps1704.tmp.png 可以看到M1和M2,networkconnection has been established [3]. 测试代码: 发送端链接tcp://localhost:61616,发送消息到queue, 接收端做如下修改:
connectionFactory = newActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,"tcp://localhost:61617"); 经测试Receiver可以接受到数据,表示M1和M2已经共享了queue。 如果要实现故障转移,则可将接收端的代码改为: connectionFactory = newActiveMQConnectionFactory( ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, " failover:(tcp://localhost:61617,tcp://localhost:61616)?randomize=false"); 2、 The DiscoveryTransport(动态发现,broker之间的协议,与client无关) DynamicDiscovery集群方式在配置ActiveMQ实例时,不需要知道所有其它实例的URI地址对activemq.xml做如下配置: [1]. M1做如下配置:tworkConnectors> <networkConnectoruri="multicast://default"/> </networkConnectors> <transportConnectors> <transportConnectorname="openwire" uri="tcp://0.0.0.0:61616?maximumConnections=1000&wireFormat.maxFrameSize=104857600" discoveryUri="multicast://default"/> </transportConnectors> [2]. M2做如下配置: <networkConnectors> <networkConnectoruri="multicast://default"/> </networkConnectors> <transportConnectors> <transportConnectorname="openwire" uri="tcp://0.0.0.0:61617?maximumConnections=1000&wireFormat.maxFrameSize=104857600" discoveryUri="multicast://default"/> </transportConnectors> [3]. 启动M1和M2,可以看到如下启动日志: network connection has beenestablished。 [4]. 测试代码和结果同上。
|