mirror of
https://github.com/PowerJob/PowerJob.git
synced 2025-07-17 00:00:04 +08:00
provide fully support for snowflake
This commit is contained in:
parent
07d63df4d7
commit
19ffe6d052
@ -0,0 +1,38 @@
|
|||||||
|
package com.github.kfcfans.oms.server.persistence.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import javax.persistence.*;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器信息表(用于分配服务器唯一ID)
|
||||||
|
*
|
||||||
|
* @author tjq
|
||||||
|
* @since 2020/4/15
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Entity
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Table(name = "server_info", uniqueConstraints = {@UniqueConstraint(columnNames = "ip")})
|
||||||
|
public class ServerInfoDO {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器IP地址
|
||||||
|
*/
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
private Date gmtCreate;
|
||||||
|
private Date gmtModified;
|
||||||
|
|
||||||
|
public ServerInfoDO(String ip) {
|
||||||
|
this.ip = ip;
|
||||||
|
this.gmtCreate = new Date();
|
||||||
|
this.gmtModified = this.gmtCreate;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package com.github.kfcfans.oms.server.persistence.repository;
|
||||||
|
|
||||||
|
import com.github.kfcfans.oms.server.persistence.model.ServerInfoDO;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 服务器信息 数据操作层
|
||||||
|
*
|
||||||
|
* @author tjq
|
||||||
|
* @since 2020/4/15
|
||||||
|
*/
|
||||||
|
public interface ServerInfoRepository extends JpaRepository<ServerInfoDO, Long> {
|
||||||
|
ServerInfoDO findByIp(String ip);
|
||||||
|
}
|
@ -1,16 +0,0 @@
|
|||||||
package com.github.kfcfans.oms.server.service;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 唯一ID生成服务
|
|
||||||
*
|
|
||||||
* @author tjq
|
|
||||||
* @since 2020/4/6
|
|
||||||
*/
|
|
||||||
public class IdGenerateService {
|
|
||||||
|
|
||||||
public static Long allocate() {
|
|
||||||
// TODO:换成合适的分布式ID生成算法
|
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,53 @@
|
|||||||
|
package com.github.kfcfans.oms.server.service.id;
|
||||||
|
|
||||||
|
import com.github.kfcfans.common.utils.NetUtils;
|
||||||
|
import com.github.kfcfans.oms.server.persistence.model.ServerInfoDO;
|
||||||
|
import com.github.kfcfans.oms.server.persistence.repository.ServerInfoRepository;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 唯一ID生成服务,使用 Twitter snowflake 算法
|
||||||
|
* 机房ID:固定为0,占用三位(8个机房怎么样也够了吧)
|
||||||
|
* 机器ID:数据库自增,占用7位(最多支持128台机器)
|
||||||
|
*
|
||||||
|
* @author tjq
|
||||||
|
* @since 2020/4/6
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
public class IdGenerateService {
|
||||||
|
|
||||||
|
private SnowFlakeIdGenerator snowFlakeIdGenerator;
|
||||||
|
|
||||||
|
private static final int DATA_CENTER_ID = 0;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public IdGenerateService(ServerInfoRepository serverInfoRepository) {
|
||||||
|
|
||||||
|
String ip = NetUtils.getLocalHost();
|
||||||
|
ServerInfoDO server = serverInfoRepository.findByIp(ip);
|
||||||
|
|
||||||
|
if (server == null) {
|
||||||
|
ServerInfoDO newServerInfo = new ServerInfoDO(ip);
|
||||||
|
server = serverInfoRepository.saveAndFlush(newServerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
Long id = server.getId();
|
||||||
|
snowFlakeIdGenerator = new SnowFlakeIdGenerator(DATA_CENTER_ID, id);
|
||||||
|
|
||||||
|
log.info("[IdGenerateService] init snowflake for server(address={}) by machineId({}).", ip, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分配分布式唯一ID
|
||||||
|
* @return 分布式唯一ID
|
||||||
|
*/
|
||||||
|
public long allocate() {
|
||||||
|
return snowFlakeIdGenerator.nextId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package com.github.kfcfans.oms.server.common.utils.snowflake;
|
package com.github.kfcfans.oms.server.service.id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Twitter SnowFlake(Scala -> Java)
|
* Twitter SnowFlake(Scala -> Java)
|
||||||
@ -6,19 +6,19 @@ package com.github.kfcfans.oms.server.common.utils.snowflake;
|
|||||||
* @author tjq
|
* @author tjq
|
||||||
* @since 2020/4/6
|
* @since 2020/4/6
|
||||||
*/
|
*/
|
||||||
public class SnowFlakeIdGenerator {
|
class SnowFlakeIdGenerator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 起始的时间戳
|
* 起始的时间戳(a special day for me)
|
||||||
*/
|
*/
|
||||||
private final static long START_STAMP = 1480166465631L;
|
private final static long START_STAMP = 1555776000000L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 每一部分占用的位数
|
* 每一部分占用的位数
|
||||||
*/
|
*/
|
||||||
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
|
private final static long SEQUENCE_BIT = 12; //序列号占用的位数
|
||||||
private final static long MACHINE_BIT = 5; //机器标识占用的位数
|
private final static long MACHINE_BIT = 7; //机器标识占用的位数
|
||||||
private final static long DATA_CENTER_BIT = 5;//数据中心占用的位数
|
private final static long DATA_CENTER_BIT = 3;//数据中心占用的位数
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 每一部分的最大值
|
* 每一部分的最大值
|
||||||
@ -56,7 +56,7 @@ public class SnowFlakeIdGenerator {
|
|||||||
public synchronized long nextId() {
|
public synchronized long nextId() {
|
||||||
long currStamp = getNewStamp();
|
long currStamp = getNewStamp();
|
||||||
if (currStamp < lastTimestamp) {
|
if (currStamp < lastTimestamp) {
|
||||||
throw new RuntimeException("Clock moved backwards. Refusing to generate id");
|
throw new RuntimeException("clock moved backwards, refusing to generate id");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currStamp == lastTimestamp) {
|
if (currStamp == lastTimestamp) {
|
@ -13,7 +13,7 @@ import com.github.kfcfans.oms.server.persistence.repository.AppInfoRepository;
|
|||||||
import com.github.kfcfans.oms.server.persistence.repository.JobInfoRepository;
|
import com.github.kfcfans.oms.server.persistence.repository.JobInfoRepository;
|
||||||
import com.github.kfcfans.oms.server.persistence.repository.InstanceLogRepository;
|
import com.github.kfcfans.oms.server.persistence.repository.InstanceLogRepository;
|
||||||
import com.github.kfcfans.oms.server.service.DispatchService;
|
import com.github.kfcfans.oms.server.service.DispatchService;
|
||||||
import com.github.kfcfans.oms.server.service.IdGenerateService;
|
import com.github.kfcfans.oms.server.service.id.IdGenerateService;
|
||||||
import com.github.kfcfans.oms.server.service.ha.WorkerManagerService;
|
import com.github.kfcfans.oms.server.service.ha.WorkerManagerService;
|
||||||
import com.google.common.base.Stopwatch;
|
import com.google.common.base.Stopwatch;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@ -46,7 +46,8 @@ public class JobScheduleService {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private DispatchService dispatchService;
|
private DispatchService dispatchService;
|
||||||
|
@Resource
|
||||||
|
private IdGenerateService idGenerateService;
|
||||||
@Resource
|
@Resource
|
||||||
private AppInfoRepository appInfoRepository;
|
private AppInfoRepository appInfoRepository;
|
||||||
@Resource
|
@Resource
|
||||||
@ -109,7 +110,7 @@ public class JobScheduleService {
|
|||||||
InstanceLogDO executeLog = new InstanceLogDO();
|
InstanceLogDO executeLog = new InstanceLogDO();
|
||||||
executeLog.setJobId(jobInfoDO.getId());
|
executeLog.setJobId(jobInfoDO.getId());
|
||||||
executeLog.setAppId(jobInfoDO.getAppId());
|
executeLog.setAppId(jobInfoDO.getAppId());
|
||||||
executeLog.setInstanceId(IdGenerateService.allocate());
|
executeLog.setInstanceId(idGenerateService.allocate());
|
||||||
executeLog.setStatus(InstanceStatus.WAITING_DISPATCH.getV());
|
executeLog.setStatus(InstanceStatus.WAITING_DISPATCH.getV());
|
||||||
executeLog.setExpectedTriggerTime(jobInfoDO.getNextTriggerTime());
|
executeLog.setExpectedTriggerTime(jobInfoDO.getNextTriggerTime());
|
||||||
executeLog.setGmtCreate(new Date());
|
executeLog.setGmtCreate(new Date());
|
||||||
|
@ -13,7 +13,7 @@ import com.github.kfcfans.oms.server.persistence.repository.JobInfoRepository;
|
|||||||
import com.github.kfcfans.common.response.ResultDTO;
|
import com.github.kfcfans.common.response.ResultDTO;
|
||||||
import com.github.kfcfans.oms.server.persistence.model.JobInfoDO;
|
import com.github.kfcfans.oms.server.persistence.model.JobInfoDO;
|
||||||
import com.github.kfcfans.oms.server.service.DispatchService;
|
import com.github.kfcfans.oms.server.service.DispatchService;
|
||||||
import com.github.kfcfans.oms.server.service.IdGenerateService;
|
import com.github.kfcfans.oms.server.service.id.IdGenerateService;
|
||||||
import com.github.kfcfans.oms.server.service.instance.InstanceService;
|
import com.github.kfcfans.oms.server.service.instance.InstanceService;
|
||||||
import com.github.kfcfans.oms.server.web.request.ModifyJobInfoRequest;
|
import com.github.kfcfans.oms.server.web.request.ModifyJobInfoRequest;
|
||||||
import com.github.kfcfans.oms.server.web.request.QueryJobInfoRequest;
|
import com.github.kfcfans.oms.server.web.request.QueryJobInfoRequest;
|
||||||
@ -48,6 +48,8 @@ public class JobController {
|
|||||||
@Resource
|
@Resource
|
||||||
private DispatchService dispatchService;
|
private DispatchService dispatchService;
|
||||||
@Resource
|
@Resource
|
||||||
|
private IdGenerateService idGenerateService;
|
||||||
|
@Resource
|
||||||
private InstanceService instanceService;
|
private InstanceService instanceService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@ -163,7 +165,7 @@ public class JobController {
|
|||||||
InstanceLogDO executeLog = new InstanceLogDO();
|
InstanceLogDO executeLog = new InstanceLogDO();
|
||||||
executeLog.setJobId(jobInfoDO.getId());
|
executeLog.setJobId(jobInfoDO.getId());
|
||||||
executeLog.setAppId(jobInfoDO.getAppId());
|
executeLog.setAppId(jobInfoDO.getAppId());
|
||||||
executeLog.setInstanceId(IdGenerateService.allocate());
|
executeLog.setInstanceId(idGenerateService.allocate());
|
||||||
executeLog.setStatus(InstanceStatus.WAITING_DISPATCH.getV());
|
executeLog.setStatus(InstanceStatus.WAITING_DISPATCH.getV());
|
||||||
executeLog.setExpectedTriggerTime(System.currentTimeMillis());
|
executeLog.setExpectedTriggerTime(System.currentTimeMillis());
|
||||||
executeLog.setGmtCreate(new Date());
|
executeLog.setGmtCreate(new Date());
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.github.kfcfans.oms.server.test;
|
package com.github.kfcfans.oms.server.test;
|
||||||
|
|
||||||
|
import com.github.kfcfans.oms.server.service.id.IdGenerateService;
|
||||||
import com.github.kfcfans.oms.server.service.lock.LockService;
|
import com.github.kfcfans.oms.server.service.lock.LockService;
|
||||||
import org.assertj.core.util.Lists;
|
import org.assertj.core.util.Lists;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -22,6 +23,8 @@ public class ServiceTest {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private LockService lockService;
|
private LockService lockService;
|
||||||
|
@Resource
|
||||||
|
private IdGenerateService idGenerateService;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLockService() {
|
public void testLockService() {
|
||||||
@ -45,4 +48,9 @@ public class ServiceTest {
|
|||||||
lockService.batchUnLock(lockNames);
|
lockService.batchUnLock(lockNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIdGenerator() {
|
||||||
|
System.out.println(idGenerateService.allocate());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -71,4 +71,10 @@ public class UtilsTest {
|
|||||||
System.out.println(nextValidTimeAfter);
|
System.out.println(nextValidTimeAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void normalTest() {
|
||||||
|
String s = "000000000111010000001100000000010110100110100000000001000000000000";
|
||||||
|
System.out.println(s.length());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<!-- ConsoleAppender:把日志输出到控制台 -->
|
<!-- ConsoleAppender:把日志输出到控制台 -->
|
||||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
<encoder>
|
<encoder>
|
||||||
<pattern>222222%d [%t] %-5level %logger{36}.%M\(%file:%line\) - %msg%n</pattern>
|
<pattern>%d [%t] %-5level %logger{36}.%M\(%file:%line\) - %msg%n</pattern>
|
||||||
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
|
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
|
||||||
<charset>UTF-8</charset>
|
<charset>UTF-8</charset>
|
||||||
</encoder>
|
</encoder>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user