1,broker clusters
最常见的JMS分布式模型通常如下:
整个环境中包含很多JMS broker和JMS客户端,并且客户端会连接其中一个broker,如果客户端连接的broker恰好挂掉,客户端会尝试自动连接至另一个broker
在JMS客户端一般使用failover协议来实现这个功能。failover传输层重连接逻辑在其它传输层逻辑之上(因此相较于其它传输层逻辑,总是会优先触发),协议规范允许配置任意多个URI,failover传输层会随机选择配置URI中的一个并尝试建立连接,如果连接建立失败,或者之后的传输过程失败,会随机选择另一个URI建立连接,示例如下:
failover:(tcp://remotehost1:61616,tcp://remotehost2:61616)?initialReconnectDelay=100
客户端在建立连接时是随机选择URI,如果不想随机选择URI,需要显式设置randomize=false
2,networks of brokers
由于客户端在建立连接时使用failover协议,所以producer和consumer在初始化时建立连接所选的URI是随机的,这时就会出现下图中的问题
producer将消息发送给broker1,但是consumer初始化时连接的是broker2,broker1中并没有对应的consumer存在,此时将导致producer发送的消息持续在broker1中堆积,consumer却监听不到任何消息。因此客户端使用完全随机的方式建立连接,broker间需要有一种手段进行通信
ActiveMQ支持在broker间建立连接,参见:Networks of Brokers,在上述场景下,broker1接收到请求后,虽然找不到与自己相连的对应consumer,通过broker1和broker2之间的连接,可以将消息forward到broker2,broker2发现对应的consumer后,使用对应的consumer消费消息
修改192.168.137.128配置如下:
<networkConnectors>
<networkConnector name="network" duplex="true" uri="static:(tcp://192.168.137.129:61616)"/>
</networkConnectors>
192.168.137.129配置保持不变,如果duplex为false,仅能建立从broker1到broker2的单向连接,即消息仅能从broker1 forward至broker2,反之则不行,duplex为true,则可建立双向连接
虽然没有consumer直接连接至broker1,但是broker1中依然显示有一个consumer,这个consumer是我们在配置文件中添加的network连接,可以通过这个连接将broker1收到的消息forward至broker2
通常在测试环境使用这种配置方式
优点是broker1和broker2可以同时提供服务(主备模式中仅主能提供服务),因此拥有更高的吞吐
如果消息量较大,broker间的连接容易成为瓶颈,虽说可以添加多条连接,然后对消息进行分片,但无疑增加了配置的复杂性,同时,比起主备模式,broker间通信增加的流量也是不容忽视的
支持load balance,但是仅支持客户端的HA,由于每个broker独立接收客户端请求,当某一个broker在将消息发送给consumer或通过连接将消息发送给另一个broker之前异常挂掉,客户端是不知道的,并且由于消息仅存于挂掉的broker中,在这个broker恢复之前,消息将一直阻塞在broker
3,主备(master slave)
主备的一个特点是客户端仅能与主建立连接,备一直standby,因此简单的主备模型仅支持HA,不支持load balance
3.1,文件共享主备
系统启动时,所有broker争抢文件目录锁(因此底层的文件共享系统必须支持可靠的文件锁),争抢到锁的broker的将作为主,其它作为备
所有接收到的消息持久化之后存放的文件目录在系统层面是共享的,主挂掉后,升为主的备机可以立即从文件目录读取、并继续发送持久化消息,不会出现消息丢失或阻塞的问题,当挂掉的主恢复后,将以备的身份重新加入集群
配置集群前先要配置底层文件共享系统,比较繁琐
3.2,JDBC主备
系统启动时,所有broker争抢DB锁,争抢到锁的broker将作为主,其它作为备
所有接收到的消息使用同一个DB进行持久化,主挂掉后,升为主的备机可以立即从DB读取、并继续发送持久化消息,不会出现消息丢失或阻塞的问题,当挂掉的主恢复后,将以备的身份重新加入集群
由于每条消息都使用DB进行持久化,因此性能比较差,当消息量比较大时,DB很容易成为性能瓶颈
3.3,ZK主备
系统启动时,由zk根据注册的broker协商出主,其它将作为备
假设整个集群有3个节点,至少有2个节点正常,zk才会认为整个集群是可用的(3/2+1=2,即至少有一半以上的节点可用),此时主接收到客户端的消息后,除了将消息持久化至本地,还会将该消息同步复制到另一个节点,当另一个节点完成持久化,才会通知客户端消息发送成功,剩余的一个节点,将进行异步复制。主挂掉后,拥有最新更新的备将被选举为主,由于存在同步复制消息的节点,因此不会出现消息丢失的问题,当主恢复后,将以备的身份加入整个集群
这种主备模式能提供近似文件共享主备的性能,但是需要更多的服务器