springboot+idea集成xxl-job定时管理中心

springboot+idea集成xxl-job定时管理中心

最近公司要求做一个定时任务管理的项目,网上查资料看到了xxl-job,尝试搭建了一个,做一下分享,希望对大家有帮助

  

  功能模块:

  通过xxl,我们可以用相对简单的方式,把定时相关的任务交给xxl去管理。比如,你需要在十点执行一个定时任务,如果你已经注册了执行器,那么你只需要通过网页添加一条任务数据即可,管理中心会在执行时间去调用你的项目,执行相应的处理器。

  xxl可以添加定时执行的任务,也可以添加只执行一次的任务,用的是Quartz,Cron表达式

  你也可以通过源码动态地对任务进行CRUD操作

  xxl支持分布式管理,可以多个执行器执行同一条任务

  它有可视化页面,页面做的很漂亮也很简洁,瞄一眼大概都会操作,如下:

  

  ok,废话不多说

  接下来,本文将主要讲解搭建的流程,及通过调用管理中心接口,使用源码对任务进行CRUD操作。

 

一、源码部分及使用说明

  源码:https://github.com/xuxueli/xxl-job

  使用说明:https://www.xuxueli.com/xxl-job/#%E3%80%8A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BB%BB%E5%8A%A1%E8%B0%83%E5%BA%A6%E5%B9%B3%E5%8F%B0XXL-JOB%E3%80%8B

  

  1.1 下载管理项目xxl-job

 

  1.2 切换分支,我这里用的是2.2.0版本,注意:不能用人家正在开发的主分支作为管理中心,一方面,主分支正在开发,很可能有未知的错误。另一方面,正在开发的分支没有配套的maven依赖。没有合适的依赖,管理中心项目和客户端项目连接肯定会有问题的

  1.3 目录简介

    

    1.3.1 文件tables_xxl_job.sql必须放到自己的库里运行一下,这是管理中心项目要用到的数据库。把“数据库初始化脚本”运行一下,放到自己的库里,这个是mysql的,我这边xxl_job_registry报了键字符太长,就把键删掉了,因为我这边注册的客户端比较少

    1.3.2 模块xxl-job-admin就是项目的启动模块

    1.3.3 基本上xxl-job-executor-sample-springboot这个项目包含了你要搭建客户端项目的全部内容,如果没有特殊要求,复制粘贴即可

二、搭建管理中心项目

  2.1 修改xxl-job\xxl-job-admin\src\main\resources\application.properties,主要是配置数据库和管理界面的用户和密码

+ View Code

  2.2 启动项目,访问http://localhost:8100/xxl-job-admin/,如下就成功了

 

三、搭建客户端(执行端),打开你需要执行定时任务的项目

  3.1 结构

 

  3.2 配置类,这个不用修改,放到你自己的项目里就行

  3.3 处理器,我这个版本的使用@XxlJob注解即可配置处理器,就是定时任务要执行的代码,注意这里的public ReturnT<String> demoJobHandler(String param) throws Exception格式不可修改

@Component

public class SampleXxlJob {

    private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);





    /**

     * 1、简单任务示例(Bean模式)

     */

    @XxlJob("demoJobHandler")

    public ReturnT<String> demoJobHandler(String param) throws Exception {

        XxlJobLogger.log("XXL-JOB, Hello World.");



        for (int i = 0; i < 5; i++) {

            XxlJobLogger.log("beat at:" + i);

            TimeUnit.SECONDS.sleep(2);

        }

        return ReturnT.SUCCESS;

    }





}

  3.4 配置文件,添加这个就行了,注意:http://127.0.0.1:8100/xxl-job-admin这个地址就是管理中心的地址,不要配错。还有这个appname将会在创建执行器的时候用到,可以自己命名。这里面的port和项目的port不一样,是执行器的port,不要和项目的port配成一样,默认搞9999就行了

xxl:

  job:

    admin:

      addresses: http://127.0.0.1:8100/xxl-job-admin

    executor:

      appname: xxl-job-executor-test

      ip:

      port: 9999

      logpath: /data/applogs/xxl-job/jobhandler

      logretentiondays: 30

      address:

    accessToken:

  3.5 依赖,主要是第一条依赖,版本一定要配成管理中心的版本;第二条依赖主要是下面使用源码添加任务的时候用,不需要就不要加了

<!--xxl-->

<dependency>

    <groupId>com.xuxueli</groupId>

    <artifactId>xxl-job-core</artifactId>

    <version>2.2.0</version>

</dependency><br>     <!--源码CRUD任务-->

<dependency>

    <groupId>cn.hutool</groupId>

    <artifactId>hutool-all</artifactId>

    <version>5.5.4</version>

</dependency>

  3.6 打开页面,添加执行器,AppName就是上面提到的xxl-job-executor-test,名称自己随便写,选自动注册即可,自动注册会自动监听有哪些执行器正在执行,手动录入需要手动添加

  3.7 添加任务,这里的JobHandler就是@XxlJob的value

   3.8 启动客户端,就能看到你自己的执行器已经被记录了。

   3.9 任务里面执行一下,能跑断点就没问题了

 

 

   至此搭建环境完成,你可以用页面管理你的定时任务了,如果你还需要用源码管理任务,请继续看下面

四、用源码对任务进行CRUD操作

  4.1 查看源码,打开管理中心项目的xxl-job\xxl-job-admin\src\main\java\com\xxl\job\admin\controller\JobInfoController.java,这里就是对任务的管理,调用这些接口就能实现功能

   4.2 考虑到比较懒,附上一个工具类。maven依赖上面提过了,XxlJobInfo这个类去管理中心项目找

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.greatchn.ssfwpt.common.bean.XxlJobInfo;
import com.greatchn.ssfwpt.common.tools.map.MapTools;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.HttpCookie;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ------参数格式
 * XxlJobInfo xxlJobInfo = new XxlJobInfo();
 * xxlJobInfo.setId(3);//插入时不需要
 * xxlJobInfo.setJobGroup(1);
 * xxlJobInfo.setJobDesc("测试任务");
 * xxlJobInfo.setExecutorRouteStrategy("FIRST");
 * xxlJobInfo.setJobCron("0/6 * * * * ?");
 * xxlJobInfo.setGlueType("BEAN");
 * xxlJobInfo.setExecutorHandler("demoJobHandler");
 * xxlJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
 * xxlJobInfo.setExecutorTimeout(0);
 * xxlJobInfo.setExecutorFailRetryCount(0);
 * xxlJobInfo.setAuthor("XXL");
 * xxlJobInfo.setTriggerStatus(1);
 */
@Component
public class XxlTools {

    @Value("${xxl.job.admin.addresses}")
    private String adminAddresses;

    /**
     * 添加任务
     *
     * @param xxlJobInfo
     * @return 任务序号(-1失败,1,2,3... 成功)
     */
    public int addXxlJob(XxlJobInfo xxlJobInfo) {
        HttpResponse response = getResponse(xxlJobInfo, "add");
        return response.getStatus() == 200 ? JSON.parseObject(response.body()).getIntValue("content") : -1;
    }

    /**
     * 更新任务
     *
     * @param xxlJobInfo
     * @return true成功,false失败
     */
    public boolean updateXxlJob(XxlJobInfo xxlJobInfo) {
        HttpResponse response = getResponse(xxlJobInfo, "update");
        return response.getStatus() == 200 ? true : false;
    }

    /**
     * 删除任务
     *
     * @param xxlJobInfo
     * @return
     */
    public boolean removeXxlJob(XxlJobInfo xxlJobInfo) {
        HttpResponse response = getResponse(xxlJobInfo, "remove");
        return response.getStatus() == 200 ? true : false;
    }

    /**
     * 停止任务
     *
     * @param xxlJobInfo
     * @return
     */
    public boolean stopXxlJob(XxlJobInfo xxlJobInfo) {
        HttpResponse response = getResponse(xxlJobInfo, "stop");
        return response.getStatus() == 200 ? true : false;
    }

    /**
     * 启动任务
     *
     * @param xxlJobInfo
     * @return
     */
    public boolean startXxlJob(XxlJobInfo xxlJobInfo) {
        HttpResponse response = getResponse(xxlJobInfo, "start");
        return response.getStatus() == 200 ? true : false;
    }

    /**
     * 获取登录cookie
     *
     * @return
     */
    public String getCookie() {
        String path = adminAddresses + "/login";
        Map<String, Object> hashMap = new HashMap();
        hashMap.put("userName", "admin");
        hashMap.put("password", "123456");
        HttpResponse response = HttpRequest.post(path).form(hashMap).execute();
        List<HttpCookie> cookies = response.getCookies();
        StringBuilder sb = new StringBuilder();
        for (HttpCookie cookie : cookies) {
            sb.append(cookie.toString());
        }
        String cookie = sb.toString();
        return cookie;
    }

    /**
     * 调用xxl-job项目获取返回结果
     *
     * @param xxlJobInfo
     * @param method
     * @return
     */
    public HttpResponse getResponse(XxlJobInfo xxlJobInfo, String method) {
        String path = adminAddresses + "/jobinfo/" + method;
        Map<String, Object> paramMap = MapTools.entityToMap(xxlJobInfo);

        getCookie();

        return HttpRequest.post(path).form(paramMap).execute();
    }

    /**
     * 获取固定时间的Cron表达式
     *
     * @param time
     * @return cron表达式
     */
    public String getOnTimeCron(String time) {
        try {
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(time);
            String[] times = time.split(" ");
            String[] yMd = times[0].split("-");
            String[] Hms = times[1].split(":");
            String year = yMd[0];
            String month = StringUtils.startsWith(yMd[1], "0") ? StringUtils.substring(yMd[1], 1) : yMd[1];
            String day = StringUtils.startsWith(yMd[2], "0") ? StringUtils.substring(yMd[2], 1) : yMd[2];
            String hour = StringUtils.startsWith(Hms[0], "0") ? StringUtils.substring(Hms[0], 1) : Hms[0];
            String minute = StringUtils.startsWith(Hms[1], "0") ? StringUtils.substring(Hms[1], 1) : Hms[1];
            String second = StringUtils.startsWith(Hms[2], "0") ? StringUtils.substring(Hms[2], 1) : Hms[2];
            StringBuffer stringBuffer = new StringBuffer();
            stringBuffer.append(second);
            stringBuffer.append(" ");
            stringBuffer.append(minute);
            stringBuffer.append(" ");
            stringBuffer.append(hour);
            stringBuffer.append(" ");
            stringBuffer.append(day);
            stringBuffer.append(" ");
            stringBuffer.append(month);
            stringBuffer.append(" ? ");
            stringBuffer.append(year);
            return stringBuffer.toString();
        } catch (Exception e) {
            return null;
        }
    }

}

 五、附上一些测试结果

  5.1 执行器appname一样,就是说一个任务多个执行器的情况,该任务执行时,只会在其中一个执行器执行(类似于MQ的点对点),并且如果此执行器不停止,会一直在此执行器执行。不是随机的选一个执行器执行的

  5.2 一个任务多个执行器,如果一直在执行此任务的执行器关闭,会选择其他执行器执行

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 创建SpringBoot项目 首先,在IDE中创建一个SpringBoot项目,选择Maven作为构建工具,并在pom文件中添加SpringBoot和mybatis-plus的依赖。 2. 配置数据库连接 在application.properties文件中添加数据库连接信息,包括url、username、password等。 ``` spring.datasource.url=jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver ``` 3. 创建实体类和mapper 创建实体类和对应的mapper接口,使用mybatis-plus的注解来简化SQL操作。例如: ```java @Data @TableName("user") // 表名 public class User { @TableId(value = "id", type = IdType.AUTO) // id字段自增 private Long id; @TableField("name") // name字段 private String name; @TableField("age") // age字段 private Integer age; } ``` ```java public interface UserMapper extends BaseMapper<User> { } ``` 4. 编写业务逻辑 根据具体需求编写业务逻辑代码,例如实现对用户的增删改查操作。使用mybatis-plus的CRUD方法来简化操作。 ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public boolean saveUser(User user) { return userMapper.insert(user) > 0; } @Override public boolean updateUser(User user) { return userMapper.updateById(user) > 0; } @Override public boolean deleteUser(Long id) { return userMapper.deleteById(id) > 0; } @Override public User getUserById(Long id) { return userMapper.selectById(id); } @Override public List<User> getUserList() { return userMapper.selectList(null); } } ``` 5. 编写Controller层 编写Controller层代码,处理HTTP请求并调用对应的业务逻辑方法。使用@RestController注解来标注该类是一个REST风格的控制器。 ```java @RestController public class UserController { @Autowired private UserService userService; @PostMapping("/user") public Result saveUser(@RequestBody User user) { boolean result = userService.saveUser(user); return result ? Result.success() : Result.error("保存用户失败"); } @PutMapping("/user") public Result updateUser(@RequestBody User user) { boolean result = userService.updateUser(user); return result ? Result.success() : Result.error("更新用户失败"); } @DeleteMapping("/user/{id}") public Result deleteUser(@PathVariable Long id) { boolean result = userService.deleteUser(id); return result ? Result.success() : Result.error("删除用户失败"); } @GetMapping("/user/{id}") public Result getUserById(@PathVariable Long id) { User user = userService.getUserById(id); return Result.success(user); } @GetMapping("/user") public Result getUserList() { List<User> userList = userService.getUserList(); return Result.success(userList); } } ``` 6. 测试接口 启动SpringBoot应用程序,使用Postman等工具测试接口,确认接口功能正常。 以上便是搭建SpringBoot mybatis-plus项目的基本流程。通过使用mybatis-plus来简化SQL操作,可以极大的提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值