由于实现了重新启动机制,我正面临使用ScheduledExecutorService
的错误行为。ScheduledExecutorService Thread创建多个线程
问题 - 短
每次重新启动尝试创建一个新的计划任务,然后重新启动旧的。
问题 - 龙
过程的目标是发布消息到RabbitMQ的不时(这是保活)。当RabbitMQ发生异常时,它使用ExceptionObserver通知 发生异常。实现的ExceptionObserver会停止服务并重新启动它。它试图重启3次,如果重启成功,计数为 重置为零。如果无法重新启动,则尝试计数会递增,如果达到尝试限制,则会关闭该过程。
每次服务重新启动时,它都会创建一个新的“KeepAliveService”并重新启动最后的服务。因此,每次发生异常时,都会创建一项新服务,并重新启动旧的服务。如果重启后有1次异常,则有2个进程正在运行。如果2个异常事件有3个进程正在运行,依此类推。
服务类处理保持连接服务(启动/停止ScheduledExecutorService的)
private KeepaliveExecutor keepaliveExecutor; // This is the runnable used inside the scheduledService
private ScheduledFuture futureTask; // The escheduled task
private ScheduledExecutorService scheduledService; // the scheduled service
private ExceptionObserver exceptionObserver; // The Exception Handler, which will handle the exceptions
public void startService(final int keepaliveTime) throws IllegalArgumentException, FInfraException {
keepaliveExecutor = new KeepaliveExecutor(new RabbitMQService(settings), settings);
keepaliveExecutor.setExceptionObserver(exceptionObserver);
scheduledService = Executors.newSingleThreadScheduledExecutor();
futureTask = scheduledService.scheduleAtFixedRate(keepaliveExecutor, 0, keepaliveTime, TimeUnit.MINUTES);
}
public void stopService() {
futureTask.cancel(true);
scheduledService.shutdown();
}
的KeepaliveExecutor类
class KeepaliveExecutor implements Runnable {
private FInfraExceptionObserver exceptionObserver;
@Override
public void run() {
try {
final String keepAlive = JsonMapper.toJsonString(keepaliveMessage);
rabbitService.publishMessage(keepAlive);
keepaliveMessage.setFirtsPackage(false);
} catch(FInfraException ex) {
if(exceptionObserver != null) {
exceptionObserver.notifyExpcetion(ex);
}
}
}
的ExceptionObserver实现类
public class FInfraExceptionHandler implements FInfraExceptionObserver {
private final FInfraServiceHandler finfraHandler;
public FInfraExceptionHandler(FInfraServiceHandler finfraHandler) {
this.finfraHandler = finfraHandler;
}
@Override
public void notifyExpcetion(Throwable ex) {
Util.logger.log(Level.INFO, "F-Infra Exception occurred", ex);
finfraHandler.stopService();
Util.logger.log(Level.INFO, "Waiting 30s for restarting...");
Util.wait(30, TimeUnit.SECONDS);
finfraHandler.startService();
}
的FInfraServiceHandler
public class FInfraServiceHandler {
private static final int ATTEMPT_LIMIT = 3;
private FInfraService finfraService;
private int keepaliveTime;
private int attempt;
public FInfraServiceHandler() {
this.finfraService = new FInfraService();
this.finfraService.setExceptionObserver(new FInfraExceptionHandler(this));
this.attempt = 0;
}
void startService(){
if(attempt <= ATTEMPT_LIMIT) {
try {
attempt++;
Util.logger.log(Level.INFO, "Starting F-Infra Service. Attemp[{0} of {1}]", new String[]{String.valueOf(attempt), String.valueOf(ATTEMPT_LIMIT)});
finfraService.startService(keepaliveTime);
} catch(FInfraException | RuntimeException ex){
Util.logger.log(Level.INFO, "F-INFRA EXCEPTION", ex);
startService();
}
Util.logger.log(Level.INFO, "F-Infra started!");
attempt = 0;
return;
}
Util.logger.log(Level.INFO, "Restart attemp limit reached.");
Main.closeAll(new ShutdownException("It's not possible stablish a connection with F-Infra Service."));
}
public void stopService() {
if(attempt > 0){
Util.logger.log(Level.INFO, "Stpoping F-Infra...");
finfraService.stopService();
}
}
这里如下这告诉我有运行
jul 16, 2017 2:58:03 PM domain.FInfraServiceHandler startService
INFO: Starting F-Infra Service. Attemp[1 of 3]
jul 16, 2017 2:58:03 PM domain.FInfraServiceHandler startService
INFO: F-Infra started!
jul 16, 2017 5:01:15 PM domain.FInfraExceptionHandler notifyExpcetion
INFO: F-Infra Exception occurred
domain.FInfraException: java.net.UnknownHostException: rabbit.domain
at domain.RabbitMQService.openConnection(RabbitMQService.java:48)
at domain.RabbitMQService.publishMessage(RabbitMQService.java:66)
at domain.KeepaliveExecutor.run(KeepaliveExecutor.java:38)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.UnknownHostException: rabbit.domain
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at com.rabbitmq.client.impl.FrameHandlerFactory.create(FrameHandlerFactory.java:32)
at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:34)
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:91)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:670)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:722)
at domain.RabbitMQService.openConnection(RabbitMQService.java:45)
... 9 more
jul 16, 2017 5:01:15 PM domain.FInfraExceptionHandler notifyExpcetion
INFO: Waiting 30s for restarting...
jul 16, 2017 5:01:45 PM domain.FInfraServiceHandler startService
INFO: Starting F-Infra Service. Attemp[1 of 3]
jul 16, 2017 5:01:45 PM domain.FInfraServiceHandler startService
INFO: F-Infra started!
jul 16, 2017 6:01:58 PM domain.FInfraExceptionHandler notifyExpcetion
INFO: F-Infra Exception occurred
domain.FInfraException: java.net.UnknownHostException: rabbit.domain
at domain.RabbitMQService.openConnection(RabbitMQService.java:48)
at domain.RabbitMQService.publishMessage(RabbitMQService.java:66)
at domain.KeepaliveExecutor.run(KeepaliveExecutor.java:38)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.UnknownHostException: rabbit.domain
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at com.rabbitmq.client.impl.FrameHandlerFactory.create(FrameHandlerFactory.java:32)
at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:34)
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:91)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:670)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:722)
at domain.RabbitMQService.openConnection(RabbitMQService.java:45)
... 9 more
jul 16, 2017 6:01:58 PM domain.FInfraExceptionHandler notifyExpcetion
INFO: Waiting 30s for restarting...
jul 16, 2017 6:02:03 PM domain.FInfraExceptionHandler notifyExpcetion
INFO: F-Infra Exception occurred
domain.FInfraException: java.net.UnknownHostException: rabbit.domain
at domain.RabbitMQService.openConnection(RabbitMQService.java:48)
at domain.RabbitMQService.publishMessage(RabbitMQService.java:66)
at domain.KeepaliveExecutor.run(KeepaliveExecutor.java:38)
at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(Unknown Source)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.net.UnknownHostException: rabbit.domain
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at com.rabbitmq.client.impl.FrameHandlerFactory.create(FrameHandlerFactory.java:32)
at com.rabbitmq.client.impl.recovery.RecoveryAwareAMQConnectionFactory.newConnection(RecoveryAwareAMQConnectionFactory.java:34)
at com.rabbitmq.client.impl.recovery.AutorecoveringConnection.init(AutorecoveringConnection.java:91)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:670)
at com.rabbitmq.client.ConnectionFactory.newConnection(ConnectionFactory.java:722)
at domain.RabbitMQService.openConnection(RabbitMQService.java:45)
... 9 more
jul 16, 2017 6:02:03 PM domain.FInfraExceptionHandler notifyExpcetion
INFO: Waiting 30s for restarting...
jul 16, 2017 6:02:28 PM domain.FInfraServiceHandler startService
INFO: Starting F-Infra Service. Attemp[1 of 3]
jul 16, 2017 6:02:28 PM domain.FInfraServiceHandler startService
INFO: F-Infra started!
jul 16, 2017 6:02:33 PM domain.FInfraServiceHandler startService
INFO: Starting F-Infra Service. Attemp[1 of 3]
jul 16, 2017 6:02:33 PM domain.FInfraServiceHandler startService
INFO: F-Infra started!
我不知道该怎么办,关闭旧线,或者使用当前的重新启动多个服务日志。我尝试过的很多方法都是调用Thread.currentThread()。interrupt();在调用start方法之前调用ExceptionObserver类。 但这并不奏效。
我不知道该怎么做。