10.1.1
master/slave非共享存储
非共享master、slave存储他们各有自己的存储空间,这是最容易用来为broker提供高可用的消息服务,但是呢, 它有自己的缺点:slave需要完整的配置它自己的special 状态,
master也可能需要配一些可选的配置,理想状态下master需要先run,slave不需要start任何transport,也不会初始化任何网络连接,除非master failed了[如果slave 到
master丢掉了大量的连接化,master 失败就会被slave察觉到],非共享存储模式可能会加重message处理的负担,但是和他提供的好处相比那就显得影响特别小了
非共享存储master/slave的过程
producer-send message->matser--replication-->slave--master--ticket->produer-->next message
如果master 挂掉了,有两种选择:
1.自我关闭:保存自己的状态,然后等着管理员来手动配置slave成为master
2.启动transport和初始化网络连接,slave自动的成为master
若slave成功接管 master broker,那么全部的客户端都要利用故障转移转向新的master,配置如下
failover://(tcp://masterhost:61616,tcp://slavehost:61616)?randomize=false
非共享的master/slave有一些限制:
1.1只有master激活后的replication会复制到slave,因此,当一条replication正从master 运输到slave的时候,若此时master还没有收到slave的acknowledge,client 又发
一条消息,假使master fail了,那么信息就可能丢失,如果你想要避免这个问题, 你就不得不在master的配置中设置waitForSlave属性,这个属性会强制master不接受任何客户端的连接
除非master收到收到slave broker的acknowledge
1.2一个master只会有一个slave,slave不会有任何slave
如果在配置非共享master/slave之前你早已经run了broker,那么最好停下broker,复制所有message存储的文件(通常位于data目录)到slave broker,重启master和slave
适用场景[不能丢失任何message,能够容忍down time]
配置非共享master、slave(masterConnector)
1 remoteURI
2.userName
3.password
<services>
<masterConnector remoteURI="tcp://remotehost:62001" userName="Rob" password="Davies" />
</services>
1.3最好slave的transport和network和master保持一致
slave可选配置项:shutdownOnMaterFailure property:当这个参数被配置的时候,slave会平滑的关闭,并且消息不会丢失
2.1共享master/slave【不限slave】
非共享master/slave和其他的保持了独立性,共享存储 master/slave 允许许多broker共享存储机制, 但是在某一时刻只有一个broker是live的,利用共享存储机制
将会确保master broker 失败后,不需要人工干预
2.1.1共享database master、slvae
如果你早已经利用database来消息存储:当AMQ broker用一个关系数据库的时候存储,他会利用表的排他锁确保在同一时刻只有一个AMQ broker能够接入数据库,
如果你运行超过1个broker来试图接入同一个database, 只有第一个broker能够抓住锁,后续的broker只能处于投票状态,当处于投票状态的时候,broker会假定这些broker都是slave,
因此不会启用任何的transport或者网络连接
2.1.2共享文件系统的master/slave模式[推荐kahadb:不通点文件锁]
10.2activemq怎么通过网络传输message的
10.2.1存储转发、
activemq存储转发:activemq总是存储在本地的broker在跨网络转发给另外的broker之前,这个意味着如果message由于网络连接问题不能传输的话,当连接重新变好之后。broker将要
重新send那些没有传输的message
当本地网络建立起一个connection到远程网络之后,远程的broker将要传输contain各种持久化和active consumer的目的地道本地broker,本地broker将要利用这些信息来决定哪些
message 远程broker感兴趣, 并且转发到远程的broker,他也可能定义一个filter在网络连接上决定是否include或者exclude
网络连接器可以配置单向或者双工网络
<networkConnectors>
<networkConnector uri="static://(tcp://backoffice:61617)"
name="bridge"
duplex="true"
conduitSubscriptions="true"
decreaseNetworkConsumerPriority="false">
</networkConnector>
</networkConnectors>
注意配置的顺序
1。网络
2.消息存储
3.Transports
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://activemq.apache.org/schema/core/" >
<broker brokerName="receiver" persistent="true" useJmx="true">
<networkConnectors>
<networkConnector uri="static://(tcp://backoffice:61617)" />
</networkConnectors>
<persistenceAdapter><kahaDB directory="activemq-data"></persistenceAdapter>
<transportConnectors><transportConnector uri="tcp://localhost:62002"></transportConnector></transportConnectors>
</broker>
</beans>
网络discover
当和远程的broker建立了连接后。connection利用发现agent来定位远程broker并且重连连接,activemq提供了两种类型的发现协议
1.dynamic:用多播或者约定的来发现broker
2.static配置一系列broker url来建立连接
tips:利用多播发现协议来创建网络连接是直接转发 的,当你在network connector配置muticast transport开始activemq:
<networkConnectors>
<networkConnector uri="multicast://default"><!--制定了所属组-->
</networkConnectors>
用multicast discory有一些限制,不能控制寻找broker,并且利用本地的network寻找broker也有限,这是因为ip多播不会继承路由器
大多数先前章节的配置列子都是用staitc的方式寻找建立的网络, 先前的列子需要大量的配置配置文件,并且他们不适合任何大型网络,但是他们用在大多数部署应用中
列如:
配置本地本地master broker和本地slave broker连接远程master
<networkConnectors>
<networkConnector uri="static:(tcp://remote-master:61617,tcp://remote-slave:61617)"
</networkConnectors>
static discory agent能够配置来控制重建连接connection(fail情况下)
可选参数
参数名 默认值 描述
initialReconnectDelay 1000 重连之前等待的时间(ms) 【用在useExponentBackOff 关闭的情况下】
maxReconnectDelay 3000 重连之前等待的最大时间(ms)【用在useExponentBackOff 关闭的情况下】
useExponentialBackOff true 每次重连失败时是否增大等待时间
backOffMultiplier 2 增大等待时间的系数
列子
<networkConnectors>
<networkConnector uri="static:(tcp://remote-master:61617?useExponentialBackOff=false)"
</networkConnectors>
10.2.3网络配置
网络默认是依靠远程broker来通知broker哪些message是他们感性趣的,message consumer【active,新的】会监听本地的网络连接,本地的网络连接会订阅远程broker
的messgae,并且转发,为了网络在动态的网络中运行好, 我们需要开启adviseSupport【在静态网络中可以不配置】,activemq用advisory消息来通信两个broker之间的
状态,advisory信息也可以用来转发信息【改变信息的broker】
在远程 broker上可能没有任何active持久化 订阅者或者consumer,因此当网络连接初始化远程broker,远程broker将要阅读destinaction上的messgae,并且pass这些信息到本地的
broker,然后本地broker将要转发这些desination
网络利用broker来创建一个典型的持久化订阅在远程broker上, 因此如果你改变了broker的名字的话,你将要丢失message for持久化topic订阅者,为了避免这种情况,确信你使用了唯一
的brokername在broker元素上
<broker xmlns="http://activemq.apache.org/schema/core"
brokerName="brokerA" dataDirectory="{activemq.base}/data">
<networkConnectors>
<networkConnector name="brokerA-to-brokerB" uri="tcp://remotehost:61616" />
</networkConnectors>
</broker>
为了更好地理解网络是怎么运行的,你最好理解以下参数
网络配置参数
网络参数:DYNAMICONLY
dynamicOnly=true默认是false,假如为true的话 一个网络sub将不会被启用在重启之后
etworkConnector配置
配置参数
属性 默认值 描述
name bridge名称
dynamicOnly false 如果为true, 持久订阅被激活时才创建对应的网路持久订阅。默认是启动时激活。
decreaseNetworkConsumerPriority false 如果为true,网络的消费者优先级降低为-5。如果为false,则默认跟本地消费者一样为0.
networkTTL 1 消息和订阅在网络上通过的broker数量
conduitSubscriptions true 多个网络消费者是否被当做一个消费者来对待。
excludedDestinations empty 不通过网络转发的destination
dynamicallyIncludedDestinations empty 通过网络转发的destinations,注意空列表代表所有的都转发。
staticallyIncludedDestinations empty 匹配的都将通过网络转发-即使没有对应的消费者
duplex false 如果为true,则既可消费又可生产消息到网络broker
prefetchSize 1000 设置网络消费者的prefetch size参数。必须大于0,因为网络消费者不能自己轮询消息。
suppressDuplicateQueueSubscriptions false (从5.3版本开始) 如果为true, 重复的订阅关系一产生即被阻止。
bridgeTempDestinations true 是否广播advisory messages来创建临时destination。
alwaysSyncSend false (从 5.6版本开始) 如果为true,非持久化消息也将使用request/reply方式代替oneway方式发送到远程broker。
staticBridge false (从5.6版本开始) 如果为true,只有staticallyIncludedDestinations中配置的destination可以被处理。
networkConnector的实现原理是基于ActiveMQ的公告消息(AdvisoryMessage)机制的(参见此处)。当broker2通过networkConnector、duplex方式指向broker1时,发生了什么呢?
假定broker1已经启动,这时候broker2开始启动。
1. broker2先启动自己的connector
2. 然后使用一个vm的connector,创建一个connection,把自己作为一个client,连接到broker1。
3. 通过订阅Advisory Message,拿到相互的Consumer与相应的Queue列表。
<networkConnectors>
<networkConnector uri="static:(tcp://remote-master:61617?useExponentialBackOff=false)">
<excludedDestinations>
<queue physicalName="audit.queue-1">
<queue physicalName="audit.queue-2">
<queue physicalName="local.>">
<topic physicalName="local.>">
</excludedDestinations>
</networkConnector>
</networkConnectors>
配置案列
<networkConnectors>
<networkConnector uri="static://(tcp://remote-master:61617?useExponentialBackOff=false)" name="queues_only" duplex="true">
<excludedDestinations>
<queue physicalName=">" />
</excludedDestinations>
</networkConnector>
<networkConnector uri="static://(tcp://remote-master:61617?useExponentialBackOff=false)" name="topics_only" duplex="true">
<excludedDestinations>
<queue physicalName=">" />
</excludedDestinations>
</networkConnector>
</networkConnectors>
10.3在并发应用中配置activemq
10.3.1在垂直规模上是一个技术用来增加单个activemq broker能够处理的连接的数量,默认情况下activemq broker被设计来移动message来确保低延迟和高可用,默认情况activemq利用阻塞io来
处理transport连接,你能够采用非阻塞io在activemq 减少线程使用的数量:配置如下
<broker>
<transportConnectors>
<transportConnector uri="nio://localhost:61616></transportConnector>
</transportConnectors>
</broker>
10.3.2此外,你还可以利用线程池来代替系统参数
ACATIVE_OPTS="-Dorg.apache.activemq.UseDedicatedTaskRunner=false"
10.3.3确保activemq broker有足够的内存来处理大量的并发连接
ACATIVE_OPTS="-Xmx1024M
-Dorg.apache.activemq.UseDedicatedTaskRunner=false"
第二配置适当的内存总量通过System Usage元素来限制
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" optimizedDispatch="true"/>
</policyEntries>
</policyMap>
</destinationPolicy>
第三减少cpu对每个连接的负载
String uri="failover://(tcp://localhsot:61616?"+wireFormat.tighEncodingEnabled="false");
ConnectFactory cf=new ActiveMQConnectFactory(uri);
第四默认的queen配置通常是用来分离线程,并且存储消息和转发他们到有兴趣的consumer,在大量的queen情况下建议关闭optimiz-dISPATCH
10.3.2水平规模上
failover://(tcp://broker1:61616,tcp://broker2:61616)?redomomize=true)
为了确保队列的message或者持久化的topic 订阅者不被孤立,配置网络用dynamicOnly和prefetchS比较好
<networkConnector uri="static://(tcp://remote-master:61617?useExponentialBackOff=false)" name="bridge" dynamicOnly="true" prefetchSize="1">