entry : paramsMap.entrySet()) {
44 | params += entry.getKey() + ":" + StringUtils.arrayToDelimitedString(entry.getValue(), ",") + ";";
45 | }
46 | }
47 | long start = System.currentTimeMillis();
48 | try {
49 | filterChain.doFilter(request, response);
50 | } catch (Throwable e) {
51 | throw e;
52 | } finally {
53 | long cost = System.currentTimeMillis() - start;
54 | logger.info("request filter path={}, cost={}, params={}", request.getServletPath(), cost, params);
55 | }
56 | }
57 |
58 | @Override
59 | public void destroy() {
60 |
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/java/com/xiaoju/uemc/tinyid/server/service/TinyIdTokenService.java:
--------------------------------------------------------------------------------
1 | package com.xiaoju.uemc.tinyid.server.service;
2 |
3 | /**
4 | * @author du_imba
5 | */
6 | public interface TinyIdTokenService {
7 | /**
8 | * 是否有权限
9 | * @param bizType
10 | * @param token
11 | * @return
12 | */
13 | boolean canVisit(String bizType, String token);
14 | }
15 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/java/com/xiaoju/uemc/tinyid/server/service/impl/DbSegmentIdServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xiaoju.uemc.tinyid.server.service.impl;
2 |
3 | import com.xiaoju.uemc.tinyid.base.entity.SegmentId;
4 | import com.xiaoju.uemc.tinyid.base.exception.TinyIdSysException;
5 | import com.xiaoju.uemc.tinyid.base.service.SegmentIdService;
6 | import com.xiaoju.uemc.tinyid.server.common.Constants;
7 | import com.xiaoju.uemc.tinyid.server.dao.TinyIdInfoDAO;
8 | import com.xiaoju.uemc.tinyid.server.dao.entity.TinyIdInfo;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Component;
13 | import org.springframework.transaction.annotation.Isolation;
14 | import org.springframework.transaction.annotation.Transactional;
15 |
16 | import java.util.concurrent.atomic.AtomicLong;
17 |
18 |
19 | /**
20 | * @author du_imba
21 | */
22 | @Component
23 | public class DbSegmentIdServiceImpl implements SegmentIdService {
24 |
25 | private static final Logger logger = LoggerFactory.getLogger(DbSegmentIdServiceImpl.class);
26 |
27 | @Autowired
28 | private TinyIdInfoDAO tinyIdInfoDAO;
29 |
30 | /**
31 | * Transactional标记保证query和update使用的是同一连接
32 | * 事务隔离级别应该为READ_COMMITTED,Spring默认是DEFAULT(取决于底层使用的数据库,mysql的默认隔离级别为REPEATABLE_READ)
33 | *
34 | * 如果是REPEATABLE_READ,那么在本次事务中循环调用tinyIdInfoDAO.queryByBizType(bizType)获取的结果是没有变化的,也就是查询不到别的事务提交的内容
35 | * 所以多次调用tinyIdInfoDAO.updateMaxId也就不会成功
36 | *
37 | * @param bizType
38 | * @return
39 | */
40 | @Override
41 | @Transactional(isolation = Isolation.READ_COMMITTED)
42 | public SegmentId getNextSegmentId(String bizType) {
43 | // 获取nextTinyId的时候,有可能存在version冲突,需要重试
44 | for (int i = 0; i < Constants.RETRY; i++) {
45 | TinyIdInfo tinyIdInfo = tinyIdInfoDAO.queryByBizType(bizType);
46 | if (tinyIdInfo == null) {
47 | throw new TinyIdSysException("can not find biztype:" + bizType);
48 | }
49 | Long newMaxId = tinyIdInfo.getMaxId() + tinyIdInfo.getStep();
50 | Long oldMaxId = tinyIdInfo.getMaxId();
51 | int row = tinyIdInfoDAO.updateMaxId(tinyIdInfo.getId(), newMaxId, oldMaxId, tinyIdInfo.getVersion(),
52 | tinyIdInfo.getBizType());
53 | if (row == 1) {
54 | tinyIdInfo.setMaxId(newMaxId);
55 | SegmentId segmentId = convert(tinyIdInfo);
56 | logger.info("getNextSegmentId success tinyIdInfo:{} current:{}", tinyIdInfo, segmentId);
57 | return segmentId;
58 | } else {
59 | logger.info("getNextSegmentId conflict tinyIdInfo:{}", tinyIdInfo);
60 | }
61 | }
62 | throw new TinyIdSysException("get next segmentId conflict");
63 | }
64 |
65 | public SegmentId convert(TinyIdInfo idInfo) {
66 | SegmentId segmentId = new SegmentId();
67 | segmentId.setCurrentId(new AtomicLong(idInfo.getMaxId() - idInfo.getStep()));
68 | segmentId.setMaxId(idInfo.getMaxId());
69 | segmentId.setRemainder(idInfo.getRemainder() == null ? 0 : idInfo.getRemainder());
70 | segmentId.setDelta(idInfo.getDelta() == null ? 1 : idInfo.getDelta());
71 | // 默认20%加载
72 | segmentId.setLoadingId(segmentId.getCurrentId().get() + idInfo.getStep() * Constants.LOADING_PERCENT / 100);
73 | return segmentId;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/java/com/xiaoju/uemc/tinyid/server/service/impl/TinyIdTokenServiceImpl.java:
--------------------------------------------------------------------------------
1 | package com.xiaoju.uemc.tinyid.server.service.impl;
2 |
3 | import com.xiaoju.uemc.tinyid.server.dao.TinyIdTokenDAO;
4 | import com.xiaoju.uemc.tinyid.server.dao.entity.TinyIdToken;
5 | import com.xiaoju.uemc.tinyid.server.service.TinyIdTokenService;
6 | import org.slf4j.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.scheduling.annotation.Scheduled;
10 | import org.springframework.stereotype.Component;
11 | import org.springframework.util.StringUtils;
12 |
13 | import javax.annotation.PostConstruct;
14 | import java.util.HashMap;
15 | import java.util.HashSet;
16 | import java.util.List;
17 | import java.util.Map;
18 | import java.util.Set;
19 |
20 | /**
21 | * @author du_imba
22 | */
23 | @Component
24 | public class TinyIdTokenServiceImpl implements TinyIdTokenService {
25 |
26 | @Autowired
27 | private TinyIdTokenDAO tinyIdTokenDAO;
28 |
29 | private static Map> token2bizTypes = new HashMap<>();
30 |
31 | private static final Logger logger = LoggerFactory.getLogger(TinyIdTokenServiceImpl.class);
32 |
33 | public List queryAll() {
34 | return tinyIdTokenDAO.selectAll();
35 | }
36 |
37 | /**
38 | * 1分钟刷新一次token
39 | */
40 | @Scheduled(cron = "0 0/1 * * * ?")
41 | public void refresh() {
42 | logger.info("refresh token begin");
43 | init();
44 | }
45 |
46 | @PostConstruct
47 | private synchronized void init() {
48 | logger.info("tinyId token init begin");
49 | List list = queryAll();
50 | Map> map = converToMap(list);
51 | token2bizTypes = map;
52 | logger.info("tinyId token init success, token size:{}", list == null ? 0 : list.size());
53 | }
54 |
55 | @Override
56 | public boolean canVisit(String bizType, String token) {
57 | if (StringUtils.isEmpty(bizType) || StringUtils.isEmpty(token)) {
58 | return false;
59 | }
60 | Set bizTypes = token2bizTypes.get(token);
61 | return (bizTypes != null && bizTypes.contains(bizType));
62 | }
63 |
64 | public Map> converToMap(List list) {
65 | Map> map = new HashMap<>(64);
66 | if (list != null) {
67 | for (TinyIdToken tinyIdToken : list) {
68 | if (!map.containsKey(tinyIdToken.getToken())) {
69 | map.put(tinyIdToken.getToken(), new HashSet());
70 | }
71 | map.get(tinyIdToken.getToken()).add(tinyIdToken.getBizType());
72 | }
73 | }
74 | return map;
75 | }
76 |
77 | }
78 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/java/com/xiaoju/uemc/tinyid/server/vo/ErrorCode.java:
--------------------------------------------------------------------------------
1 | package com.xiaoju.uemc.tinyid.server.vo;
2 |
3 | /**
4 | * @author du_imba
5 | */
6 | public enum ErrorCode {
7 | /**
8 | * token is wrong
9 | */
10 | TOKEN_ERR(5, "token is error"),
11 | /**
12 | * server internal error
13 | */
14 | SYS_ERR(6, "sys error");
15 |
16 | private Integer code;
17 | private String message;
18 |
19 | ErrorCode(Integer code, String message) {
20 | this.code = code;
21 | this.message = message;
22 | }
23 |
24 | public Integer getCode() {
25 | return code;
26 | }
27 |
28 |
29 | public String getMessage() {
30 | return message;
31 | }
32 |
33 | }
34 |
35 |
36 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/java/com/xiaoju/uemc/tinyid/server/vo/Response.java:
--------------------------------------------------------------------------------
1 | package com.xiaoju.uemc.tinyid.server.vo;
2 |
3 | /**
4 | * @author du_imba
5 | */
6 | public class Response {
7 | private T data;
8 | private Integer code = 200;
9 | private String message = "";
10 |
11 | public static final int SYS_ERROR = 500;
12 |
13 | public T getData() {
14 | return data;
15 | }
16 |
17 | public void setData(T data) {
18 | this.data = data;
19 | }
20 |
21 | public Integer getCode() {
22 | return code;
23 | }
24 |
25 | public void setCode(Integer code) {
26 | this.code = code;
27 | }
28 |
29 | public String getMessage() {
30 | return message;
31 | }
32 |
33 | public void setMessage(String message) {
34 | this.message = message;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/resources/offline/application.properties:
--------------------------------------------------------------------------------
1 | server.port=9999
2 | server.context-path=/tinyid
3 |
4 | batch.size.max=100000
5 |
6 | datasource.tinyid.names=primary
7 | #datasource.tinyid.names=primary,secondary
8 | datasource.tinyid.type=org.apache.tomcat.jdbc.pool.DataSource
9 |
10 | datasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver
11 | datasource.tinyid.primary.url=jdbc:mysql://localhost:3306/db1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
12 | datasource.tinyid.primary.username=root
13 | datasource.tinyid.primary.password=123456
14 | #datasource.tinyid.primary.testOnBorrow=false
15 | #datasource.tinyid.primary.maxActive=10
16 |
17 | #datasource.tinyid.secondary.driver-class-name=com.mysql.jdbc.Driver
18 | #datasource.tinyid.secondary.url=jdbc:mysql://localhost:3306/db2?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
19 | #datasource.tinyid.secondary.username=root
20 | #datasource.tinyid.secondary.password=123456
21 | #datasource.tinyid.secondary.testOnBorrow=false
22 | #datasource.tinyid.secondary.maxActive=10
23 |
24 |
25 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/resources/offline/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ./logs/
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/resources/online/application.properties:
--------------------------------------------------------------------------------
1 | #online
2 | server.port=9999
3 | server.context-path=/tinyid
4 |
5 | batch.size.max=100000
6 |
7 | datasource.tinyid.names=primary
8 | #datasource.tinyid.names=primary,secondary
9 |
10 | datasource.tinyid.primary.driver-class-name=com.mysql.jdbc.Driver
11 | datasource.tinyid.primary.url=jdbc:mysql://localhost:3306/db1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
12 | datasource.tinyid.primary.username=root
13 | datasource.tinyid.primary.password=123456
14 |
15 | #datasource.tinyid.secondary.driver-class-name=com.mysql.jdbc.Driver
16 | #datasource.tinyid.secondary.url=jdbc:mysql://localhost:3306/db2?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
17 | #datasource.tinyid.secondary.username=root
18 | #datasource.tinyid.secondary.password=123456
19 |
--------------------------------------------------------------------------------
/tinyid-server/src/main/resources/online/log4j2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | /home/xiaoju/tinyid-server/logs/
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/tinyid-server/src/test/java/com/xiaoju/uemc/tinyid/server/ServerTest.java:
--------------------------------------------------------------------------------
1 | package com.xiaoju.uemc.tinyid.server;
2 |
3 | import com.xiaoju.uemc.tinyid.base.generator.IdGenerator;
4 | import com.xiaoju.uemc.tinyid.server.factory.impl.IdGeneratorFactoryServer;
5 | import org.junit.Test;
6 | import org.junit.runner.RunWith;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.boot.test.context.SpringBootTest;
9 | import org.springframework.test.context.junit4.SpringRunner;
10 |
11 | /**
12 | * @Author du_imba
13 | */
14 | @RunWith(SpringRunner.class)
15 | @SpringBootTest
16 | public class ServerTest {
17 |
18 | @Autowired
19 | IdGeneratorFactoryServer idGeneratorFactoryServer;
20 |
21 | @Test
22 | public void testNextId() {
23 | IdGenerator idGenerator = idGeneratorFactoryServer.getIdGenerator("test");
24 | Long id = idGenerator.nextId();
25 | System.out.println("current id is: " + id);
26 | }
27 | }
28 |
--------------------------------------------------------------------------------