我试图检查某些数据库主机是否还活着。 ConfigReader类解析xml文件并获取某些数据库主机的列表。 如果某些主机不可用,我想看到这样的日志:
running check for host:dbhost1
Some Exception is ...
running check for host:dbhost2
host is alive
等等。
但是如果主机不活动,我会看到这个异常。应用程序退出而不是记录并抛出异常。
#### running check for host:dbhost1
Exception in thread "main" java.sql.SQLException: Cannot create PoolableConnectionFactory (I/O-Fehler: The Network Adapter could not establish the connection)
at org.apache.commons.dbcp2.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:2291)
at org.apache.commons.dbcp2.BasicDataSource.createDataSource(BasicDataSource.java:2038)
at org.apache.commons.dbcp2.BasicDataSource.getConnection(BasicDataSource.java:1533)
at com.csinfra.jdbmon.app.CheckDatabase.runCheckGroup(CheckDatabase.java:108)
以下是课程:
@Component
public class ScheduleCheck {
public ConfigReader configReader;
public CheckDatabase checkDatabase;
public void runHostCheck() throws Exception {
configReader.readConfig();
checkDatabase.setConfigReader(configReader);
for(Host host:configReader.getHostMap().values()){
System.out.println("#### running check for host:"+host.getId());
checkDatabase.runCheckGroup(host, getCheckFromCheckGroup(host));
}
}
}
@Component
public class CheckDatabase {
public void runCheckGroup(Host host) throws Exception{
createConnections(host.getJdbcurl(), host.getJdbcuser(), host.getJdbcpassword(), host.getDriverclassname());
Connection connection_single = jdbcPool.getConnection();
if(connection_single!=null){
System.out.println("host is alive");
}
}
public void createConnections(String url, String username, String password, String driverClassname) throws Exception{
jdbcPool = new BasicDataSource();
jdbcPool.setDriverClassName(driverClassname);
jdbcPool.setUsername(username);
jdbcPool.setUrl(url);
jdbcPool.setPassword(password);
jdbcPool.setInitialSize(2);
jdbcPool.setCacheState(false);
jdbcPool.setMaxTotal(2);
jdbcPool.setMaxWaitMillis(6000);
jdbcPool.setMaxIdle(2);
jdbcPool.setDefaultReadOnly(true);
}
}
@Configurable
@Aspect
@Component
public class AopMethodLogger {
private static final Logger LOGGER = RootLogger.getLogger(AopMethodLogger.class);
@AfterThrowing(pointcut = "execution(* com.csinfra.app..*.*(..))", throwing = "exception")
public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) throws Throwable {
LOGGER.debug("Some Exception is "+exception.getLocalizedMessage());
throw exception;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<aop:aspectj-autoproxy proxy-target-class="true" />
<context:component-scan base-package="com.csinfra.app />
<bean id="aopMethod" class="com.csinfra.app.log.AopMethodLogger" />
<bean id="scheduleCheck" class="com.csinfra.app.ScheduleCheck">
<property name="configReader" ref="configReader" />
<property name="checkDatabase" ref="checkDatabase" />
</bean>
<bean id="checkDatabase" class="com.csinfra.app.CheckDatabase">
</bean>
</beans>
答案 0 :(得分:0)
CheckDatabase.runCheckGroup抛出异常并且没有处理,这就是应用程序退出的原因。 使用try / catch调用runCheckGroup并记录异常:
try{
checkDatabase.runCheckGroup(host, getCheckFromCheckGroup(host));
} catch(Exception e){
System.out.println("Exception occured :"+e);
}
与数据库的连接数量有限,因此创建新连接只是为了检查数据库是否存活似乎相当昂贵。 让spring注入所有可用的数据源可能更好:
@Autowire
List<DataSource>dataSources;
这样做的好处是可以自动检查所有已配置的数据源,无需额外配置。
而不是迭代那些,为每个做像
这样的事情new JdbcTemplate(dataSource).queryForInt("SELECT 1")
检查它的活着。