com.alibaba.dts.client.executor.grid.timer.HealthChecker Maven / Gradle / Ivy
package com.alibaba.dts.client.executor.grid.timer;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import com.alibaba.dts.client.config.NodeConfig;
import com.alibaba.dts.client.executor.job.context.ClientContextImpl;
import com.alibaba.dts.client.store.Store;
import com.alibaba.dts.common.exception.AccessException;
import com.alibaba.dts.common.exception.InitException;
import com.alibaba.dts.common.logger.SchedulerXLoggerFactory;
import com.alibaba.dts.common.logger.innerlog.Logger;
import com.alibaba.dts.common.util.NamedThreadFactory;
/**
* @author Ronan Zhan
* @date 2018/2/1
*/
public class HealthChecker {
private static final Logger logger = SchedulerXLoggerFactory.getLogger(HealthChecker.class);
public static volatile AtomicBoolean h2Alive = new AtomicBoolean(true);
public static volatile AtomicLong failCounter = new AtomicLong();
private ClientContextImpl clientContext;
private ScheduledThreadPoolExecutor HealthCheckThreadPool = new ScheduledThreadPoolExecutor(1, new NamedThreadFactory("SchedulerX-H2-Health-Check-Thread-"));
public HealthChecker(ClientContextImpl clientContext) {
this.clientContext = clientContext;
}
public void init() {
HealthCheckThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
if (SystemMonitor.getDiskAvailablePercentage().get() < 5) {
logger.error("healthCheck error disk usage < 5% !");
h2Alive.set(false);
return;
}
/*
CommonDao commonDao = clientContext.getStore().getCommonDao();
if (commonDao == null) {
throw new AccessException("commonDao is closed!");
}
clientContext.getStore().getCommonDao().healthCheck();
*/
clientContext.getStore().getTaskSnapshotDao().queryTotalCount();
h2Alive.set(true);
failCounter.set(0);
} catch (AccessException e) {
h2Alive.set(false);
long count = failCounter.addAndGet(1);
if (count % 6 == 0) {
logger.error("healthCheck error", e);
recover();
}
} catch (Throwable throwable) {
logger.error("healthCheck error", throwable);
}
}
}, 0, 10, TimeUnit.SECONDS);
}
private void recover() {
logger.info("start recovering, dbPath={}...", clientContext.getNodeConfig().getDbPath());
try {
// checkDiskSpace();
closeStore();
deleteDbFile(clientContext.getNodeConfig());
reSetStore(clientContext);
h2Alive.set(true);
logger.info("recovering finished");
} catch (Throwable e) {
logger.error("recover datasource error", e);
}
}
private void checkDiskSpace() throws IOException {
if (SystemMonitor.getDiskAvailablePercentage().get() < 10) {
throw new IOException("disk usable space is less than 10%");
}
}
private void closeStore() {
clientContext.getStore().close();
}
private void reSetStore(ClientContextImpl clientContext) throws InitException {
clientContext.setStore(new Store(clientContext));
clientContext.getStore().init();
}
private void deleteDbFile(NodeConfig nodeConfig) {
String dbUrl = clientContext.getNodeConfig().getDbPath();
File file = new File(dbUrl);
if (file.exists()) {
if (file.isDirectory()) {
for (File dbFile : file.listFiles()) {
if (dbFile.exists()) {
dbFile.delete();
}
}
}
}
}
}