实现spring BackOff接口,自定义退避算法,用于activeMQ配置监听器容器重连服务器策略
--这里设置最大尝试重连3次,每3次尝试重连后,重置重连次数,下次则根据初始间隔的倍数递增进行重连
目的:解决activeMQ配置监听容器连接服务失败后一直间隔5s就重新尝试连接导致资源占用异常的问题,实现spring BackOff接口自定义退避算法,每个工程服务下配置文件的activeMQ服务地址为空则直接中止尝试重连,若不为空则根据实现的退避算法来控制重连间隔时间;
在spring配置activeMQ监听容器时,使用自定义的spring backoff退避算法,例如


实现spring BackOff接口的类代码示例:
package xxx.message.JMS;
import org.springframework.util.backoff.BackOff;
import org.springframework.util.backoff.BackOffExecution;
import xxx.utils.CheckUtil;
import xxx.utils.PropertiesUtil;
/**
* 实现spring BackOff接口,自定义退避算法,用于activeMQ配置监听器容器重连服务器策略
* (activeMQ连接服务器失败按照指数时间间隔重新尝试连接,若使用的服务没有配置activeMQ服务地址则直接中止尝试连接)
*
* @author wu
*
*/
public class MessageFixedBackOff implements BackOff
{
private long interval = 5000;
private long maxAttempts = Long.MAX_VALUE;
public MessageFixedBackOff() {
}
public MessageFixedBackOff(long interval, long maxAttempts) {
this.interval = interval;
this.maxAttempts = maxAttempts;
}
/**
* Set the interval between two attempts in milliseconds.
*/
public void setInterval(long interval) {
this.interval = interval;
}
/**
* Return the interval between two attempts in milliseconds.
*/
public long getInterval() {
return interval;
}
/**
* Set the maximum number of attempts in milliseconds.
*/
public void setMaxAttempts(long maxAttempts) {
this.maxAttempts = maxAttempts;
}
/**
* Return the maximum number of attempts in milliseconds.
*/
public long getMaxAttempts() {
return maxAttempts;
}
@Override
public BackOffExecution start()
{
return new FixedBackOffExecution();
}
private class FixedBackOffExecution implements BackOffExecution {
private long currentAttempts = 0;//初始连接次数
private long interval = getInterval();//初始间隔
@Override
public long nextBackOff() {
if(CheckUtil.isNullorEmpty(PropertiesUtil.getValue("activemq.url"))){
return STOP;
}
long maxInterval = 7200 * 1000L;//最大间隔
int multiplier = 2;//递增倍数(即下次间隔是上次的多少倍)
this.currentAttempts++;
//设置了最大重连次数,则每次轮询一组重连间隔递增倍数增长,直到大于最大间隔重置
if (this.currentAttempts <= getMaxAttempts()) {
return interval;
}else {
//重置初始连接次数为0
currentAttempts = 0;
//判断是否超过最大间隔,则重置初始间隔
if(interval * multiplier > maxInterval){
interval = getInterval();
}else{
//递增间隔
interval = interval * multiplier;
}
return interval;
}
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("MessageFixedBackOff{");
sb.append("interval=").append(interval);
String attemptValue = (MessageFixedBackOff.this.maxAttempts == Long.MAX_VALUE ?
"unlimited" : String.valueOf(MessageFixedBackOff.this.maxAttempts));
sb.append(", currentAttempts=").append(this.currentAttempts);
sb.append(", maxAttempts=").append(attemptValue);
sb.append('}');
return sb.toString();
}
}
}
大致效果如日志输出:
2018-06-14 17:28:16 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=5000, currentAttempts=0, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:28:22 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=5000, currentAttempts=1, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:28:28 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=5000, currentAttempts=2, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:28:34 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=5000, currentAttempts=3, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:28:45 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=10000, currentAttempts=0, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:28:56 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=10000, currentAttempts=1, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:29:07 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=10000, currentAttempts=2, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:29:18 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=10000, currentAttempts=3, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:29:40 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=20000, currentAttempts=0, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:30:01 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=20000, currentAttempts=1, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:30:22 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=20000, currentAttempts=2, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:30:43 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=20000, currentAttempts=3, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:31:24 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=40000, currentAttempts=0, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:32:05 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=40000, currentAttempts=1, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:32:46 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=40000, currentAttempts=2, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:33:27 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=40000, currentAttempts=3, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:34:48 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=80000, currentAttempts=0, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:36:09 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=80000, currentAttempts=1, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:37:30 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=80000, currentAttempts=2, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:38:51 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=80000, currentAttempts=3, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:41:32 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=160000, currentAttempts=0, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:44:13 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=160000, currentAttempts=1, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:46:55 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=160000, currentAttempts=2, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]
2018-06-14 17:49:36 [messageTopicListenerContainer-1] ERROR o.s.j.l.DefaultMessageListenerContainer - Could not refresh JMS Connection for destination 'queue://projectTopic' - retrying using MessageFixedBackOff{interval=160000, currentAttempts=3, maxAttempts=3}. Cause: Could not connect to broker URL: tcp://127.0.0.1:61616. Reason: java.net.ConnectException: Connection refused: connect [DefaultMessageListenerContainer.java:947]