Pre Merge pull request !24 from FanX/2.3.0

pull/24/MERGE
FanX 4 years ago committed by Gitee
commit ba0846961b

@ -13,6 +13,7 @@
<modules>
<module>xxl-job-core</module>
<module>xxl-job-admin</module>
<module>xxl-job-spring-boot-starter</module>
<module>xxl-job-executor-samples</module>
</modules>

@ -43,10 +43,10 @@
<scope>test</scope>
</dependency>
<!-- xxl-job-core -->
<!-- xxl-job-spring-boot-starter -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<artifactId>xxl-job-spring-boot-starter</artifactId>
<version>${project.parent.version}</version>
</dependency>

@ -1,78 +0,0 @@
package com.xxl.job.executor.core.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* "spring-cloud-commons" "InetUtils" IP
*
* 1
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}

@ -1,26 +1,9 @@
# web port
server.port=8081
# no web
#spring.main.web-environment=false
# log config
logging.config=classpath:logback.xml
spring.application.name=demo-app
### 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.admin.addresses=http://127.0.0.1:8080/xxl-job-admin,http://192.168.50.11:8080/xxl-job-admin
xxl-job.executor.preferred-networks=192.168.50
### xxl-job, access token
xxl.job.accessToken=
### xxl-job executor appname
xxl.job.executor.appname=xxl-job-executor-sample
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
xxl.job.executor.address=
### xxl-job executor server-info
xxl.job.executor.ip=
xxl.job.executor.port=9999
### xxl-job executor log-path
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### xxl-job executor log-retention-days
xxl.job.executor.logretentiondays=30

@ -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…
Cancel
Save