|
|
|
@ -6,10 +6,10 @@ import com.google.common.base.Preconditions; |
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
import net.sopod.soim.common.util.ImClock; |
|
|
|
import net.sopod.soim.common.util.ImClock; |
|
|
|
import net.sopod.soim.common.util.ObjectUtil; |
|
|
|
import net.sopod.soim.common.util.ObjectUtil; |
|
|
|
|
|
|
|
import net.sopod.soim.logic.segmentid.api.model.dto.SegmentDTO; |
|
|
|
|
|
|
|
import net.sopod.soim.logic.segmentid.api.service.SegmentIdService; |
|
|
|
import net.sopod.soim.logic.segmentid.config.SegmentConfig; |
|
|
|
import net.sopod.soim.logic.segmentid.config.SegmentConfig; |
|
|
|
import net.sopod.soim.logic.segmentid.mapper.SegmentIdMapper; |
|
|
|
import net.sopod.soim.logic.segmentid.mapper.SegmentIdMapper; |
|
|
|
import net.sopod.soim.logic.segmentid.model.dto.NextSegmentParam; |
|
|
|
|
|
|
|
import net.sopod.soim.logic.segmentid.model.dto.SegmentDTO; |
|
|
|
|
|
|
|
import net.sopod.soim.logic.segmentid.model.entity.SegmentId; |
|
|
|
import net.sopod.soim.logic.segmentid.model.entity.SegmentId; |
|
|
|
import net.sopod.soim.logic.segmentid.util.RedisLockUtil; |
|
|
|
import net.sopod.soim.logic.segmentid.util.RedisLockUtil; |
|
|
|
import org.apache.dubbo.config.annotation.DubboService; |
|
|
|
import org.apache.dubbo.config.annotation.DubboService; |
|
|
|
@ -27,9 +27,9 @@ import java.util.concurrent.ThreadLocalRandom; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
@DubboService |
|
|
|
@DubboService |
|
|
|
@AllArgsConstructor |
|
|
|
@AllArgsConstructor |
|
|
|
public class SegmentIdService { |
|
|
|
public class SegmentIdServiceImpl implements SegmentIdService { |
|
|
|
|
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SegmentIdService.class); |
|
|
|
private static final Logger logger = LoggerFactory.getLogger(SegmentIdServiceImpl.class); |
|
|
|
|
|
|
|
|
|
|
|
private final SegmentIdMapper segmentIdMapper; |
|
|
|
private final SegmentIdMapper segmentIdMapper; |
|
|
|
|
|
|
|
|
|
|
|
@ -37,8 +37,13 @@ public class SegmentIdService { |
|
|
|
|
|
|
|
|
|
|
|
private final SegmentConfig segmentConfig; |
|
|
|
private final SegmentConfig segmentConfig; |
|
|
|
|
|
|
|
|
|
|
|
public SegmentDTO nextSegmentId(NextSegmentParam param) { |
|
|
|
@Override |
|
|
|
String bizTag = param.getBizTag(); |
|
|
|
public SegmentDTO nextSegmentId(String bizTag) { |
|
|
|
|
|
|
|
return nextSegmentId(bizTag, null); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public SegmentDTO nextSegmentId(String bizTag, Long step) { |
|
|
|
SegmentId segmentId = segmentIdMapper.selectById(bizTag); |
|
|
|
SegmentId segmentId = segmentIdMapper.selectById(bizTag); |
|
|
|
if (segmentId == null) { |
|
|
|
if (segmentId == null) { |
|
|
|
String key = SegmentConfig.KEY_PREFIX_SEGMENT_ID_INSERT + bizTag; |
|
|
|
String key = SegmentConfig.KEY_PREFIX_SEGMENT_ID_INSERT + bizTag; |
|
|
|
@ -53,7 +58,7 @@ public class SegmentIdService { |
|
|
|
.setCreateTime(ImClock.date()) |
|
|
|
.setCreateTime(ImClock.date()) |
|
|
|
.setCurrentId(segmentConfig.getInitId()) |
|
|
|
.setCurrentId(segmentConfig.getInitId()) |
|
|
|
.setVersion(0L) |
|
|
|
.setVersion(0L) |
|
|
|
.setInitStep(segmentConfig.getInitStep()); |
|
|
|
.setInitStep(ObjectUtil.defaultValue(step, segmentConfig.getInitStep())); |
|
|
|
segmentIdMapper.insert(newSegmentId); |
|
|
|
segmentIdMapper.insert(newSegmentId); |
|
|
|
segmentId = newSegmentId; |
|
|
|
segmentId = newSegmentId; |
|
|
|
} finally { |
|
|
|
} finally { |
|
|
|
@ -61,6 +66,7 @@ public class SegmentIdService { |
|
|
|
RedisLockUtil.releaseLock(redisTemplate, key, val); |
|
|
|
RedisLockUtil.releaseLock(redisTemplate, key, val); |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
logger.info("wait lock..."); |
|
|
|
// 等待锁释放
|
|
|
|
// 等待锁释放
|
|
|
|
long timeout = 2000L; |
|
|
|
long timeout = 2000L; |
|
|
|
boolean released = waitReleaseRedisLock(key, timeout); |
|
|
|
boolean released = waitReleaseRedisLock(key, timeout); |
|
|
|
@ -73,15 +79,27 @@ public class SegmentIdService { |
|
|
|
throw new RuntimeException(String.format("%s分段数据不存在,新增失败", bizTag)); |
|
|
|
throw new RuntimeException(String.format("%s分段数据不存在,新增失败", bizTag)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
int i = 0; |
|
|
|
long begin = ImClock.millis(); |
|
|
|
do { |
|
|
|
for (int i = 0; ; i++) { |
|
|
|
SegmentDTO segment = getSegment(segmentId, param.getStep()); |
|
|
|
if (i > 0) { |
|
|
|
|
|
|
|
segmentId = segmentIdMapper.selectById(bizTag); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
SegmentDTO segment = getSegment(segmentId, step); |
|
|
|
if (segment != null) { |
|
|
|
if (segment != null) { |
|
|
|
|
|
|
|
if (i > 0) |
|
|
|
|
|
|
|
logger.info("{} get segment try {} times", bizTag, i); |
|
|
|
return segment; |
|
|
|
return segment; |
|
|
|
} |
|
|
|
} |
|
|
|
i++; |
|
|
|
try { |
|
|
|
} while (i < segmentConfig.getDbSegmentVersionRetryTimes()); |
|
|
|
Thread.sleep(ThreadLocalRandom.current().nextInt(50) + 50L); |
|
|
|
|
|
|
|
} catch (InterruptedException e) { |
|
|
|
|
|
|
|
logger.error("wait db interrupted!", e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
long current = ImClock.millis(); |
|
|
|
|
|
|
|
if (current - begin > segmentConfig.getGetSegmentPollDBTimeout()) { |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
throw new RuntimeException("id分段获取失败"); |
|
|
|
throw new RuntimeException("id分段获取失败"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -106,11 +124,12 @@ public class SegmentIdService { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 获取id段 |
|
|
|
* 获取id段 |
|
|
|
|
|
|
|
* |
|
|
|
* @param dbSegmentId 当前DB segmentId |
|
|
|
* @param dbSegmentId 当前DB segmentId |
|
|
|
* @param step 步长 |
|
|
|
* @param step 步长 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private SegmentDTO getSegment(SegmentId dbSegmentId, Long step) { |
|
|
|
private SegmentDTO getSegment(SegmentId dbSegmentId, Long step) { |
|
|
|
step = ObjectUtil.defaultValue(step, dbSegmentId.getInitStep(), null); |
|
|
|
step = ObjectUtil.defaultValue(step, dbSegmentId.getInitStep(), dbSegmentId.getInitStep()); |
|
|
|
Preconditions.checkState(step > 0, "步长需大于0"); |
|
|
|
Preconditions.checkState(step > 0, "步长需大于0"); |
|
|
|
// 开始id, 结束id
|
|
|
|
// 开始id, 结束id
|
|
|
|
Long currentId = dbSegmentId.getCurrentId(); |
|
|
|
Long currentId = dbSegmentId.getCurrentId(); |