diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/Alarmable.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/extension/Alarmable.java similarity index 71% rename from powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/Alarmable.java rename to powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/extension/Alarmable.java index 715bfd7f..abab5b00 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/Alarmable.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/extension/Alarmable.java @@ -1,6 +1,8 @@ -package com.github.kfcfans.powerjob.server.service.alarm; +package com.github.kfcfans.powerjob.server.extension; import com.github.kfcfans.powerjob.server.persistence.core.model.UserInfoDO; +import com.github.kfcfans.powerjob.server.service.alarm.Alarm; +import com.github.kfcfans.powerjob.server.service.alarm.AlarmCenter; import org.springframework.beans.factory.InitializingBean; import java.util.List; diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/extension/ServerIdProvider.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/extension/ServerIdProvider.java new file mode 100644 index 00000000..62751040 --- /dev/null +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/extension/ServerIdProvider.java @@ -0,0 +1,14 @@ +package com.github.kfcfans.powerjob.server.extension; + +/** + * provide unique server ip in the cluster for IdGenerateService + * @author user + */ +public interface ServerIdProvider { + + /** + * get number for IdGenerateService + * @return serverId, must in range [0, 16384) + */ + long getServerId(); +} diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/ServerInfoRepository.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/ServerInfoRepository.java index 7f0b70ba..615933f2 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/ServerInfoRepository.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/persistence/core/repository/ServerInfoRepository.java @@ -2,11 +2,6 @@ package com.github.kfcfans.powerjob.server.persistence.core.repository; import com.github.kfcfans.powerjob.server.persistence.core.model.ServerInfoDO; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.data.jpa.repository.Lock; -import org.springframework.data.jpa.repository.Query; - -import javax.persistence.LockModeType; -import java.util.List; /** * 服务器信息 数据操作层 @@ -16,8 +11,4 @@ import java.util.List; */ public interface ServerInfoRepository extends JpaRepository { ServerInfoDO findByIp(String ip); - - @Query("select t from ServerInfoDO as t order by t.id asc") - @Lock(LockModeType.PESSIMISTIC_WRITE) - List findAllAndLockTable(); } diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/AlarmCenter.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/AlarmCenter.java index 06bd79b3..356931c6 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/AlarmCenter.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/AlarmCenter.java @@ -1,5 +1,6 @@ package com.github.kfcfans.powerjob.server.service.alarm; +import com.github.kfcfans.powerjob.server.extension.Alarmable; import com.github.kfcfans.powerjob.server.persistence.core.model.UserInfoDO; import com.google.common.collect.Lists; import com.google.common.collect.Queues; diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/DingTalkAlarmService.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/DingTalkAlarmService.java index f1e4ee48..2bcde0ed 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/DingTalkAlarmService.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/DingTalkAlarmService.java @@ -8,7 +8,7 @@ import com.github.kfcfans.powerjob.server.common.SJ; import com.github.kfcfans.powerjob.server.common.utils.DingTalkUtils; import com.github.kfcfans.powerjob.server.persistence.core.model.UserInfoDO; import com.github.kfcfans.powerjob.server.service.alarm.Alarm; -import com.github.kfcfans.powerjob.server.service.alarm.Alarmable; +import com.github.kfcfans.powerjob.server.extension.Alarmable; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.collect.Lists; diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/MailAlarmService.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/MailAlarmService.java index 516d1814..60010e1d 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/MailAlarmService.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/MailAlarmService.java @@ -2,7 +2,7 @@ package com.github.kfcfans.powerjob.server.service.alarm.impl; import com.github.kfcfans.powerjob.server.persistence.core.model.UserInfoDO; import com.github.kfcfans.powerjob.server.service.alarm.Alarm; -import com.github.kfcfans.powerjob.server.service.alarm.Alarmable; +import com.github.kfcfans.powerjob.server.extension.Alarmable; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/WebHookAlarmService.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/WebHookAlarmService.java index dc6662c7..9de33c67 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/WebHookAlarmService.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/alarm/impl/WebHookAlarmService.java @@ -5,7 +5,7 @@ import com.github.kfcfans.powerjob.common.OmsConstant; import com.github.kfcfans.powerjob.common.utils.HttpUtils; import com.github.kfcfans.powerjob.server.persistence.core.model.UserInfoDO; import com.github.kfcfans.powerjob.server.service.alarm.Alarm; -import com.github.kfcfans.powerjob.server.service.alarm.Alarmable; +import com.github.kfcfans.powerjob.server.extension.Alarmable; import lombok.extern.slf4j.Slf4j; import okhttp3.MediaType; import okhttp3.RequestBody; diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/DefaultServerIdProvider.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/DefaultServerIdProvider.java index 1c018370..41ba4ac9 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/DefaultServerIdProvider.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/DefaultServerIdProvider.java @@ -1,39 +1,37 @@ package com.github.kfcfans.powerjob.server.service.id; import com.github.kfcfans.powerjob.common.utils.NetUtils; +import com.github.kfcfans.powerjob.server.extension.ServerIdProvider; import com.github.kfcfans.powerjob.server.persistence.core.model.ServerInfoDO; import com.github.kfcfans.powerjob.server.persistence.core.repository.ServerInfoRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; /** + * 默认服务器 ID 生成策略,不适用于 Server 频繁重启且变化 IP 的场景 * @author user */ +@Slf4j +@Service public class DefaultServerIdProvider implements ServerIdProvider { - private final ServerInfoRepository serverInfoRepository; - private volatile Long id; + private final Long id; - public DefaultServerIdProvider(ServerInfoRepository serverInfoRepository) { - this.serverInfoRepository = serverInfoRepository; - } + public DefaultServerIdProvider(ServerInfoRepository serverInfoRepository) { + String ip = NetUtils.getLocalHost(); + ServerInfoDO server = serverInfoRepository.findByIp(ip); - @Override - public long serverId() { - if (id == null) { - synchronized (this) { - if (id == null) { - String ip = NetUtils.getLocalHost(); - ServerInfoDO server = serverInfoRepository.findByIp(ip); - - if (server == null) { + if (server == null) { ServerInfoDO newServerInfo = new ServerInfoDO(ip); server = serverInfoRepository.saveAndFlush(newServerInfo); - } - - id = server.getId(); } - } + this.id = server.getId(); + + log.info("[DefaultServerIdProvider] address:{},id:{}", ip, id); } - return id; - } + @Override + public long getServerId() { + return id; + } } diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/IdGenerateService.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/IdGenerateService.java index c334d01b..73565360 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/IdGenerateService.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/IdGenerateService.java @@ -1,17 +1,19 @@ package com.github.kfcfans.powerjob.server.service.id; -import com.github.kfcfans.powerjob.common.utils.NetUtils; -import com.github.kfcfans.powerjob.server.persistence.core.model.ServerInfoDO; -import com.github.kfcfans.powerjob.server.persistence.core.repository.ServerInfoRepository; +import com.github.kfcfans.powerjob.common.PowerJobException; +import com.github.kfcfans.powerjob.server.extension.ServerIdProvider; +import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +import java.util.List; /** * 唯一ID生成服务,使用 Twitter snowflake 算法 * 机房ID:固定为0,占用2位 - * 机器ID:数据库自增,占用14位(如果频繁部署需要删除数据库重置id) + * 机器ID:由 ServerIdProvider 提供 * * @author tjq * @since 2020/4/6 @@ -21,16 +23,37 @@ import org.springframework.stereotype.Service; public class IdGenerateService { private final SnowFlakeIdGenerator snowFlakeIdGenerator; - private static final int DATA_CENTER_ID = 0; @Autowired - public IdGenerateService(@Qualifier("serverIdProvider") ServerIdProvider serverIdProvider) { - long id = serverIdProvider.serverId(); - snowFlakeIdGenerator = new SnowFlakeIdGenerator(DATA_CENTER_ID, id); - String ip = NetUtils.getLocalHost(); + public IdGenerateService(List serverIdProviders) { - log.info("[IdGenerateService] init snowflake for server(address={}) by machineId({}).", ip, id); + if (CollectionUtils.isEmpty(serverIdProviders)) { + throw new PowerJobException("can't find any ServerIdProvider!"); + } + + ServerIdProvider serverIdProvider; + int severIpProviderNums = serverIdProviders.size(); + if (severIpProviderNums == 1) { + serverIdProvider = serverIdProviders.get(0); + } else { + List extendServerIpProviders = Lists.newArrayList(); + for (ServerIdProvider sp : serverIdProviders) { + if (sp instanceof DefaultServerIdProvider) { + continue; + } + extendServerIpProviders.add(sp); + } + int extNum = extendServerIpProviders.size(); + if (extNum != 1) { + throw new PowerJobException(String.format("find %d ServerIdProvider but just need one, please delete the useless ServerIdProvider!", extNum)); + } + serverIdProvider = extendServerIpProviders.get(0); + } + + long id = serverIdProvider.getServerId(); + snowFlakeIdGenerator = new SnowFlakeIdGenerator(DATA_CENTER_ID, id); + log.info("[IdGenerateService] initialize IdGenerateService successfully, ServerIdProvider:{},ID:{}", serverIdProvider.getClass().getSimpleName(), id); } /** diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/ServerIdProvider.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/ServerIdProvider.java deleted file mode 100644 index f7fcbd2e..00000000 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/ServerIdProvider.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.kfcfans.powerjob.server.service.id; - -/** - * @author user - */ -public interface ServerIdProvider { - /** - * get number for IdGenerateService - * @return serverId - */ - long serverId(); -} diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/ServerIdProviderConfiguration.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/ServerIdProviderConfiguration.java deleted file mode 100644 index e2e6f5c4..00000000 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/ServerIdProviderConfiguration.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.kfcfans.powerjob.server.service.id; - -import com.github.kfcfans.powerjob.server.persistence.core.repository.ServerInfoRepository; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * @author user - */ -@Configuration -public class ServerIdProviderConfiguration { - @ConditionalOnProperty(prefix = "oms.server-id", name = "provider", havingValue = "hostname") - @Bean(name = "serverIdProvider") - public ServerIdProvider statefulSetServerIdProvider() { - return new StatefulSetServerIdProvider(); - } - - @ConditionalOnMissingBean(ServerIdProvider.class) - @Bean(name = "serverIdProvider") - public ServerIdProvider defaultServerIdProvider(ServerInfoRepository serverInfoRepository) { - return new DefaultServerIdProvider(serverInfoRepository); - } -} diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/SnowFlakeIdGenerator.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/SnowFlakeIdGenerator.java index 637fef6d..2eb5888d 100644 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/SnowFlakeIdGenerator.java +++ b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/SnowFlakeIdGenerator.java @@ -34,8 +34,8 @@ class SnowFlakeIdGenerator { private final static long DATA_CENTER_LEFT = SEQUENCE_BIT + MACHINE_BIT; private final static long TIMESTAMP_LEFT = DATA_CENTER_LEFT + DATA_CENTER_BIT; - private long dataCenterId; //数据中心 - private long machineId; //机器标识 + private final long dataCenterId; //数据中心 + private final long machineId; //机器标识 private long sequence = 0L; //序列号 private long lastTimestamp = -1L;//上一次时间戳 diff --git a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/StatefulSetServerIdProvider.java b/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/StatefulSetServerIdProvider.java deleted file mode 100644 index 9e796e36..00000000 --- a/powerjob-server/src/main/java/com/github/kfcfans/powerjob/server/service/id/StatefulSetServerIdProvider.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.github.kfcfans.powerjob.server.service.id; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author user - */ -public class StatefulSetServerIdProvider implements ServerIdProvider { - /** - * xxx-1,aa-bb-2 - */ - private static final Pattern HOSTNAME_PATTERN = Pattern.compile("^.*-([0-9]+)$"); - - @Override - public long serverId() { - try { - String hostname = InetAddress.getLocalHost().getHostName(); - Matcher matcher = HOSTNAME_PATTERN.matcher(hostname); - if (matcher.matches()) { - return Long.parseLong(matcher.group(1)); - } - throw new RuntimeException(String.format("hostname=%s not match %s", hostname, HOSTNAME_PATTERN.toString())); - } catch (UnknownHostException e) { - throw new RuntimeException(e); - } - } -}