From de1da4359b647fdf425ad6e179ceba570b024c95 Mon Sep 17 00:00:00 2001
From: tangmingyou <234767776@qq.com>
Date: Sun, 3 Apr 2022 01:42:35 +0800
Subject: [PATCH] =?UTF-8?q?=E5=88=86=E5=B8=83=E5=BC=8Fid=E5=8F=B7=E6=AE=B5?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../segmentid/{ => api}/model/Segment.java | 2 +-
.../api}/model/dto/NextSegmentParam.java | 2 +-
.../segmentid/api}/model/dto/SegmentDTO.java | 8 ++-
.../api/service/SegmentIdService.java | 18 +++++++
im-logic/im-segment-id/pom.xml | 12 +++++
.../logic/segmentid/SegmentIdApplication.java | 2 +
.../logic/segmentid/config/SegmentConfig.java | 5 +-
.../segmentid/mapper/SegmentIdMapper.java | 2 +
...Service.java => SegmentIdServiceImpl.java} | 49 +++++++++++++------
.../src/main/resources/application.yml | 4 +-
.../test/SegmentIdApplicationTest.java | 48 ++++++++++++++++++
pom.xml | 5 ++
12 files changed, 136 insertions(+), 21 deletions(-)
rename im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/{ => api}/model/Segment.java (65%)
rename {im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid => im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api}/model/dto/NextSegmentParam.java (82%)
rename {im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid => im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api}/model/dto/SegmentDTO.java (50%)
create mode 100644 im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/service/SegmentIdService.java
rename im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/{SegmentIdService.java => SegmentIdServiceImpl.java} (77%)
create mode 100644 im-logic/im-segment-id/src/test/java/net/sopod/soim/logic/segmentid/test/SegmentIdApplicationTest.java
diff --git a/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/model/Segment.java b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/Segment.java
similarity index 65%
rename from im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/model/Segment.java
rename to im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/Segment.java
index d23c0c9..05180f3 100644
--- a/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/model/Segment.java
+++ b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/Segment.java
@@ -1,4 +1,4 @@
-package net.sopod.soim.logic.segmentid.model;
+package net.sopod.soim.logic.segmentid.api.model;
/**
* Segment
diff --git a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/model/dto/NextSegmentParam.java b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/dto/NextSegmentParam.java
similarity index 82%
rename from im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/model/dto/NextSegmentParam.java
rename to im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/dto/NextSegmentParam.java
index 60270f0..61b7e3e 100644
--- a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/model/dto/NextSegmentParam.java
+++ b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/dto/NextSegmentParam.java
@@ -1,4 +1,4 @@
-package net.sopod.soim.logic.segmentid.model.dto;
+package net.sopod.soim.logic.segmentid.api.model.dto;
import lombok.Data;
diff --git a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/model/dto/SegmentDTO.java b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/dto/SegmentDTO.java
similarity index 50%
rename from im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/model/dto/SegmentDTO.java
rename to im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/dto/SegmentDTO.java
index 44ec87b..b52da8e 100644
--- a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/model/dto/SegmentDTO.java
+++ b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/model/dto/SegmentDTO.java
@@ -1,8 +1,10 @@
-package net.sopod.soim.logic.segmentid.model.dto;
+package net.sopod.soim.logic.segmentid.api.model.dto;
import lombok.Data;
import lombok.experimental.Accessors;
+import java.io.Serializable;
+
/**
* SegmentDTO
*
@@ -11,7 +13,9 @@ import lombok.experimental.Accessors;
*/
@Data
@Accessors(chain = true)
-public class SegmentDTO {
+public class SegmentDTO implements Serializable {
+
+ private static final long serialVersionUID = 4767453140231279111L;
private long beginId;
diff --git a/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/service/SegmentIdService.java b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/service/SegmentIdService.java
new file mode 100644
index 0000000..5ac20cc
--- /dev/null
+++ b/im-logic-api/im-segment-id-api/src/main/java/net/sopod/soim/logic/segmentid/api/service/SegmentIdService.java
@@ -0,0 +1,18 @@
+package net.sopod.soim.logic.segmentid.api.service;
+
+import net.sopod.soim.logic.segmentid.api.model.dto.NextSegmentParam;
+import net.sopod.soim.logic.segmentid.api.model.dto.SegmentDTO;
+
+/**
+ * SegmentIdService
+ *
+ * @author tmy
+ * @date 2022-04-02 23:07
+ */
+public interface SegmentIdService {
+
+ SegmentDTO nextSegmentId(String bizTag);
+
+ SegmentDTO nextSegmentId(String bizTag, Long step);
+
+}
diff --git a/im-logic/im-segment-id/pom.xml b/im-logic/im-segment-id/pom.xml
index 0d429c7..8542119 100644
--- a/im-logic/im-segment-id/pom.xml
+++ b/im-logic/im-segment-id/pom.xml
@@ -74,5 +74,17 @@
org.springframework
spring-orm
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.junit.vintage
+ junit-vintage-engine
+
+
+
\ No newline at end of file
diff --git a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/SegmentIdApplication.java b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/SegmentIdApplication.java
index 71be1fb..b1eacb0 100644
--- a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/SegmentIdApplication.java
+++ b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/SegmentIdApplication.java
@@ -1,6 +1,7 @@
package net.sopod.soim.logic.segmentid;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
+import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -11,6 +12,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @date 2022-04-02 14:55
*/
@EnableDubbo(scanBasePackages = {"net.sopod.soim.logic.segmentid.service"})
+@MapperScan("net.sopod.soim.logic.segmentid.mapper")
@SpringBootApplication
public class SegmentIdApplication {
diff --git a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/config/SegmentConfig.java b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/config/SegmentConfig.java
index 8e1210b..7cab1a7 100644
--- a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/config/SegmentConfig.java
+++ b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/config/SegmentConfig.java
@@ -23,6 +23,9 @@ public class SegmentConfig {
private long initStep = 1000L;
- private int dbSegmentVersionRetryTimes = 3;
+ //private int dbSegmentVersionRetryTimes = 10;
+
+ /** 从数据库查询区段号超时时间,并发时进行轮询 */
+ private long getSegmentPollDBTimeout = 2000L;
}
diff --git a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/mapper/SegmentIdMapper.java b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/mapper/SegmentIdMapper.java
index f0ff626..ded1656 100644
--- a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/mapper/SegmentIdMapper.java
+++ b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/mapper/SegmentIdMapper.java
@@ -2,6 +2,7 @@ package net.sopod.soim.logic.segmentid.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import net.sopod.soim.logic.segmentid.model.entity.SegmentId;
+import org.springframework.stereotype.Repository;
/**
* SegmentIdMapper
@@ -9,6 +10,7 @@ import net.sopod.soim.logic.segmentid.model.entity.SegmentId;
* @author tmy
* @date 2022-04-02 15:00
*/
+@Repository
public interface SegmentIdMapper extends BaseMapper {
}
diff --git a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/SegmentIdService.java b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/SegmentIdServiceImpl.java
similarity index 77%
rename from im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/SegmentIdService.java
rename to im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/SegmentIdServiceImpl.java
index f4457f1..ac189d6 100644
--- a/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/SegmentIdService.java
+++ b/im-logic/im-segment-id/src/main/java/net/sopod/soim/logic/segmentid/service/SegmentIdServiceImpl.java
@@ -6,10 +6,10 @@ import com.google.common.base.Preconditions;
import lombok.AllArgsConstructor;
import net.sopod.soim.common.util.ImClock;
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.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.util.RedisLockUtil;
import org.apache.dubbo.config.annotation.DubboService;
@@ -27,9 +27,9 @@ import java.util.concurrent.ThreadLocalRandom;
*/
@DubboService
@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;
@@ -37,8 +37,13 @@ public class SegmentIdService {
private final SegmentConfig segmentConfig;
- public SegmentDTO nextSegmentId(NextSegmentParam param) {
- String bizTag = param.getBizTag();
+ @Override
+ public SegmentDTO nextSegmentId(String bizTag) {
+ return nextSegmentId(bizTag, null);
+ }
+
+ @Override
+ public SegmentDTO nextSegmentId(String bizTag, Long step) {
SegmentId segmentId = segmentIdMapper.selectById(bizTag);
if (segmentId == null) {
String key = SegmentConfig.KEY_PREFIX_SEGMENT_ID_INSERT + bizTag;
@@ -53,7 +58,7 @@ public class SegmentIdService {
.setCreateTime(ImClock.date())
.setCurrentId(segmentConfig.getInitId())
.setVersion(0L)
- .setInitStep(segmentConfig.getInitStep());
+ .setInitStep(ObjectUtil.defaultValue(step, segmentConfig.getInitStep()));
segmentIdMapper.insert(newSegmentId);
segmentId = newSegmentId;
} finally {
@@ -61,6 +66,7 @@ public class SegmentIdService {
RedisLockUtil.releaseLock(redisTemplate, key, val);
}
} else {
+ logger.info("wait lock...");
// 等待锁释放
long timeout = 2000L;
boolean released = waitReleaseRedisLock(key, timeout);
@@ -73,15 +79,27 @@ public class SegmentIdService {
throw new RuntimeException(String.format("%s分段数据不存在,新增失败", bizTag));
}
}
- int i = 0;
- do {
- SegmentDTO segment = getSegment(segmentId, param.getStep());
+ long begin = ImClock.millis();
+ for (int i = 0; ; i++) {
+ if (i > 0) {
+ segmentId = segmentIdMapper.selectById(bizTag);
+ }
+ SegmentDTO segment = getSegment(segmentId, step);
if (segment != null) {
+ if (i > 0)
+ logger.info("{} get segment try {} times", bizTag, i);
return segment;
}
- i++;
- } while (i < segmentConfig.getDbSegmentVersionRetryTimes());
-
+ try {
+ 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分段获取失败");
}
@@ -106,11 +124,12 @@ public class SegmentIdService {
/**
* 获取id段
+ *
* @param dbSegmentId 当前DB segmentId
- * @param step 步长
+ * @param 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");
// 开始id, 结束id
Long currentId = dbSegmentId.getCurrentId();
diff --git a/im-logic/im-segment-id/src/main/resources/application.yml b/im-logic/im-segment-id/src/main/resources/application.yml
index 479f900..824b87f 100644
--- a/im-logic/im-segment-id/src/main/resources/application.yml
+++ b/im-logic/im-segment-id/src/main/resources/application.yml
@@ -7,7 +7,8 @@ spring:
username: root
password: sopod@2347#
redis:
- host: 124.222.131.236:3379
+ host: 124.222.131.236
+ port: 3379
password: sopod@redis#
dubbo:
@@ -20,3 +21,4 @@ dubbo:
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
+
diff --git a/im-logic/im-segment-id/src/test/java/net/sopod/soim/logic/segmentid/test/SegmentIdApplicationTest.java b/im-logic/im-segment-id/src/test/java/net/sopod/soim/logic/segmentid/test/SegmentIdApplicationTest.java
new file mode 100644
index 0000000..d6819d9
--- /dev/null
+++ b/im-logic/im-segment-id/src/test/java/net/sopod/soim/logic/segmentid/test/SegmentIdApplicationTest.java
@@ -0,0 +1,48 @@
+package net.sopod.soim.logic.segmentid.test;
+
+import net.sopod.soim.common.util.ImClock;
+import net.sopod.soim.logic.segmentid.SegmentIdApplication;
+import net.sopod.soim.logic.segmentid.api.model.dto.SegmentDTO;
+import net.sopod.soim.logic.segmentid.api.service.SegmentIdService;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * SegmentIdApplicationTest
+ *
+ * @author tmy
+ * @date 2022-04-03 00:54
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest(classes = SegmentIdApplication.class)
+public class SegmentIdApplicationTest {
+
+ @DubboReference
+ private SegmentIdService segmentIdService;
+
+ @Test
+ public void test1() throws InterruptedException {
+ CountDownLatch countDown = new CountDownLatch(10);
+ for (int i = 0; i < 10; i++) {
+ final int idx = i;
+ new Thread(() -> {
+ try {
+ long begin = ImClock.millis();
+ SegmentDTO segment = segmentIdService.nextSegmentId("im-user");
+ System.out.println(idx + segment.toString() + (ImClock.millis() - begin));
+ }catch (Exception e){
+ System.out.println(idx + "fail:" + e.getMessage());
+ } finally {
+ countDown.countDown();
+ }
+ }).start();
+ }
+ countDown.await();
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index e616194..ba2ebd6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -129,6 +129,11 @@
spring-boot-starter-data-redis
${spring-boot.version}
+
+ io.lettuce
+ lettuce-core
+ 6.1.6.RELEASE
+
org.apache.dubbo
dubbo-spring-boot-starter