微服务和VUE入门教程(21): springboot中定时器-Schedule
微服务和VUE入门教程(0): 着手搭建项目
微服务和VUE入门教程(1): 搭建前端登录界面
微服务和VUE入门教程(2): 注册中心
微服务和VUE入门教程(3): user微服务的搭建
微服务和VUE入门教程(4):网关zuul的搭建
微服务和VUE入门教程(5): 前后端交互
微服务和VUE入门教程(6):连接数据库-mybatis
微服务和VUE入门教程(7):配置中心-config
微服务和VUE入门教程(8):前端主页的编写
微服务和VUE入门教程(9): token验证-token后端生成以及前端获取
微服务和VUE入门教程(10): token验证-前端登录拦截以及token过期提醒
微服务和VUE入门教程(11): mybatis 动态查询
微服务和VUE入门教程(12):前端提示搜索框的实现
微服务和VUE入门教程(13): token验证-zuul拦截与验证
微服务和VUE入门教程(14): 热部署
微服务和VUE入门教程(15): 课堂小知识
微服务和VUE入门教程(16): zuul 熔断
微服务和VUE入门教程(17): VUE 响应拦截器
微服务和VUE入门教程(18): 前端接口模块化
微服务和VUE入门教程(19): VUE组件化–子组件向父组件通信
微服务和VUE入门教程(20): VUE组件化–父组件向子组件通信
微服务和VUE入门教程(21): springboot中定时器-Schedule
微服务和VUE入门教程(22): 页面长时间未操作自动退出登录
微服务和VUE入门教程(23): 微服务之间的调用
微服务和VUE入门教程(24): 微服务之断路器
微服务和VUE入门教程(25): 微服务之Hystrix-dashboard
微服务和VUE入门教程(26): 微服务之turbine
微服务和VUE入门教程(27):VUE前端工程打包
1. 前言
一般情况下,我们如果需要某个表,比如错误日志表,当这个表中的数量超过一定的阈值,系统自动会给我们发送一个警报,提醒我们要做一些处理。我们需要利用定时器(Schedule)来完成来实现这个功能。
2. 功能介绍
当警报关闭的时候,我们通过点击“开启警报”来启动后端的警报监控。后端每10秒(定时器时间)来访问一下student表,
若这个表中的数量超过了50(阈值),就会发邮件给2605121231@qq.com.
当经过启动的时候,操作按钮变成:关闭警报,重启警报。
3. 新建警报表
CREATE TABLE `alarm` (
`threshold` INT(20) DEFAULT NULL,
`cronTime` INT(20) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`alarmStatus` INT(20) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我们需要将警报信息持久化,这样才能每次打开页面的时候得到正确的警报设置信息。
4. StuApplication.java
加入
@EnableScheduling //启动Scheduled定时任务机制
很重要!很重要!很重要!
5. xml
在mapper.xml文件中,我们主要实现三个方法,alarmSel,alarmUpdateThreshold,alarmUpdate。
pojo,dao,service 大同小异。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--DAO的路径-->
<mapper namespace="com.student.dao.AlarmDAO">
<!--实体类路径-->
<resultMap id="BaseAlarmMap" type="com.student.pojo.Alarm">
<result column="threshold" property="threshold" />
<result column="cron_time" property="cronTime" />
<result column="email" property="email" />
<result column="alarm_status" property="alarmStatus" />
</resultMap>
<!--查询警报信息-->
<select id="alarmSel" resultMap="BaseAlarmMap">
select * from alarm
</select>
<!--更新阈值-->
<update id="alarmUpdateThreshold" parameterType="java.util.Map">
update alarm set threshold = #{threshold}
</update>
<!--更新信息-->
<update id="alarmUpdate" parameterType="java.util.Map">
update alarm set
threshold = #{threshold},cron_time = #{cronTime},email = #{email},alarm_status = #{alarmStatus}
</update>
</mapper>
6. AlarmController
@RestController
@CrossOrigin
public class AlarmController {
@Autowired
AlarmService alarmService;
@Autowired
StuService stuService;
/**
* 定时器
* */
// 基本配置
private String DEFAULT_CRON = "0/5 * * * * ?";
private int threshold = 50;
private String email;
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
private ScheduledFuture<?> future;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
return new ThreadPoolTaskScheduler();
}
//开启警报
@RequestMapping(value = "/alarm/start",method = RequestMethod.POST)
public JSONObject startAlarm(@RequestBody JSONObject jsonObject){
threshold = jsonObject.getInteger("threshold");
String cronTime = jsonObject.getString("cronTime");
email = jsonObject.getString("email");
DEFAULT_CRON = "0/" + cronTime + " * * * * ?";
//开启定时器
future = threadPoolTaskScheduler.schedule(new MyRunable(),new CronTrigger(DEFAULT_CRON));
int i = alarmService.updateAlarm(jsonObject);
JSONObject result = new JSONObject();
if(i==1){
result.put("state",200);
result.put("alarmStatus",1);
}else {
result.put("state",400);
}
return result;
}
// 警报线程
private class MyRunable implements Runnable{
@Override
public void run() {
// 查找学生信息表总数量
int count = stuService.getStuCount(null);
if(count > threshold){
//TODO: 发邮件
System.out.println("已达到极限");
// 提高阈值
threshold = threshold + 50;
JSONObject alarmThreshold = new JSONObject();
alarmThreshold.put("threshold",threshold);
alarmService.UpdateAlarmThreshold(alarmThreshold);
}
System.out.println("run," + new Date()+" ,count" + count);
}
}
}
可以看出,在这个controller类前面,定义了一堆参数,有阈值,定时器的间隔时间,还有一个定时器的方法。
启动警报方法中,通过使用定时器
future = threadPoolTaskScheduler.schedule(new MyRunable(),new CronTrigger(DEFAULT_CRON));
来执行MyRunable这个方法,并且设置了定时器时间为:DEFAULT_CRON ;
MyRunable继承了Runnable这个方法,开启了重写了run方法。
7. 停止警报和重启警报
//停止警报
@RequestMapping(value = "/alarm/stop", method = RequestMethod.POST)
public JSONObject stopAlarm(@RequestBody JSONObject jsonObject){
//关闭定时器
if(future != null){
System.out.println("警报关闭");
future.cancel(true);
}
int i = alarmService.updateAlarm(jsonObject);
JSONObject result = new JSONObject();
if(i == 1){
result.put("state",200);
result.put("alarmStatus",0);
}else {
result.put("state",400);
}
return result;
}
// 重启警报
@RequestMapping(value = "/alarm/restart", method = RequestMethod.POST)
public JSONObject restartAlarm(@RequestBody JSONObject jsonObject){
System.out.println("重启");
threshold = jsonObject.getInteger("threshold");
String cronTime = jsonObject.getString("cronTime");
email = jsonObject.getString("email");
DEFAULT_CRON = "0/" + cronTime + " * * * * ?";
//先停止再重启
if(future != null){
future.cancel(true);
}
future = threadPoolTaskScheduler.schedule(new MyRunable(),new CronTrigger(DEFAULT_CRON));
//修改数据库中警报表的设置
int i = alarmService.updateAlarm(jsonObject);
JSONObject result = new JSONObject();
if(i == 1){
result.put("state",200);
result.put("alarmStatus",1);
}else {
result.put("state",400);
}
return result;
}
停止警报和重启警报,也是建立在定时器的基础上。
if(future != null){
System.out.println("警报关闭");
future.cancel(true);
}
通过取消定时器future,从而停止警报。重启警报实现原理是先停止再重启,使更改的警报信息生效。
8. 前端代码
代码代码没有什么值得注意的地方,就不写了。