use database config control sequence of order code
Showing
6 changed files
with
149 additions
and
9 deletions
@@ -70,7 +70,9 @@ public class CacheKeyBuilder { | @@ -70,7 +70,9 @@ public class CacheKeyBuilder { | ||
70 | 70 | ||
71 | SELLER_EARNEST_MONEY_CONFIG("ufo:order:seller:earnestMoney:config",""), | 71 | SELLER_EARNEST_MONEY_CONFIG("ufo:order:seller:earnestMoney:config",""), |
72 | 72 | ||
73 | - PRESALE_THRESHOLD("ufo:order:presale:threshold", "") | 73 | + PRESALE_THRESHOLD("ufo:order:presale:threshold", ""), |
74 | + | ||
75 | + ORDER_CODE_RULE("ufo:order:code:rule", "") | ||
74 | ; | 76 | ; |
75 | 77 | ||
76 | private String fix; | 78 | private String fix; |
@@ -12,6 +12,7 @@ import com.yohoufo.dal.order.MetaConfigMapper; | @@ -12,6 +12,7 @@ import com.yohoufo.dal.order.MetaConfigMapper; | ||
12 | import com.yohoufo.dal.order.model.MetaConfig; | 12 | import com.yohoufo.dal.order.model.MetaConfig; |
13 | import com.yohoufo.order.model.dto.BuyerPenalty; | 13 | import com.yohoufo.order.model.dto.BuyerPenalty; |
14 | import com.yohoufo.order.model.dto.EarnestMoney; | 14 | import com.yohoufo.order.model.dto.EarnestMoney; |
15 | +import com.yohoufo.order.model.dto.OrderCodeRule; | ||
15 | import com.yohoufo.order.model.dto.PreSaleOrderConfig; | 16 | import com.yohoufo.order.model.dto.PreSaleOrderConfig; |
16 | import com.yohoufo.order.service.cache.CacheKeyBuilder; | 17 | import com.yohoufo.order.service.cache.CacheKeyBuilder; |
17 | import com.yohoufo.order.service.cache.ExpiredTime; | 18 | import com.yohoufo.order.service.cache.ExpiredTime; |
@@ -247,4 +248,22 @@ public class MetaConfigService { | @@ -247,4 +248,22 @@ public class MetaConfigService { | ||
247 | return psoc; | 248 | return psoc; |
248 | } | 249 | } |
249 | 250 | ||
251 | + /** | ||
252 | + * 获取配置的订单号生成规则 | ||
253 | + * @return | ||
254 | + */ | ||
255 | + public OrderCodeRule getOrderCodeRule(){ | ||
256 | + CacheKeyBuilder.KeyTemp kt = CacheKeyBuilder.KeyTemp.ORDER_CODE_RULE; | ||
257 | + RedisKeyBuilder rkb = kt.builderKeyOnlyFixed(); | ||
258 | + final String key = MetaConfigKey.ORDER_CODE_RULE; | ||
259 | + String configVal = new DataProcesser(rkb, key, ExpiredTime.ORDER_BASE_CONFIG).getConfigVal();; | ||
260 | + OrderCodeRule ocr = new OrderCodeRule(); | ||
261 | + try{ | ||
262 | + ocr = JSONObject.parseObject(configVal, OrderCodeRule.class); | ||
263 | + }catch (Exception ex){ | ||
264 | + logger.warn("in getOrderCodeRule parseObject fail, metaVal {}", configVal, ex); | ||
265 | + } | ||
266 | + return ocr; | ||
267 | + } | ||
268 | + | ||
250 | } | 269 | } |
order/src/main/java/com/yohoufo/order/service/support/codegenerator/impl/OrderCodeGeneratorImpl.java
1 | package com.yohoufo.order.service.support.codegenerator.impl; | 1 | package com.yohoufo.order.service.support.codegenerator.impl; |
2 | 2 | ||
3 | import com.yohobuy.ufo.model.order.common.OrderCodeType; | 3 | import com.yohobuy.ufo.model.order.common.OrderCodeType; |
4 | +import com.yohobuy.ufo.model.order.constants.OpsEnv; | ||
5 | +import com.yohoufo.order.model.dto.OrderCodeRule; | ||
6 | +import com.yohoufo.order.service.impl.MetaConfigService; | ||
4 | import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator; | 7 | import com.yohoufo.order.service.support.codegenerator.OrderCodeGenerator; |
5 | import com.yohoufo.order.service.support.codegenerator.bean.CodeBitMeta; | 8 | import com.yohoufo.order.service.support.codegenerator.bean.CodeBitMeta; |
6 | import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta; | 9 | import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta; |
@@ -31,6 +34,9 @@ public class OrderCodeGeneratorImpl implements OrderCodeGenerator { | @@ -31,6 +34,9 @@ public class OrderCodeGeneratorImpl implements OrderCodeGenerator { | ||
31 | @Autowired | 34 | @Autowired |
32 | MachineIdProvider machineIdProvider; | 35 | MachineIdProvider machineIdProvider; |
33 | 36 | ||
37 | + @Autowired | ||
38 | + MetaConfigService metaConfigService; | ||
39 | + | ||
34 | long machineId = 0l; | 40 | long machineId = 0l; |
35 | 41 | ||
36 | @PostConstruct | 42 | @PostConstruct |
@@ -41,7 +47,13 @@ public class OrderCodeGeneratorImpl implements OrderCodeGenerator { | @@ -41,7 +47,13 @@ public class OrderCodeGeneratorImpl implements OrderCodeGenerator { | ||
41 | } | 47 | } |
42 | 48 | ||
43 | if (idPopulator == null){ | 49 | if (idPopulator == null){ |
44 | - idPopulator = new AtomicIdPopulator(); | 50 | + |
51 | + SequenceStrategy.SingleData sssd = createSequence(); | ||
52 | + long seq = sssd.start; | ||
53 | + | ||
54 | + AtomicIdPopulator.Variant variant = new AtomicIdPopulator().new Variant(seq); | ||
55 | + | ||
56 | + idPopulator = new AtomicIdPopulator(variant); | ||
45 | } | 57 | } |
46 | 58 | ||
47 | machineId = machineIdProvider.getMachineId(); | 59 | machineId = machineIdProvider.getMachineId(); |
@@ -50,6 +62,31 @@ public class OrderCodeGeneratorImpl implements OrderCodeGenerator { | @@ -50,6 +62,31 @@ public class OrderCodeGeneratorImpl implements OrderCodeGenerator { | ||
50 | validateMachineId(this.machineId); | 62 | validateMachineId(this.machineId); |
51 | } | 63 | } |
52 | 64 | ||
65 | + private SequenceStrategy.SingleData createSequence(){ | ||
66 | + OrderCodeRule ocr = metaConfigService.getOrderCodeRule(); | ||
67 | + Long seq = 0L; | ||
68 | + String env = null; | ||
69 | + boolean envIsNull = false; | ||
70 | + if (ocr==null || (envIsNull = ((env=ocr.getEnv()) == null))){ | ||
71 | + log.warn("in order code generator env use prd, OrderCodeRule {}", ocr); | ||
72 | + } | ||
73 | + //明确指定了配置使用非生产环境时,序列号从1000开始 | ||
74 | + if (!envIsNull && !OpsEnv.PRD.getName().equalsIgnoreCase(env)){ | ||
75 | + seq = 1000L; | ||
76 | + log.info("in order code generator env use not prd config, OrderCodeRule {} seq {}", ocr, seq); | ||
77 | + } | ||
78 | + log.info("in order code generator init config, OrderCodeRule {} seq {}", ocr, seq); | ||
79 | + /* | ||
80 | + *这是常驻内存的方式,其实很不妥,运维不方便; | ||
81 | + * 数据库修改后需要重新发布工程才能获取新值 | ||
82 | + */ | ||
83 | + SequenceStrategy.SingleData sssd = SequenceStrategy.SingleData.create(env, seq); | ||
84 | + | ||
85 | + return sssd; | ||
86 | + } | ||
87 | + | ||
88 | + | ||
89 | + | ||
53 | public long generate(OrderCodeType type) { | 90 | public long generate(OrderCodeType type) { |
54 | CodeMeta id = new CodeMeta(); | 91 | CodeMeta id = new CodeMeta(); |
55 | 92 |
order/src/main/java/com/yohoufo/order/service/support/codegenerator/impl/SequenceStrategy.java
0 → 100644
1 | +package com.yohoufo.order.service.support.codegenerator.impl; | ||
2 | + | ||
3 | +import lombok.Getter; | ||
4 | +import lombok.ToString; | ||
5 | +import org.slf4j.Logger; | ||
6 | +import org.slf4j.LoggerFactory; | ||
7 | +import org.springframework.stereotype.Service; | ||
8 | + | ||
9 | +/** | ||
10 | + * Created by chao.chen on 2019/3/11. | ||
11 | + */ | ||
12 | +@Service | ||
13 | +public class SequenceStrategy { | ||
14 | + private final static Logger logger = LoggerFactory.getLogger(SequenceStrategy.class); | ||
15 | + public static final long DEFAULT_SEQ = 0L; | ||
16 | + | ||
17 | + @ToString | ||
18 | + public static class SingleData{ | ||
19 | + @Getter | ||
20 | + String env; | ||
21 | + @Getter | ||
22 | + long start; | ||
23 | + private static SingleData data; | ||
24 | + static SingleData create(String env, long start){ | ||
25 | + if (data == null){ | ||
26 | + synchronized (SingleData.class){ | ||
27 | + if (data == null){ | ||
28 | + data = new SingleData(); | ||
29 | + data.env = env; | ||
30 | + data.start = start; | ||
31 | + } | ||
32 | + } | ||
33 | + } | ||
34 | + return data; | ||
35 | + } | ||
36 | + | ||
37 | + | ||
38 | + } | ||
39 | + | ||
40 | + | ||
41 | + public static SingleData getStart(){ | ||
42 | + SingleData sd = SingleData.data; | ||
43 | + logger.info("in get order code generator obtain seq Start {}", sd); | ||
44 | + return sd; | ||
45 | + } | ||
46 | + | ||
47 | + | ||
48 | + | ||
49 | +} |
order/src/main/java/com/yohoufo/order/service/support/codegenerator/populater/AtomicIdPopulator.java
@@ -3,6 +3,7 @@ package com.yohoufo.order.service.support.codegenerator.populater; | @@ -3,6 +3,7 @@ package com.yohoufo.order.service.support.codegenerator.populater; | ||
3 | 3 | ||
4 | import com.yohoufo.order.service.support.codegenerator.bean.CodeBitMeta; | 4 | import com.yohoufo.order.service.support.codegenerator.bean.CodeBitMeta; |
5 | import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta; | 5 | import com.yohoufo.order.service.support.codegenerator.bean.CodeMeta; |
6 | +import com.yohoufo.order.service.support.codegenerator.impl.SequenceStrategy; | ||
6 | import com.yohoufo.order.service.support.codegenerator.timer.SimpleTimer; | 7 | import com.yohoufo.order.service.support.codegenerator.timer.SimpleTimer; |
7 | 8 | ||
8 | import java.util.concurrent.atomic.AtomicReference; | 9 | import java.util.concurrent.atomic.AtomicReference; |
@@ -12,15 +13,25 @@ import java.util.concurrent.atomic.AtomicReference; | @@ -12,15 +13,25 @@ import java.util.concurrent.atomic.AtomicReference; | ||
12 | */ | 13 | */ |
13 | public class AtomicIdPopulator implements IdPopulator { | 14 | public class AtomicIdPopulator implements IdPopulator { |
14 | 15 | ||
15 | - class Variant { | ||
16 | - private long sequence = 0; | 16 | + public class Variant { |
17 | + private long sequence = SequenceStrategy.DEFAULT_SEQ; | ||
17 | private long lastTimestamp = -1; | 18 | private long lastTimestamp = -1; |
19 | + | ||
20 | + public Variant(long sequence) { | ||
21 | + this.sequence = sequence; | ||
22 | + } | ||
18 | } | 23 | } |
19 | 24 | ||
20 | - private AtomicReference<Variant> variant = new AtomicReference<Variant>(new Variant()); | 25 | + private AtomicReference<Variant> variant; |
21 | 26 | ||
22 | public AtomicIdPopulator() { | 27 | public AtomicIdPopulator() { |
23 | super(); | 28 | super(); |
29 | + variant = new AtomicReference<Variant>(new Variant(SequenceStrategy.DEFAULT_SEQ)); | ||
30 | + } | ||
31 | + | ||
32 | + public AtomicIdPopulator(Variant variant) { | ||
33 | + super(); | ||
34 | + this.variant = new AtomicReference<Variant>(variant==null ? new Variant(SequenceStrategy.DEFAULT_SEQ) : variant) ; | ||
24 | } | 35 | } |
25 | 36 | ||
26 | public void populateId(SimpleTimer timer, CodeMeta id, CodeBitMeta idBitMeta) { | 37 | public void populateId(SimpleTimer timer, CodeMeta id, CodeBitMeta idBitMeta) { |
@@ -45,22 +56,31 @@ public class AtomicIdPopulator implements IdPopulator { | @@ -45,22 +56,31 @@ public class AtomicIdPopulator implements IdPopulator { | ||
45 | timestamp = timer.tillNextTimeUnit(varOld.lastTimestamp); | 56 | timestamp = timer.tillNextTimeUnit(varOld.lastTimestamp); |
46 | } | 57 | } |
47 | } else { | 58 | } else { |
48 | - sequence = 0; | 59 | + sequence = getSeqStart(); |
49 | } | 60 | } |
50 | 61 | ||
51 | // Assign the current variant by the atomic tools | 62 | // Assign the current variant by the atomic tools |
52 | - varNew = new Variant(); | ||
53 | - varNew.sequence = sequence; | 63 | + varNew = new Variant(sequence); |
64 | + //varNew.sequence = sequence; | ||
54 | varNew.lastTimestamp = timestamp; | 65 | varNew.lastTimestamp = timestamp; |
55 | 66 | ||
56 | if (variant.compareAndSet(varOld, varNew)) { | 67 | if (variant.compareAndSet(varOld, varNew)) { |
57 | id.setSeq(sequence); | 68 | id.setSeq(sequence); |
58 | id.setTime(timestamp); | 69 | id.setTime(timestamp); |
59 | - | ||
60 | break; | 70 | break; |
61 | } | 71 | } |
62 | 72 | ||
63 | } | 73 | } |
64 | } | 74 | } |
65 | 75 | ||
76 | + | ||
77 | + public long getSeqStart(){ | ||
78 | + long sequence = SequenceStrategy.DEFAULT_SEQ; | ||
79 | + SequenceStrategy.SingleData sssd = SequenceStrategy.getStart(); | ||
80 | + if (sssd!=null){ | ||
81 | + sequence = sssd.getStart(); | ||
82 | + } | ||
83 | + return sequence; | ||
84 | + } | ||
85 | + | ||
66 | } | 86 | } |
-
Please register or login to post a comment