问题场景
需求:每隔30分钟抓取集群固定文件夹下的数据包进行分析产生报告。
实现方式
1、使用quartz-1.8.5.jar
2、spring-ScheduledExecutorService+TimeTask-定时器实现
解决步骤
a 导入上述的jar包
b 编写作业类
import com.jcraft.jsch.ChannelSftp;
import itext.CommonUtil;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* Created on 2017/9/6
* Author: youxingyang.
*/
public class Scanner {
/**
* 执行作业
*/
public static void doScanner() {
String p = "/config.properties";
Properties props = new Properties();
InputStream in = Scanner.class.getResourceAsStream(p);
try {
props.load(in);
} catch (IOException e1) {
e1.printStackTrace();
}
String host = props.getProperty("sftpTumor.host");
int port = Integer.parseInt(props.getProperty("sftpTumor.port"));
String username = props.getProperty("sftpTumor.username");
String password = props.getProperty("sftpTumor.password");
ChannelSftp sftp = null;
try {
sftp = FtpUtils.connect(host, port, username, password);
//doSomething
} catch (Exception e) {
e.printStackTrace();
} finally {
sftp.quit();
sftp.getSession().disconnect();
}
}
}
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import java.util.Properties;
/**
* Created on 2017/9/6
* Author: youxingyang.
*/
public class FtpUtils {
/**
* 连接sftp服务器
* @param host 主机
* @param port 端口
* @param username 用户名
* @param password 密码
* @return
*/
public static ChannelSftp connect(String host, int port, String username, String password) {
ChannelSftp sftp = null;
try {
JSch jsch = new JSch();
jsch.getSession(username, host, port);
Session sshSession = jsch.getSession(username, host, port);
System.out.println("Session created.");
sshSession.setPassword(password);
Properties sshConfig = new Properties();
sshConfig.put("StrictHostKeyChecking", "no");
sshSession.setConfig(sshConfig);
sshSession.connect();
System.out.println("Session connected.");
System.out.println("Opening Channel.");
Channel channel = sshSession.openChannel("sftp");
channel.connect();
sftp = (ChannelSftp) channel;
System.out.println("Connected to " + host + ".");
} catch (Exception e) {
e.printStackTrace();
}
return sftp;
}
}
c 配置XML
<!-- 配置作业类 -->
<bean id="scanner" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<!-- 上面的作业类 -->
<bean class="com.xx.Scanner" />
</property>
<!-- 上面的作业类的方法 -->
<property name="targetMethod" value="doScanner" />
<property name="concurrent" value="false" /><!-- 作业不并发调度 -->
</bean>
<!-- 配置作业调度的触发方式(触发器)
org.springframework.scheduling.quartz.SimpleTriggerBean 第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。
org.springframework.scheduling.quartz.CronTriggerBean 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。
-->
<!-- 第一种 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scanner" />
<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="1800000" /><!-- 每30min调度一次 -->
</bean>
<!-- 第二种
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="scanner" />
<property name="cronExpression" value="0 0 12 * * ?" /> 每天12:00运行一次
</bean> -->
<!-- 配置调度工厂 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" /> <!-- 该参数指定的就是之前配置的触发器的名字。 -->
</list>
</property>
</bean>
d 启动Tomcat运行定时器
注意:连接前请确保有权限能连接到相应地址,否则会报超时。
后记:上述XML配置只是用了simpleTrigger运行了一个任务,该任务由一个普通的Scanner类下的doScanner方法实现,那如果想要在此基础上再运行一个定时任务呢?例如每天13点运行另一个不同的任务,该任务由一个普通的Collection类下的doCollection方法实现,配置文件如下:
<!-- 配置作业类 对应simpleTrigger-->
<bean id="scanner" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class="com.business.util.Scanner" /> <!-- 普通的Java类 -->
</property>
<property name="targetMethod" value="doScanner" />
<property name="concurrent" value="false" /><!-- 作业不并发调度 -->
</bean>
<!-- 配置作业类 对应cronTrigger-->
<bean id="collection" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject">
<bean class="com.business.util.Collection" /> <!-- 普通的Java类 -->
</property>
<property name="targetMethod" value="doCollection" />
<property name="concurrent" value="false" /><!-- 作业不并发调度 -->
</bean>
<!-- 配置作业调度的触发方式(触发器)
org.springframework.scheduling.quartz.SimpleTriggerBean 第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。
org.springframework.scheduling.quartz.CronTriggerBean 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。
-->
<!-- 第一种 -->
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="scanner" />
<property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 -->
<property name="repeatInterval" value="1800000" /><!-- 每30min调度一次 -->
</bean>
<!-- 第二种 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="collection" />
<property name="cronExpression" value="0 0 13 * * ?" /> <!-- 每天13点执行 -->
</bean>
<!-- 配置调度工厂 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" /> <!-- 该参数指定的就是之前配置的触发器的名字。 -->
<ref bean="simpleTrigger" /> <!-- 该参数指定的就是之前配置的触发器的名字。 -->
</list>
</property>
</bean>