Browse Source

订单编号生成类

gaodm 6 years ago
parent
commit
b5113a120e

+ 36 - 0
diagbotman-service/src/main/java/com/diagbot/idc/AbstractIdCreater.java

@@ -0,0 +1,36 @@
+package com.diagbot.idc;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @Description: ID生成抽象类接口
+ * @author: gaodm
+ * @time: 2018/9/5 9:20
+ */
+public abstract class AbstractIdCreater<T> implements IdCreater<T> {
+
+    protected int machineId;
+    protected int dataCenterId;
+
+    public AbstractIdCreater(int machineId, int dataCenterId) {
+        this.machineId = machineId;
+        this.dataCenterId = dataCenterId;
+    }
+
+    @Override
+    public abstract Long getNextId(T param);
+
+    @Override
+    public List<Long> getNextIds(T param, int size) {
+        List<Long> longs = new ArrayList<>(size);
+        for (int i = 0; i < size; i++) {
+            longs.add(getNextId(param));
+        }
+        return longs;
+    }
+
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+}

+ 24 - 0
diagbotman-service/src/main/java/com/diagbot/idc/IdCreater.java

@@ -0,0 +1,24 @@
+package com.diagbot.idc;
+
+import java.util.List;
+
+/**
+ * @Description: ID生成接口
+ * @author: gaodm
+ * @time: 2018/9/5 9:21
+ */
+public interface IdCreater<T> {
+
+    /**
+     * 生成一个id
+     * @return 生成的id
+     */
+    Long getNextId(T param);
+
+    /**
+     * 批量生成id
+     * @param size 生成数量
+     * @return 生成的id列表
+     */
+    List<Long> getNextIds(T param, int size);
+}

+ 62 - 0
diagbotman-service/src/main/java/com/diagbot/idc/InvisibleIdCreater.java

@@ -0,0 +1,62 @@
+package com.diagbot.idc;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.dao.DataAccessException;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.core.RedisCallback;
+import org.springframework.data.redis.core.RedisTemplate;
+
+import java.util.List;
+
+/**
+ * @Description: 不可见id由redis生成
+ * @author: gaodm
+ * @time: 2018/9/5 9:21
+ */
+@SuppressWarnings("unchecked")
+@Slf4j
+public class InvisibleIdCreater extends AbstractIdCreater<Class> {
+
+    @Autowired
+    @Qualifier("redisTemplateForIdc")
+    RedisTemplate redisTemplate;
+
+    public InvisibleIdCreater(int machineId, int dataCenterId) {
+        super(machineId, dataCenterId);
+    }
+
+    @Override
+    public Long getNextId(Class param) {
+        final byte[] redis_key = redisTemplate.getKeySerializer().serialize("id_" + param.getName());
+        Object execute = redisTemplate.execute(new RedisCallback() {
+            @Override
+            public Long doInRedis(RedisConnection connection) throws DataAccessException {
+                Long incr = connection.incr(redis_key);
+                return incr;
+            }
+        });
+        return (Long) execute;
+    }
+
+    @Override
+    public List<Long> getNextIds(Class param, final int size) {
+        final byte[] rawKey = redisTemplate.getKeySerializer().serialize("id_" + param.getName());
+        //pipeline
+        RedisCallback<List<Object>> pipelineCallback = new RedisCallback<List<Object>>() {
+            @Override
+            public List<Object> doInRedis(RedisConnection connection) throws DataAccessException {
+                connection.openPipeline();
+                for (int i = 0; i < size; i++) {
+                    connection.incr(rawKey);
+                }
+                return connection.closePipeline();
+            }
+        };
+
+        List<Long> results = (List<Long>) redisTemplate.execute(pipelineCallback);
+        return results;
+    }
+
+}

+ 71 - 0
diagbotman-service/src/main/java/com/diagbot/idc/VisibleIdCreater.java

@@ -0,0 +1,71 @@
+package com.diagbot.idc;
+
+
+import com.diagbot.util.DateUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.RandomUtils;
+import org.apache.commons.lang3.time.DateUtils;
+
+import java.util.Calendar;
+
+/**
+ * @Description: 可见id每秒递增
+ * @author: gaodm
+ * @time: 2018/9/5 10:45
+ */
+@Slf4j
+public class VisibleIdCreater extends AbstractIdCreater<Integer> {
+
+    private long lastTimestamp = -1L;
+
+    private long sequence = 0L;
+    private long sequenceMask = 9999;
+
+    public VisibleIdCreater(int machineId, int dataCenterId) {
+        super(machineId, dataCenterId);
+    }
+
+    @Override
+    /**
+     *  对外id生成规则
+     *  180905123451110001
+     *  180905 - 12345 -  1   -  1   -     1     - 0001
+     *   日期 -  秒数  - 业务 - 机器 - 数据中心 - 秒内自增
+     *  @param type 业务id 1.订单 2.交易 3.退款
+     *  @return 生成的id
+     */
+    public synchronized Long getNextId(Integer type) {
+
+        Calendar calendar = Calendar.getInstance();
+
+        long timestamp = timeGen() / 1000;
+
+        if (timestamp < lastTimestamp) {
+            log.error(String.format("clock is moving backwards. Rejecting requests until %d.", lastTimestamp));
+            throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1);
+            if (sequence > sequenceMask) {
+                //timestamp = tilNextMillis(lastTimestamp);
+                log.error(String.format("id creater sequence is full. wait to next time"));
+                return null;
+            }
+        } else {
+            sequence = getNewSequence();
+        }
+
+        lastTimestamp = timestamp;
+
+        String date = DateUtil.format(calendar.getTime(), "yyMMdd");
+        long seconds = DateUtils.getFragmentInSeconds(calendar, Calendar.DAY_OF_YEAR);
+
+        return Long.valueOf(date + String.format("%05d", seconds) + String.valueOf(type) + machineId + dataCenterId + sequence);
+    }
+
+    private long getNewSequence() {
+        return RandomUtils.nextInt(1000, 2000);
+    }
+
+}