配置靜態連接
//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