Merge pull request #863 from souvc/master

添加Jboot框架使用xxl-job的应用示例
pull/10/head
许雪里 6 years ago committed by GitHub
commit ca154f6ea5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -16,6 +16,7 @@
<module>xxl-job-executor-sample-jfinal</module>
<module>xxl-job-executor-sample-nutz</module>
<module>xxl-job-executor-sample-frameless</module>
<module>xxl-job-executor-sample-jboot</module>
</modules>
</project>

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>xxl-job-executor-samples</artifactId>
<groupId>com.xuxueli</groupId>
<version>2.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>xxl-job-executor-sample-jboot</artifactId>
<name>${project.artifactId}</name>
<description>Example executor project for spring boot.</description>
<url>http://www.xuxueli.com/</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.jboot</groupId>
<artifactId>jboot</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.11</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/webapp</directory>
<includes>
<include>**/</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<assembleDirectory>${project.build.directory}/app</assembleDirectory>
<repositoryName>lib</repositoryName>
<binFolder>bin</binFolder>
<configurationDirectory>webRoot</configurationDirectory>
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<configurationSourceDirectory>src/main/resources</configurationSourceDirectory>
<repositoryLayout>flat</repositoryLayout>
<encoding>UTF-8</encoding>
<logsDirectory>logs</logsDirectory>
<tempDirectory>tmp</tempDirectory>
<programs>
<program>
<mainClass>io.jboot.Jboot</mainClass>
<id>jboot</id>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,14 @@
package com.xuxueli;
import io.jboot.app.JbootApplication;
/**
* Jboot app
*
* @author https://github.com/souvc
*/
public class JbootApp {
public static void main(String[] args) {
JbootApplication.run(args);
}
}

@ -0,0 +1,68 @@
package com.xuxueli.executor.sample.jboot.config;
import com.xuxueli.executor.sample.jboot.jobhandler.CommandJobHandler;
import com.xuxueli.executor.sample.jboot.jobhandler.DemoJobHandler;
import com.xuxueli.executor.sample.jboot.jobhandler.HttpJobHandler;
import com.xuxueli.executor.sample.jboot.jobhandler.ShardingJobHandler;
import com.xxl.job.core.executor.XxlJobExecutor;
import io.jboot.Jboot;
import io.jboot.core.listener.JbootAppListenerBase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author https://github.com/souvc
*/
public class JbootConfig extends JbootAppListenerBase {
private Logger logger = LoggerFactory.getLogger(JbootConfig.class);
// ---------------------- xxl-job executor ----------------------
private XxlJobExecutor xxlJobExecutor = null;
private void initXxlJobExecutor() {
// registry jobhandler
XxlJobExecutor.registJobHandler("demoJobHandler", new DemoJobHandler());
XxlJobExecutor.registJobHandler("shardingJobHandler", new ShardingJobHandler());
XxlJobExecutor.registJobHandler("httpJobHandler", new HttpJobHandler());
XxlJobExecutor.registJobHandler("commandJobHandler", new CommandJobHandler());
// init executor
xxlJobExecutor = new XxlJobExecutor();
xxlJobExecutor.setAdminAddresses(Jboot.configValue("xxl.job.admin.addresses"));
xxlJobExecutor.setAppName(Jboot.configValue("xxl.job.executor.appname"));
xxlJobExecutor.setIp(Jboot.configValue("xxl.job.executor.ip"));
xxlJobExecutor.setPort(Integer.valueOf(Jboot.configValue("xxl.job.executor.port")));
xxlJobExecutor.setAccessToken(Jboot.configValue("xxl.job.accessToken"));
xxlJobExecutor.setLogPath(Jboot.configValue("xxl.job.executor.logpath"));
xxlJobExecutor.setLogRetentionDays(Integer.valueOf(Jboot.configValue("xxl.job.executor.logretentiondays")));
// start executor
try {
xxlJobExecutor.start();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
// ---------------------- jboot ----------------------
private void destoryXxlJobExecutor() {
if (xxlJobExecutor != null) {
xxlJobExecutor.destroy();
}
}
@Override
public void onStart() {
initXxlJobExecutor();
super.onStart();
}
@Override
public void onStop() {
destoryXxlJobExecutor();
super.onStop();
}
}

@ -0,0 +1,15 @@
package com.xuxueli.executor.sample.jboot.controller;
import io.jboot.web.controller.JbootController;
import io.jboot.web.controller.annotation.RequestMapping;
/**
* @author https://github.com/souvc
*/
@RequestMapping("/")
public class IndexController extends JbootController {
public void index() {
renderText("xxl job executor running.");
}
}

@ -0,0 +1,54 @@
package com.xuxueli.executor.sample.jboot.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
*
*
* @author xuxueli 2018-09-16 03:48:34
*/
public class CommandJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
String command = param;
int exitValue = -1;
BufferedReader bufferedReader = null;
try {
// command process
Process process = Runtime.getRuntime().exec(command);
BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
// command log
String line;
while ((line = bufferedReader.readLine()) != null) {
XxlJobLogger.log(line);
}
// command exit
process.waitFor();
exitValue = process.exitValue();
} catch (Exception e) {
XxlJobLogger.log(e);
} finally {
if (bufferedReader != null) {
bufferedReader.close();
}
}
if (exitValue == 0) {
return IJobHandler.SUCCESS;
} else {
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
}
}
}

@ -0,0 +1,32 @@
package com.xuxueli.executor.sample.jboot.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import java.util.concurrent.TimeUnit;
/**
* HandlerBean
*
*
* 1"IJobHandler"com.xxl.job.core.handler.IJobHandler
* 2 "JFinalCoreConfig.initXxlJobExecutor" keyJobHandler
* 3 "XxlJobLogger.log"
*
* @author xuxueli 2015-12-19 19:43:36
*/
public class DemoJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(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 SUCCESS;
}
}

@ -0,0 +1,81 @@
package com.xuxueli.executor.sample.jboot.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* Http
*
* @author xuxueli 2018-09-16 03:48:34
*/
public class HttpJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
// request
HttpURLConnection connection = null;
BufferedReader bufferedReader = null;
try {
// connection
URL realUrl = new URL(param);
connection = (HttpURLConnection) realUrl.openConnection();
// connection setting
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setReadTimeout(5 * 1000);
connection.setConnectTimeout(3 * 1000);
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
// do connection
connection.connect();
//Map<String, List<String>> map = connection.getHeaderFields();
// valid StatusCode
int statusCode = connection.getResponseCode();
if (statusCode != 200) {
throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
}
// result
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder result = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
result.append(line);
}
String responseMsg = result.toString();
XxlJobLogger.log(responseMsg);
return SUCCESS;
} catch (Exception e) {
XxlJobLogger.log(e);
return FAIL;
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
if (connection != null) {
connection.disconnect();
}
} catch (Exception e2) {
XxlJobLogger.log(e2);
}
}
}
}

@ -0,0 +1,34 @@
package com.xuxueli.executor.sample.jboot.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.log.XxlJobLogger;
import com.xxl.job.core.util.ShardingUtil;
/**
* 广
*
* @author xuxueli 2017-07-25 20:56:50
*/
public class ShardingJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
// 分片参数
ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardingVO.getIndex(), shardingVO.getTotal());
// 业务逻辑
for (int i = 0; i < shardingVO.getTotal(); i++) {
if (i == shardingVO.getIndex()) {
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
} else {
XxlJobLogger.log("第 {} 片, 忽略", i);
}
}
return SUCCESS;
}
}

@ -0,0 +1,19 @@
#jboot Æô¶¯¶Ë¿Ú
undertow.port=8082
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### xxl-job executor address
xxl.job.executor.appname=xxl-job-executor-sample
xxl.job.executor.ip=
xxl.job.executor.port=9994
### xxl-job, access token
xxl.job.accessToken=
### xxl-job log path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job log retention days
xxl.job.executor.logretentiondays=-1

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 级别从高到低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
<!-- 日志输出规则 根据当前ROOT 级别日志输出时级别高于root默认的级别时 会输出 -->
<!-- 以下 每个配置的 filter 是过滤掉输出文件里面会出现高级别文件依然出现低级别的日志信息通过filter 过滤只记录本级别的日志 -->
<!-- scan 当此属性设置为true时配置文件如果发生改变将会被重新加载默认值为true。 -->
<!-- scanPeriod 设置监测配置文件是否有修改的时间间隔如果没有给出时间单位默认单位是毫秒。当scan为true时此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug 当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。 -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 动态日志级别 -->
<jmxConfigurator/>
<!-- 定义日志文件 输出位置 -->
<property name="log_dir" value="logs"/>
<!-- 日志最大的历史 30天 -->
<property name="maxHistory" value="30"/>
<!-- ConsoleAppender 控制台输出日志 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
<!-- 设置日志输出格式 -->
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
<!-- ERROR级别日志 -->
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender -->
<appender name="ERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器只记录WARN级别的日志 -->
<!-- 果日志级别等于配置级别过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>ERROR</level>
<!-- 用于配置符合过滤条件的操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 用于配置不符合过滤条件的操作 -->
<onMismatch>DENY</onMismatch>
</filter>
<!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>
${log_dir}/error/%d{yyyy-MM-dd}/logs.log
</fileNamePattern>
<!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6 则只保存最近6个月的文件删除之前的旧文件。注意删除旧文件是那些为了归档而创建的目录也会被删除 -->
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
<!-- 设置日志输出格式 -->
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
<!-- WARN级别日志 appender -->
<appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 过滤器只记录WARN级别的日志 -->
<!-- 果日志级别等于配置级别过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 设置过滤级别 -->
<level>WARN</level>
<!-- 用于配置符合过滤条件的操作 -->
<onMatch>ACCEPT</onMatch>
<!-- 用于配置不符合过滤条件的操作 -->
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志输出位置 可相对、和绝对路径 -->
<fileNamePattern>${log_dir}/warn/%d{yyyy-MM-dd}/logs.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- INFO级别日志 appender -->
<appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/info/%d{yyyy-MM-dd}/logs.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- DEBUG级别日志 appender -->
<appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/debug/%d{yyyy-MM-dd}/logs.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- TRACE级别日志 appender -->
<appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log_dir}/trace/%d{yyyy-MM-dd}/logs.log</fileNamePattern>
<maxHistory>${maxHistory}</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<!-- root级别 DEBUG -->
<root>
<!-- 打印debug级别日志及以上级别日志 -->
<level value="info"/>
<!-- 控制台输出 -->
<appender-ref ref="console"/>
<!-- 文件输出 -->
<!--<appender-ref ref="ERROR"/>-->
<!--<appender-ref ref="INFO"/>-->
<!--<appender-ref ref="WARN"/>-->
<!--<appender-ref ref="DEBUG"/>-->
<!--<appender-ref ref="TRACE"/>-->
</root>
</configuration>

@ -0,0 +1,20 @@
package com.xuxueli;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
* Unit test for simple App.
*/
public class AppTest
{
/**
* Rigorous Test :-)
*/
@Test
public void shouldAnswerWithTrue()
{
assertTrue( true );
}
}
Loading…
Cancel
Save