Pre Merge pull request !24 from FanX/2.3.0
commit
ba0846961b
@ -0,0 +1,57 @@
|
||||
|
||||
# 使用方式
|
||||
## 1. 添加依赖
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job-spring-boot-starter</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
## 2. 配置 application.yml
|
||||
遵循约定优于配置的原则, 提供更多的默认配置
|
||||
最低配置仅需提供 admin.address 即可
|
||||
```yaml
|
||||
spring:
|
||||
application:
|
||||
name: demo-app
|
||||
|
||||
xxl-job:
|
||||
admin:
|
||||
addresses: http://localhost:7878 # 必填
|
||||
access-token: abcdefghijklmn # 可选, 若 amin 配有 accessToken, 则需要填写
|
||||
executor:
|
||||
enable: true # 是否启用, 默认: true
|
||||
app-name: demo-app # 可选, 为空则取值 ${spring.application.name}
|
||||
port-min: 30000 # 可选, 默认: 30000
|
||||
port-max: 40000 # 可选, 默认: 49151
|
||||
ip: 192.168.3.5 # 可选, 为空则按 preferred-networks 匹配
|
||||
preferred-networks: # 可选, 当 ip 为空时, 将遍历网卡的 ip 与此值进行 startWith 匹配
|
||||
- 192.168.50
|
||||
```
|
||||
### 关于 ip 相关配置
|
||||
若已经配置 ip, 则以配置为准
|
||||
若 ip 留空, 则按 preferred-networks 进行匹配
|
||||
若 ip 与 preferred-networks 均未提供, 则按 xxl-job-core 的 IpUtil 获取
|
||||
|
||||
警告:
|
||||
多网卡环境, 采用 IpUtil 获取本机 ip 进行注册, 可能存在问题.
|
||||
比如, admin 与 job 不在同一台机器, 此时使用 job 获取的本机 ip 注册到 admin, 但 admin 可能无法访问此 ip!!!
|
||||
|
||||
建议:
|
||||
手工指定本机 ip, 或者配置 preferred-networks, 以确保 admin 能正常访问此 ip
|
||||
|
||||
|
||||
### 关于 port 相关配置
|
||||
port-max 和 port-min 分别指端口的最大值和最小值
|
||||
启动时, 会在区间内自动查找可用端口.
|
||||
查找方法: 由最大值开始, 一直递减, 直到找到可用为止.
|
||||
若此区间内无可用端口, 则会抛出异常, 无法启动
|
||||
|
||||
通常情况下, 建议使用默认的区间值
|
||||
未提供特定端口的配置, 若希望固定端口, 请将 port-min 与 port-max 设为同一值
|
||||
|
||||
|
||||
## 3. 其他
|
||||
照常编写 @XxlJob 之类的任务方法即可
|
@ -0,0 +1,65 @@
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job</artifactId>
|
||||
<version>2.3.0</version>
|
||||
</parent>
|
||||
<artifactId>xxl-job-spring-boot-starter</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>xxl-job spring-boot starter</description>
|
||||
<url>https://www.xuxueli.com/</url>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.xuxueli</groupId>
|
||||
<artifactId>xxl-job-core</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- slf4j -->
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
</project>
|
@ -0,0 +1,31 @@
|
||||
package com.xxl.job.spring.config;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* admin config
|
||||
* @author fanhang
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "xxl-job.admin")
|
||||
public class XxlJobAdminProperties {
|
||||
private String addresses;
|
||||
private String accessToken;
|
||||
|
||||
public String getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public void setAddresses(String addresses) {
|
||||
this.addresses = addresses;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
package com.xxl.job.spring.config;
|
||||
|
||||
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
|
||||
import com.xxl.job.core.util.IpUtil;
|
||||
import com.xxl.job.core.util.NetUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.*;
|
||||
|
||||
/**
|
||||
* @author fanhang
|
||||
*/
|
||||
@Configuration
|
||||
public class XxlJobAutoConfiguration {
|
||||
private static final Logger log = LoggerFactory.getLogger(XxlJobAutoConfiguration.class);
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "xxl-job.executor.enable", havingValue = "true", matchIfMissing = true)
|
||||
public XxlJobSpringExecutor xxlJobSpringExecutor(XxlJobAdminProperties adminProps, XxlJobExecutorProperties executorProps) {
|
||||
log.info("xxl-job admin [{}] with properties: {}", adminProps.getAddresses(), executorProps);
|
||||
Assert.hasText(adminProps.getAddresses(), "require [xxl-job.admin.addresses]");
|
||||
Assert.hasText(executorProps.getAppName(), "require [xxl-job.executor.appName]");
|
||||
String ip = resolveIp(executorProps.getIp(), executorProps.getPreferredNetworks());
|
||||
Assert.hasLength(ip, "resolve ip failed");
|
||||
int port = resolvePort(executorProps.getPortMin(), executorProps.getPortMax());
|
||||
|
||||
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
|
||||
xxlJobSpringExecutor.setAdminAddresses(adminProps.getAddresses());
|
||||
if (StringUtils.hasLength(adminProps.getAccessToken())) {
|
||||
xxlJobSpringExecutor.setAccessToken(adminProps.getAccessToken());
|
||||
}
|
||||
xxlJobSpringExecutor.setAppname(executorProps.getAppName());
|
||||
xxlJobSpringExecutor.setPort(port);
|
||||
xxlJobSpringExecutor.setLogPath(executorProps.getLogPath());
|
||||
xxlJobSpringExecutor.setLogRetentionDays(executorProps.getLogRetentionDays());
|
||||
xxlJobSpringExecutor.setIp(ip);
|
||||
log.info("xxl-job-executor: (admin:{}, appName:{}, ip={}, port:{})", adminProps.getAddresses(), executorProps.getAppName(), ip, port);
|
||||
return xxlJobSpringExecutor;
|
||||
}
|
||||
|
||||
private String resolveIp(String ip, Set<String> preferredNetworks) {
|
||||
if (StringUtils.hasLength(ip)) {
|
||||
// 已设置 ip
|
||||
return ip;
|
||||
}
|
||||
// 未设置 ip
|
||||
if (!CollectionUtils.isEmpty(preferredNetworks)) {
|
||||
// 已配置 preferredNetworks
|
||||
ip = findNonLoopbackPreferredAddress(preferredNetworks);
|
||||
if (StringUtils.hasLength(ip)) {
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
// 始终都没有找到 ip, 则按 xxl-job-core 默认方式获取
|
||||
ip = IpUtil.getIp();
|
||||
log.warn("auto get address: {}", ip);
|
||||
return ip;
|
||||
}
|
||||
|
||||
private int resolvePort(int portMin, int portMax) {
|
||||
Assert.state(portMin <= portMax, String.format("invalid port range [%d, %d]", portMin, portMax));
|
||||
int port = NetUtil.findAvailablePort(portMax);
|
||||
Assert.state(port >= portMin, String.format("find available port [%d] out of bounds: [%d, %d]", port, portMin, portMax));
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* copy from spring-cloud-commons #InetUtils
|
||||
*
|
||||
* @param preferredNetworks
|
||||
* @return
|
||||
*/
|
||||
private String findNonLoopbackPreferredAddress(Set<String> preferredNetworks) {
|
||||
try {
|
||||
for (Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces(); nics.hasMoreElements(); ) {
|
||||
NetworkInterface ifc = nics.nextElement();
|
||||
if (ifc.isLoopback() || ifc.isVirtual() || !ifc.isUp()) {
|
||||
continue;
|
||||
}
|
||||
for (Enumeration<InetAddress> addrs = ifc.getInetAddresses(); addrs.hasMoreElements(); ) {
|
||||
InetAddress address = addrs.nextElement();
|
||||
if (address.isLoopbackAddress()) {
|
||||
continue;
|
||||
}
|
||||
for (String preferredNetwork : preferredNetworks) {
|
||||
if (address.getHostAddress().startsWith(preferredNetwork)) {
|
||||
log.debug("resolved preferred ip [{}] from [{} - {}]", address.getHostAddress(), ifc.getName(), ifc.getDisplayName());
|
||||
return address.getHostAddress();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
log.error("Cannot get non-loopback address", ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,150 @@
|
||||
package com.xxl.job.spring.config;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* executor config
|
||||
* @author fanhang
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "xxl-job.executor")
|
||||
public class XxlJobExecutorProperties implements EnvironmentAware, InitializingBean {
|
||||
private static final Logger log = LoggerFactory.getLogger(XxlJobExecutorProperties.class);
|
||||
private static final int PORT_MIN = 30000;
|
||||
private static final int PORT_MAX = 49151;
|
||||
|
||||
private Environment environment;
|
||||
|
||||
private boolean enable = true;
|
||||
/**
|
||||
* executor appName, default ${spring.application.name}
|
||||
*/
|
||||
private String appName;
|
||||
/**
|
||||
* executor ip
|
||||
*/
|
||||
private String ip;
|
||||
/**
|
||||
* logPath dir, default ${user.home}/logs/xxl-job/${spring.application.name}
|
||||
*/
|
||||
private String logPath;
|
||||
private int logRetentionDays = 30;
|
||||
/**
|
||||
* port range min
|
||||
*/
|
||||
private int portMin = PORT_MIN;
|
||||
/**
|
||||
* port range max
|
||||
*/
|
||||
private int portMax = PORT_MAX;
|
||||
private Set<String> preferredNetworks;
|
||||
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
public String getAppName() {
|
||||
return appName;
|
||||
}
|
||||
|
||||
public void setAppName(String appName) {
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
public void setIp(String ip) {
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
public String getLogPath() {
|
||||
return logPath;
|
||||
}
|
||||
|
||||
public void setLogPath(String logPath) {
|
||||
this.logPath = logPath;
|
||||
}
|
||||
|
||||
public int getLogRetentionDays() {
|
||||
return logRetentionDays;
|
||||
}
|
||||
|
||||
public void setLogRetentionDays(int logRetentionDays) {
|
||||
this.logRetentionDays = logRetentionDays;
|
||||
}
|
||||
|
||||
public int getPortMin() {
|
||||
return portMin;
|
||||
}
|
||||
|
||||
public void setPortMin(int portMin) {
|
||||
this.portMin = portMin;
|
||||
}
|
||||
|
||||
public int getPortMax() {
|
||||
return portMax;
|
||||
}
|
||||
|
||||
public void setPortMax(int portMax) {
|
||||
this.portMax = portMax;
|
||||
}
|
||||
|
||||
public Set<String> getPreferredNetworks() {
|
||||
return preferredNetworks;
|
||||
}
|
||||
|
||||
public void setPreferredNetworks(Set<String> preferredNetworks) {
|
||||
this.preferredNetworks = preferredNetworks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
if (!enable) {
|
||||
log.warn("xxl-job-executor DISABLE because [xxl-job.executor.enable] is false ");
|
||||
return;
|
||||
}
|
||||
if (!StringUtils.hasLength(appName)) {
|
||||
appName = environment.getProperty("spring.application.name");
|
||||
}
|
||||
if (!StringUtils.hasLength(logPath)) {
|
||||
String userHome = environment.getProperty("user.home");
|
||||
logPath = userHome + File.separator + "logs" + File.separator + "xxl-job" + File.separator + appName;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "XxlJobProperties{" +
|
||||
"enable=" + enable +
|
||||
", appName='" + appName + '\'' +
|
||||
", ip='" + ip + '\'' +
|
||||
", logPath='" + logPath + '\'' +
|
||||
", logRetentionDays=" + logRetentionDays +
|
||||
", portMin=" + portMin +
|
||||
", portMax=" + portMax +
|
||||
", preferredNetworks=" + preferredNetworks +
|
||||
'}';
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.xxl.job.spring.config.XxlJobAdminProperties,\
|
||||
com.xxl.job.spring.config.XxlJobExecutorProperties,\
|
||||
com.xxl.job.spring.config.XxlJobAutoConfiguration
|
@ -0,0 +1,13 @@
|
||||
package com.xxl.job.springtest;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Boot {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Boot.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
spring:
|
||||
application:
|
||||
name: demo-app
|
||||
|
||||
xxl-job:
|
||||
admin:
|
||||
addresses: http://localhost:8080/xxl-job-admin
|
||||
executor:
|
||||
preferred-networks:
|
||||
- 192.168.50
|
||||
|
||||
|
||||
logging:
|
||||
level:
|
||||
com.xxl.job: debug
|
Loading…
Reference in new issue