无关风月
2 天以前 ce0651907f18a57dae80065e01589e975530f53e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package com.ruoyi.common.utils;
 
import com.ruoyi.common.utils.ip.IpUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
import java.util.concurrent.atomic.AtomicLong;
 
public class OrderNos {
 
    public static final char PADCHAR = '0';
 
 
 
    /**
     * 长度24位全球唯一标识
     */
 
    /**
     * 统一不重复内部订单号
     *
     * @param systemCode
     *            4字节系统编码
     * @return 24字节不重复编码
     */
    public static String oid(String systemCode) {
        StringBuilder sb = new StringBuilder();
        sb.append(padding(systemCode, 4));
        sb.append(Did.getInstance().getId(20));
        return sb.toString();
    }
 
    public static String oid() {
        return oid("O001");
    }
 
    /**
     * 获取分布式Id
     *
     * @return 默认20字符长度的数字不重复编码
     */
    public static String getDid() {
        return Did.getInstance().getId();
    }
 
    public static String getDid(int size) {
        return Did.getInstance().getId(size);
    }
 
    public static String getDid(String prefix) {
        return prefix + Did.getInstance().getId();
    }
 
    private static String padding(String text, int size) {
        String txt = StringUtils.trimToEmpty(text);
        if (StringUtils.length(txt) > size) {
            txt = StringUtils.substring(txt, StringUtils.length(txt) - size);
        }
        return StringUtils.leftPad(txt, size, PADCHAR);
    }
 
    /**
     * ID生成器
     *
     * 20字符长度 yyMMddHHmmss+3位本机IP末三位+5位随机数字
     *
     * @author zhangpu
     *
     */
    public static class Did {
        private static final Logger logger = LoggerFactory.getLogger(OrderNos.class);
        private static final int MIN_LENGTH = 19;
        private static final int SEQU_MAX = 99999;
        private static final int SEQU_19_MAX = 9999;
        private volatile static long BASE = 0;
        private AtomicLong sequence = new AtomicLong(0);
        private String nodeFlag;
        private Object nodeFlagLock = new Object();
        private static Did did = new Did();
 
 
        public static Did getInstance() {
            return did;
        }
 
        /**
         * 生产新Id
         *
         * @return
         */
        public  String getId() {
            return getId(20);
        }
 
        public  String getId(int size) {
            if (size < MIN_LENGTH) {
                throw new RuntimeException("did最小长度为" + MIN_LENGTH);
            }
            StringBuilder sb = new StringBuilder();
            sb.append(DateUtils.dateTimeNow("yyMMddHHmmss"));
            sb.append(getNodeFlag());
            sb.append(getSequ(size-15));
            return sb.toString();
        }
 
        public synchronized String getSequ(int size) {
            long timeCount = System.currentTimeMillis() / 1000;
 
            while (true) {
                long now = sequence.get();
                if (timeCount > now) {
                    // 已经过了本秒,则设置新的值
                    if (sequence.compareAndSet(now, timeCount)) {
                        break;
                    }
                } else {
                    if (sequence.compareAndSet(now, now + 1)) {
                        timeCount = now + 1;
                        break;
                    }
                }
            }
            int sn = (int) (timeCount % (size>=5?SEQU_MAX:SEQU_19_MAX));
            return StringUtils.leftPad(String.valueOf(sn), size, '0');
        }
 
        private  String  getNodeFlag(){
            if (this.nodeFlag == null) {
                synchronized (Did.class){
                    if (this.nodeFlag==null){
                        this.nodeFlag = generateNodeFlag();
                    }
                }
            }
            return this.nodeFlag;
        }
 
        /**
         * 简单节点编码
         *
         * 逻辑:Ip地址后三位,便于快速知道是哪个节点
         *
         * @return
         */
        private String generateNodeFlag() {
            String ipPostfix = null;
            try {
                String ip = IpUtils.getFirstNoLoopbackIPV4Address();
                ipPostfix = StringUtils.substringAfterLast(ip, ".");
            } catch (Exception e) {
                logger.warn("生产DID要素本机IP获取失败:" + e.getMessage());
            }
            return StringUtils.leftPad(ipPostfix, 3, "0");
        }
 
        private Did() {
            super();
        }
    }
 
 
 
}