1.模块功能:
1.对web服务器进行ping操作,如果ping不通,则上报"web服务器无法ping通".
如果可以ping通,继续测试web服务是否可以访问,如果不能访问则上报"web服务无法访问故障".
2.对数据库服务器进行ping操作,如果ping不通,则上报"数据库服务器无法ping通".
如果可以ping通,继续测试web服务是否可以访问,如果不能访问则上报"数据库无法连接故障".
2.主要技术点:
1.通过使用threadlocal线程变量解决多线程(并且每个线程都拥有自己的变量)并发的问题.
2.通过使用dom4j解析xml文件使程序更具扩展性(支持多层, 约定优于配置: 一个property下面必须有一个rule).
5.测试web服务是否可以正常访问.
6.在java文件中获取WEB-INF路径.
7.使用BeanUtils的setProerpty方法要保证bean为此property提供了set方法.
8.检测web服务是否可以访问除了用commons-httpclient类库,还要依赖common-codec,否则执行
HttpMethod method = new GetMethod(url)命令时,会卡死在这里.
9.pingUtil里面有一个ProcessMonitor线程,此线程的目的是如果ping主机的线程一直等待,
那么最长时间等待10秒,超过10秒后由ProcessMonitor线程将其杀死.
10.另外测试主机是否可以ping通,并不一定要通过分析返回结果.
3.功能扩展.
1.对web服务器进行ping操作,如果ping不通,则上报"web服务器无法ping通".
如果可以ping通,继续测试web服务是否可以访问,如果不能访问则上报"web服务无法访问故障".
2.对数据库服务器进行ping操作,如果ping不通,则上报"数据库服务器无法ping通".
如果可以ping通,继续测试web服务是否可以访问,如果不能访问则上报"数据库无法连接故障".
2.主要技术点:
1.通过使用threadlocal线程变量解决多线程(并且每个线程都拥有自己的变量)并发的问题.
2.通过使用dom4j解析xml文件使程序更具扩展性(支持多层, 约定优于配置: 一个property下面必须有一个rule).
同时注意用dom4j解析xml文件,必须依赖于jaxen类库.
<span style="font-size:12px;">package com.ilucky.malf.rule;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.ilucky.malf.rule.BaseRule;
/**
* @author IluckySi
* @date 20140727
*/
public class RuleBuilder {
private static RuleBuilder instance;
public static final String ID = "id";
public static final String NAME = "name";
public static final String TYPE = "type";
public static final String PROPERTY = "property";
private Map<String, BaseRule> map = new HashMap<String, BaseRule>();
public static RuleBuilder getInstance() {
if(instance == null) {
instance = new RuleBuilder();
}
return instance;
}
@SuppressWarnings("unchecked")
private RuleBuilder() {
String malfRulePath = "/com/ilucky/malf/malf_rule.xml";
InputStream is = null;
Document document = null;
try {
is = this.getClass().getResourceAsStream(malfRulePath);
SAXReader saxReader = new SAXReader();
document = saxReader.read(is);
Element root = document.getRootElement();
List<Element> rootChildren = root.elements();
for(int i = 0; rootChildren != null && i < rootChildren.size(); i++) {
Element rootChild = rootChildren.get(i);
String id = rootChild.attributeValue(ID);
map.put(id, build(rootChild));
}
} catch (DocumentException e) {
System.out.println("解析故障规则配置文件失败: " + e.toString());
}finally{
try {
if(is != null){
is.close();
}
} catch (IOException e) {
System.out.println("关闭流发生问题!");
}
}
}
@SuppressWarnings("unchecked")
private BaseRule build(Element element) {
BaseRule baseRule = null;
try {
String ruleId = element.attributeValue(ID);
String ruleName = element.attributeValue(NAME);
String ruleType = element.attributeValue(TYPE);
baseRule = (BaseRule)Class.forName(ruleType).newInstance();
baseRule.setId(ruleId);
baseRule.setName(ruleName);
List<Element> propertyElements = element.selectNodes(PROPERTY);
for(int i = 0; propertyElements != null && i < propertyElements.size(); i++) {
Element propertyElement = propertyElements.get(i);
String propertyName = propertyElement.attributeValue(NAME);
List<Element> ruleElements = propertyElement.elements();
if(!ruleElements.isEmpty()){
Element ruleElement = ruleElements.get(0);
BeanUtils.setProperty(baseRule, propertyName, build(ruleElement));
}
}
} catch (Exception e) {
System.out.println("解析故障规则配置文件失败: " + e.toString());
}
return baseRule;
}
public BaseRule build(String id) {
return map.get(id);
}
}
</span>
3.通过使用quartz任务调度器创建简单定时任务.
<span style="font-size:12px;">package com.ilucky.malf.quartz;
import java.text.ParseException;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
/**
* @author IluckySi
* @date 20140727
*/
public class MalfQuartz {
private int cycle = 30;
private static final String TRIGGER_NAME= "triggerName";
private static final String TRIGGER_GROUP_NAME = "triggerGroupName";
private static final String JOB_NAME = "jobName";
private static final String JOB_GROUP_NAME = "jobGroupName";
public void start(){
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler;
try {
scheduler = schedulerFactory.getScheduler();
scheduler.scheduleJob(createJobDetail(), createTrigger(cycle));
scheduler.start();
System.out.println("故障检测定时任务启动成功!");
} catch (SchedulerException e) {
System.out.println("故障检测定时任务启动失败: "+e.getMessage());
}
}
private Trigger createTrigger(int cycle) {
String cron = "0/" + cycle + " * * * * ?";
CronTrigger trigger = new CronTrigger(TRIGGER_NAME, TRIGGER_GROUP_NAME);
try {
trigger.setCronExpression(cron);
} catch (ParseException e) {
e.printStackTrace();
}
return trigger;
}
private JobDetail createJobDetail() {
return new JobDetail(JOB_NAME, JOB_GROUP_NAME, MalfJob.class);
}
}
</span>
4.测试数据库是否可以正常连接.5.测试web服务是否可以正常访问.
6.在java文件中获取WEB-INF路径.
7.使用BeanUtils的setProerpty方法要保证bean为此property提供了set方法.
8.检测web服务是否可以访问除了用commons-httpclient类库,还要依赖common-codec,否则执行
HttpMethod method = new GetMethod(url)命令时,会卡死在这里.
9.pingUtil里面有一个ProcessMonitor线程,此线程的目的是如果ping主机的线程一直等待,
那么最长时间等待10秒,超过10秒后由ProcessMonitor线程将其杀死.
10.另外测试主机是否可以ping通,并不一定要通过分析返回结果.
3.功能扩展.
1.故障规则配置文件支持多层配置,即多层嵌套,直接看配置文件:
<span style="font-size:12px;"><?xml version="1.0" encoding="UTF-8"?>
<root>
<rule id="malf_web" name="web故障测试" type="com.ilucky.malf.rule.AndRule">
<property name="leftRule">
<rule id="ping_web" name="ping web服务器测试" type="com.ilucky.malf.rule.web.PingWebRule"/>
</property>
<property name="rightRule">
<rule id="access_web" name="访问web服务测试" type="com.ilucky.malf.rule.web.AccessWebRule"/>
</property>
</rule>
<rule id="malf_database" name="数据库故障测试" type="com.ilucky.malf.rule.AndRule">
<property name="leftRule">
<rule id="ping_database" name="ping数据库服务器测试" type="com.ilucky.malf.rule.database.PingDatabaseRule"/>
</property>
<property name="rightRule">
<rule id="connect_database" name="连接数据库服务测试" type="com.ilucky.malf.rule.database.ConnectDatabaseRule"/>
</property>
</rule>
</root></span>
2.条件之间可以建立多种关系(与,或,非,异或等).3.如果要加其他故障测试,只需要修改一下配置文件,然后写工具类,无需修改原有代码.
最后看测试类:
<span style="font-size:12px;">package com.ilucky.malf;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.ilucky.malf.quartz.MalfQuartz;
/**
* @author IluckySi
* @date 20140727
*/
public class MainTest {
public static Map<String, List<Map<String, String>>> datasource= new HashMap<String, List<Map<String, String>>>();
public static void main(String[] arsg) {
//模拟web测试数据.
List<Map<String, String>> webs = new ArrayList<Map<String, String>>();
Map<String, String> map1 = new HashMap<String, String>();
map1.put("type", "web服务");
map1.put("ip", "192.168.72.149");
map1.put("url", "http://192.168.72.149:8080");
webs.add(map1);
Map<String, String> map2 = new HashMap<String, String>();
map2.put("type", "web服务");
map2.put("ip", "192.168.72.153");
map2.put("url", "http://192.168.72.153:8080");
webs.add(map2);
Map<String, String> map3 = new HashMap<String, String>();
map3.put("type", "web服务");
map3.put("ip", "192.168.72.253");
map3.put("url", "http://192.168.72.253:8080");
webs.add(map3);
datasource.put("malf_web", webs);
//模拟数据库测试数据.
List<Map<String, String>> databases = new ArrayList<Map<String, String>>();
Map<String, String> map4 = new HashMap<String, String>();
map4.put("type", "数据库服务");
map4.put("ip", "192.168.73.236");
map4.put("username", "system");
map4.put("password", "talent");
map4.put("url", "jdbc:oracle:thin:@192.168.73.236:1521:k3");
map4.put("sql", "select 1 from dual");
map4.put("driver", "oracle.jdbc.driver.OracleDriver");
databases.add(map4);
Map<String, String> map5 = new HashMap<String, String>();
map5.put("type", "数据库服务");
map5.put("ip", "192.168.67.130");
map5.put("username", "k3");
map5.put("password", "k3");
map5.put("url", "jdbc:oracle:thin:@192.168.67.130:1521:kongsan");
map5.put("sql", "select 1 from dual");
map5.put("driver", "oracle.jdbc.driver.OracleDriver");
databases.add(map5);
Map<String, String> map6 = new HashMap<String, String>();
map6.put("type", "数据库服务");
map6.put("ip", "192.168.72.153");
map6.put("username", "core");
map6.put("password", "core");
map6.put("url", "jdbc:oracle:thin:@192.168.72.153:1521:core");
map6.put("sql", "select 1 from dual");
map6.put("driver", "oracle.jdbc.driver.OracleDriver");
databases.add(map6);
datasource.put("malf_database", databases);
//创建任务调度器:30秒检测一次.
new MalfQuartz().start();
}
}
</span>
只把一部分代码贴出来了,看如下项目目录: