配置静态连接
//vim activemq.xml 添加
<networkConnectors>
<networkConnector name="local network" uri="static://(tcp://47.94.200.13:61616,tcp://47.94.200.13:61716)"/>
</networkConnectors>
可选配置
1.name: 默认的bridge
2.dynamicOnly: 默认是false,如果为true,持久订阅被激活时才创建对应的网络持久订阅。默认是启动时激活
3.decreaseNetworkConsumerPriority: 默认是false。设定消费者优先权,如果为true,网络的消费者优先级降低为-5。如果为false,则默认跟本地消费者一样为0
4.networkTTL: 默认是1,网络中用于消息和订阅消费的broker数量
5.messageTTL: 默认是1,网络中用于消息的broker数量
6.consumerTTL: 默认是1,网络中用于消费的broker数量
7.conduitSubscriptions: 默认true,是否把同一个broker的多个consumer当做一个来处理
8.dynamicallyIncludedDestinations:默认为空,要包括的动态消息地址(同excludedDestinations)
<dynamicallyIncludedDestinations>
<queue physicalName="include.test.foo"/>
<topic physicalName="include.test.bar"/>
</dynamicallyIncludedDestinations>
9.staticallyIncludedDestinations:默认为空,要包括的静态消息地址。(同excludedDestinations)
<staticallyIncludedDestinations>
<queue physicalName="always.include.queue"/>
</staticallyIncludedDestinations>
10.excludedDestinations:默认为空,指定排除地址
11.duplex:默认false,设置是否双向通信。
12. prefetchSize: 默认是1000,持有的未确认的最大消息数量,必须大于0,因为网络消费者不能自己轮询消息
13. suppressDuplicateQueueSubscriptions: 默认false,如果为true,重复的订阅关系一产生即被阻止
14. bridgeTempDestinations: 默认true,是否广播advisory messages来创建临时的destination
15. alwaysSyncSend: 默认false,如果为true,非持久化消息也将使用request/reply方式代替oneway方式发送到远程broker
16. staticBridge: 默认false,如果为true,只有staticallyIncludedDestinations中配置的destination可以被处理
decreaseNetworkConsumerPriority
decreaseNetworkConsumerPriority: 默认是false。设定消费者优先权,如果为true,网络的消费者优先级降低为-5。如果为false,则默认跟本地消费者一样为0
//采用多consumers来几乎同时获取消息,证明本地消息比网络消费优先权要高
package com.ygy.mq.springmq.active;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* Created by guoyao on 2017/7/29.
*/
public class TestMulConsumer {
private static final String DEFAULT_URL = "tcp://47.94.200.13:61616" ;
private static final String OTHER_BROKER_URL = "tcp://47.94.200.13:61716" ;
public static void main(String[] args) throws Exception{
runServer(DEFAULT_URL);
runServer(OTHER_BROKER_URL);
}
private static void runServer(String url) {
new Thread(
()->{
for(int i = 0 ; i < 30 ; i ++) {
new Thread(
()->{
showReceive(url);
}
).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
).start();
}
private static void showReceive( final String url) {
try {
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(url);
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
Session session=connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
Queue my_first_mq=session.createQueue("my_first_mq");
MessageConsumer consumer=session.createConsumer(my_first_mq);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage receive=(TextMessage) message;
try {
receive.acknowledge();
session.close();
connection.close();
System.out.println(" url = " + url + " " + receive.getText());
} catch (Exception e) {
}
}
});
} catch (Exception e) {
}
}
}
消息回流
由本地消费者优先于网络消费,当broker1的消息全被被broker2消息,但broker2的consumer停止时,broker1的consumer将接收不到消息,造成消息丢失。
解决:消息回流。
//配置 (需要双向配置)
<policyEntry queue=">" enableAudit="false">
<networkBridgeFilterFactory>
<conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/>
</networkBridgeFilterFactory>
</policyEntry>
//activemq.xml 中配置
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry topic=">" >
<pendingMessageLimitStrategy>
<constantPendingMessageLimitStrategy limit="1000"/>
</pendingMessageLimitStrategy>
</policyEntry>
<policyEntry queue=">" enableAudit="false">
<networkBridgeFilterFactory>
<conditionalNetworkBridgeFilterFactory replayWhenNoConsumers="true"/>
</networkBridgeFilterFactory>
</policyEntry>
</policyEntries>
</policyMap>
</destinationPolicy>
package com.ygy.mq.springmq.active;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
/**
* Created by guoyao on 2017/7/29.
*/
public class TestBackFlowConsumer {
private static final String DEFAULT_URL = "tcp://47.94.200.13:61616" ;
private static final String OTHER_BROKER_URL = "tcp://47.94.200.13:61716" ;
public static void main(String[] args) throws Exception{
runServer(DEFAULT_URL,3);
runServer(OTHER_BROKER_URL,10);
runServer(DEFAULT_URL, 17);
}
private static void runServer(String url,int index ) {
new Thread(
()->{
for(int i = 0 ; i < index ; i ++) {
new Thread(
()->{
showReceive(url);
}
).start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
).start();
}
private static void showReceive( final String url) {
try {
ActiveMQConnectionFactory activeMQConnectionFactory=new ActiveMQConnectionFactory(url);
Connection connection=activeMQConnectionFactory.createConnection();
connection.start();
Session session=connection.createSession(Boolean.FALSE, Session.CLIENT_ACKNOWLEDGE);
Queue my_first_mq=session.createQueue("my_first_mq");
MessageConsumer consumer=session.createConsumer(my_first_mq);
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage receive=(TextMessage) message;
try {
receive.acknowledge();
session.close();
connection.close();
System.out.println(" url = " + url + " " + receive.getText());
} catch (Exception e) {
}
}
});
} catch (Exception e) {
}
}
}
容错连接
"failover:(tcp://47.94.200.13:61616,tcp://47.94.200.13:61716)?randomize=false
可选参数
1:initialReconnectDelay:在第一次尝试重连之前等待的时间长度(毫秒),默认10
2:maxReconnectDelay:最长重连的时间间隔(毫秒),默认30000
3:useExponentialBackOff:重连时间间隔是否以指数形式增长,默认true
4:backOffMultiplier:递增倍数,默认2.0
5:maxReconnectAttempts: 默认-1|0,自版本5.6起:-1为默认值,代表不限重试次数;0代表从不重试(只尝试连接一次,并不重连), 5.6以前的版本:0为默认值,代表不限重试次数所有版本:如果设置为大于0的数,代表最大重试次数
6:startupMaxReconnectAttempts:初始化时的最大重连次数。一旦连接上,将使用maxReconnectAttempts的配置,默认0
7:randomize:使用随机链接,以达到负载均衡的目的,默认true
8:backup:提前初始化一个未使用连接,以便进行快速失败转移,默认false
9:timeout:设置发送操作的超时时间(毫秒),默认-1
10:trackMessages:设置是否缓存[故障发生时]尚未传送完成的消息,当broker一旦重新连接成功,便将这些缓存中的消息刷新到新连接的代理中,使得消息可以在broker切换前后顺利传送,默认false
11:maxCacheSize:当trackMessages启用时,缓存的最大字节,默认为128*1024bytes
12:updateURIsSupported:设定是否可以动态修改broker uri(自版本5.4起),默认true