Commit 3ab6e756 authored by shengnan hu's avatar shengnan hu
Browse files

init

parents
Pipeline #294 passed with stage
in 2 minutes and 13 seconds
package com.mall4j.cloud.leaf;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author leaf
*/
@SpringBootApplication(scanBasePackages = { "com.mall4j.cloud" })
@EnableFeignClients(basePackages = {"com.mall4j.cloud.api.**.feign"})
public class LeafServerApplication {
public static void main(String[] args) {
SpringApplication.run(LeafServerApplication.class, args);
}
}
package com.mall4j.cloud.leaf.common;
/**
* @author leaf
*/
public class Result {
private long id;
private Status status;
public Result() {
}
public Result(long id, Status status) {
this.id = id;
this.status = status;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
@Override
public String toString() {
return "Result{" + "id=" + id +
", status=" + status +
'}';
}
}
package com.mall4j.cloud.leaf.common;
/**
* @author leaf
*/
public enum Status {
/**
* success
*/
SUCCESS,
/**
* exception
*/
EXCEPTION
}
package com.mall4j.cloud.leaf.common;
import com.mall4j.cloud.leaf.IDGen;
/**
* @author left
*/
public class ZeroIDGen implements IDGen {
@Override
public Result get(String key) {
return new Result(0, Status.SUCCESS);
}
@Override
public boolean init() {
return true;
}
}
package com.mall4j.cloud.leaf.exception;
/**
* @author leaf
*/
public class InitException extends Exception {
public InitException(String msg) {
super(msg);
}
}
package com.mall4j.cloud.leaf.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @author leaf
*/
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR)
public class LeafServerException extends RuntimeException {
public LeafServerException(String msg) {
super(msg);
}
}
package com.mall4j.cloud.leaf.exception;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
/**
* @author leaf
*/
@ResponseStatus(code = HttpStatus.INTERNAL_SERVER_ERROR, reason = "Key is none")
public class NoKeyException extends RuntimeException {
}
package com.mall4j.cloud.leaf.feign;
import com.mall4j.cloud.api.leaf.feign.SegmentFeignClient;
import com.mall4j.cloud.common.response.ServerResponseEntity;
import com.mall4j.cloud.leaf.common.Result;
import com.mall4j.cloud.leaf.common.Status;
import com.mall4j.cloud.leaf.exception.LeafServerException;
import com.mall4j.cloud.leaf.exception.NoKeyException;
import com.mall4j.cloud.leaf.service.SegmentService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
/**
* @author FrozenWatermelon
* @date 2020/7/15
*/
@RestController
public class SegmentFeignController implements SegmentFeignClient {
private static final Logger logger = LoggerFactory.getLogger(SegmentFeignController.class);
@Autowired
private SegmentService segmentService;
@Override
public ServerResponseEntity<Long> getSegmentId(String key) {
return ServerResponseEntity.success(get(key, segmentService.getId(key)));
}
private Long get(String key, Result id) {
Result result;
if (key == null || key.isEmpty()) {
throw new NoKeyException();
}
result = id;
if (Objects.equals(result.getStatus(), Status.EXCEPTION)) {
throw new LeafServerException(result.toString());
}
return result.getId();
}
}
package com.mall4j.cloud.leaf.segment;
import com.mall4j.cloud.leaf.IDGen;
import com.mall4j.cloud.leaf.common.Result;
import com.mall4j.cloud.leaf.common.Status;
import com.mall4j.cloud.leaf.segment.dao.IDAllocDao;
import com.mall4j.cloud.leaf.segment.model.LeafAlloc;
import com.mall4j.cloud.leaf.segment.model.Segment;
import com.mall4j.cloud.leaf.segment.model.SegmentBuffer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.SecureRandom;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author leaf
*/
public class SegmentIDGenImpl implements IDGen {
private static final Logger logger = LoggerFactory.getLogger(SegmentIDGenImpl.class);
/**
* IDCache未初始化成功时的异常码
*/
private static final long EXCEPTION_ID_IDCACHE_INIT_FALSE = -1;
/**
* key不存在时的异常码
*/
private static final long EXCEPTION_ID_KEY_NOT_EXISTS = -2;
/**
* SegmentBuffer中的两个Segment均未从DB中装载时的异常码
*/
private static final long EXCEPTION_ID_TWO_SEGMENTS_ARE_NULL = -3;
/**
* 最大步长不超过100,0000
*/
private static final int MAX_STEP = 1000000;
/**
* 一个Segment维持时间为15分钟
*/
private static final long SEGMENT_DURATION = 15 * 60 * 1000L;
private final ExecutorService service = new ThreadPoolExecutor(5, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS,
new SynchronousQueue<>(), new UpdateThreadFactory());
private volatile boolean initOk = false;
private final Map<String, SegmentBuffer> cache = new ConcurrentHashMap<>();
private IDAllocDao dao;
private static final SecureRandom RANDOM = new SecureRandom();
private static final int DEFAULT_LOAD_FACTOR = 2;
public static class UpdateThreadFactory implements ThreadFactory {
private static int threadInitNumber = 0;
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Thread-Segment-Update-" + nextThreadNum());
}
}
@Override
public boolean init() {
logger.info("Init ...");
// 确保加载到kv后才初始化成功
updateCacheFromDb();
initOk = true;
updateCacheFromDbAtEveryMinute();
return initOk;
}
private void updateCacheFromDbAtEveryMinute() {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("check-idCache-thread");
t.setDaemon(true);
return t;
}
});
service.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
updateCacheFromDb();
}
}, 60, 60, TimeUnit.SECONDS);
}
private void updateCacheFromDb() {
logger.info("update cache from db");
try {
List<String> dbTags = dao.getAllTags();
if (dbTags == null || dbTags.isEmpty()) {
return;
}
List<String> cacheTags = new ArrayList<String>(cache.keySet());
Set<String> insertTagsSet = new HashSet<>(dbTags);
Set<String> removeTagsSet = new HashSet<>(cacheTags);
// db中新加的tags灌进cache
for (int i = 0; i < cacheTags.size(); i++) {
String tmp = cacheTags.get(i);
insertTagsSet.remove(tmp);
}
for (String tag : insertTagsSet) {
SegmentBuffer buffer = new SegmentBuffer();
buffer.setKey(tag);
Segment segment = buffer.getCurrent();
segment.setValue(new AtomicLong(0));
segment.setMax(0);
segment.setStep(0);
cache.put(tag, buffer);
logger.info("Add tag {} from db to IdCache, SegmentBuffer {}", tag, buffer);
}
// cache中已失效的tags从cache删除
for (int i = 0; i < dbTags.size(); i++) {
String tmp = dbTags.get(i);
removeTagsSet.remove(tmp);
}
for (String tag : removeTagsSet) {
cache.remove(tag);
logger.info("Remove tag {} from IdCache", tag);
}
}
catch (Exception e) {
logger.warn("update cache from db exception", e);
}
}
@Override
public Result get(final String key) {
if (!initOk) {
return new Result(EXCEPTION_ID_IDCACHE_INIT_FALSE, Status.EXCEPTION);
}
SegmentBuffer buffer = cache.get(key);
if (buffer != null) {
if (buffer.isInitOk()) {
synchronized (buffer) {
if (buffer.isInitOk()) {
try {
updateSegmentFromDb(key, buffer.getCurrent());
logger.info("Init buffer. Update leafkey {} {} from db", key, buffer.getCurrent());
buffer.setInitOk(true);
}
catch (Exception e) {
logger.warn("Init buffer {} exception", buffer.getCurrent(), e);
}
}
}
}
return getIdFromSegmentBuffer(cache.get(key));
}
return new Result(EXCEPTION_ID_KEY_NOT_EXISTS, Status.EXCEPTION);
}
public void updateSegmentFromDb(String key, Segment segment) {
SegmentBuffer buffer = segment.getBuffer();
LeafAlloc leafAlloc;
if (buffer.isInitOk()) {
leafAlloc = dao.updateMaxIdAndGetLeafAlloc(key);
buffer.setStep(leafAlloc.getStep());
// leafAlloc中的step为DB中的step
buffer.setMinStep(leafAlloc.getStep());
}
else if (buffer.getUpdateTimestamp() == 0) {
leafAlloc = dao.updateMaxIdAndGetLeafAlloc(key);
buffer.setUpdateTimestamp(System.currentTimeMillis());
buffer.setStep(leafAlloc.getStep());
// leafAlloc中的step为DB中的step
buffer.setMinStep(leafAlloc.getStep());
}
else {
long duration = System.currentTimeMillis() - buffer.getUpdateTimestamp();
int nextStep = buffer.getStep();
if (duration < SEGMENT_DURATION) {
if (nextStep * DEFAULT_LOAD_FACTOR > MAX_STEP) {
// do nothing
}
else {
nextStep = nextStep * DEFAULT_LOAD_FACTOR;
}
}
else if (duration < SEGMENT_DURATION * DEFAULT_LOAD_FACTOR) {
// do nothing with nextStep
}
else {
nextStep = nextStep / DEFAULT_LOAD_FACTOR >= buffer.getMinStep() ? nextStep / DEFAULT_LOAD_FACTOR
: nextStep;
}
logger.info("leafKey[{}], step[{}], duration[{}mins], nextStep[{}]", key, buffer.getStep(),
String.format("%.2f", ((double) duration / (1000 * 60))), nextStep);
LeafAlloc temp = new LeafAlloc();
temp.setKey(key);
temp.setStep(nextStep);
leafAlloc = dao.updateMaxIdByCustomStepAndGetLeafAlloc(temp);
buffer.setUpdateTimestamp(System.currentTimeMillis());
buffer.setStep(nextStep);
// leafAlloc的step为DB中的step
buffer.setMinStep(leafAlloc.getStep());
}
// must set value before set max
long value = leafAlloc.getMaxId() - buffer.getStep();
segment.getValue().set(value);
segment.setMax(leafAlloc.getMaxId());
segment.setStep(buffer.getStep());
segment.setRandomStep(leafAlloc.getRandomStep());
}
public Result getIdFromSegmentBuffer(final SegmentBuffer buffer) {
while (true) {
buffer.rLock().lock();
try {
final Segment segment = buffer.getCurrent();
if (!buffer.isNextReady() && (segment.getIdle() < 0.9 * segment.getStep())
&& buffer.getThreadRunning().compareAndSet(false, true)) {
service.execute(new Runnable() {
@Override
public void run() {
Segment next = buffer.getSegments()[buffer.nextPos()];
boolean updateOk = false;
try {
updateSegmentFromDb(buffer.getKey(), next);
updateOk = true;
logger.info("update segment {} from db {}", buffer.getKey(), next);
}
catch (Exception e) {
logger.warn(buffer.getKey() + " updateSegmentFromDb exception", e);
}
finally {
if (updateOk) {
buffer.wLock().lock();
buffer.setNextReady(true);
buffer.getThreadRunning().set(false);
buffer.wLock().unlock();
}
else {
buffer.getThreadRunning().set(false);
}
}
}
});
}
long value;
if (segment.getRandomStep() > 1) {
// 随机从1-10里面增加
value = segment.getValue().getAndAdd(randomAdd(segment.getRandomStep()));
}
else {
value = segment.getValue().getAndIncrement();
}
if (value < segment.getMax()) {
return new Result(value, Status.SUCCESS);
}
}
finally {
buffer.rLock().unlock();
}
waitAndSleep(buffer);
buffer.wLock().lock();
try {
final Segment segment = buffer.getCurrent();
long value = segment.getValue().getAndIncrement();
if (value < segment.getMax()) {
return new Result(value, Status.SUCCESS);
}
if (buffer.isNextReady()) {
buffer.switchPos();
buffer.setNextReady(false);
}
else {
logger.error("Both two segments in {} are not ready!", buffer);
return new Result(EXCEPTION_ID_TWO_SEGMENTS_ARE_NULL, Status.EXCEPTION);
}
}
finally {
buffer.wLock().unlock();
}
}
}
private int randomAdd(int randomStep) {
return RANDOM.nextInt(randomStep - 1) + 1;
}
private void waitAndSleep(SegmentBuffer buffer) {
int roll = 0;
while (buffer.getThreadRunning().get()) {
roll += 1;
if (roll > 10000) {
try {
TimeUnit.MILLISECONDS.sleep(10);
break;
}
catch (InterruptedException e) {
logger.warn("Thread {} Interrupted, Exception: {}", Thread.currentThread().getName(), e);
break;
}
}
}
}
public List<LeafAlloc> getAllLeafAllocs() {
return dao.getAllLeafAllocs();
}
public Map<String, SegmentBuffer> getCache() {
return cache;
}
public IDAllocDao getDao() {
return dao;
}
public void setDao(IDAllocDao dao) {
this.dao = dao;
}
}
package com.mall4j.cloud.leaf.segment.dao;
import com.mall4j.cloud.leaf.segment.model.LeafAlloc;
import java.util.List;
/**
* @author leaf
*/
public interface IDAllocDao {
/**
* com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.getAllLeafAllocs
* @return List<LeafAlloc>
*/
List<LeafAlloc> getAllLeafAllocs();
/**
* updateMaxIdAndGetLeafAlloc
* @param tag tag
* @return LeafAlloc
*/
LeafAlloc updateMaxIdAndGetLeafAlloc(String tag);
/**
* updateMaxIdByCustomStepAndGetLeafAlloc
* @param leafAlloc leafAlloc
* @return LeafAlloc
*/
LeafAlloc updateMaxIdByCustomStepAndGetLeafAlloc(LeafAlloc leafAlloc);
/**
* getAllTags
* @return List<String>
*/
List<String> getAllTags();
}
package com.mall4j.cloud.leaf.segment.dao;
import com.mall4j.cloud.leaf.segment.model.LeafAlloc;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author leaf
*/
public interface IDAllocMapper {
/**
* getAllLeafAllocs
* @return List<LeafAlloc>
*/
@Select("SELECT biz_tag, max_id, step, update_time FROM leaf_alloc")
@Results(value = { @Result(column = "biz_tag", property = "key"), @Result(column = "max_id", property = "maxId"),
@Result(column = "step", property = "step"), @Result(column = "update_time", property = "updateTime") })
List<LeafAlloc> getAllLeafAllocs();
/**
* getLeafAlloc
* @param tag tag
* @return LeafAlloc
*/
@Select("SELECT biz_tag, max_id, step, random_step FROM leaf_alloc WHERE biz_tag = #{tag}")
@Results(value = { @Result(column = "biz_tag", property = "key"), @Result(column = "max_id", property = "maxId"),
@Result(column = "step", property = "step"), @Result(column = "random_step", property = "randomStep") })
LeafAlloc getLeafAlloc(@Param("tag") String tag);
/**
* updateMaxId
* @param tag tag
*/
@Update("UPDATE leaf_alloc SET max_id = max_id + step WHERE biz_tag = #{tag}")
void updateMaxId(@Param("tag") String tag);
/**
* updateMaxIdByCustomStep
* @param leafAlloc leafAlloc
*/
@Update("UPDATE leaf_alloc SET max_id = max_id + #{step} WHERE biz_tag = #{key}")
void updateMaxIdByCustomStep(@Param("leafAlloc") LeafAlloc leafAlloc);
/**
* getAllTags
* @return List<String>
*/
@Select("SELECT biz_tag FROM leaf_alloc")
List<String> getAllTags();
}
package com.mall4j.cloud.leaf.segment.dao.impl;
import com.mall4j.cloud.leaf.segment.dao.IDAllocDao;
import com.mall4j.cloud.leaf.segment.dao.IDAllocMapper;
import com.mall4j.cloud.leaf.segment.model.LeafAlloc;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import javax.sql.DataSource;
import java.util.List;
/**
* @author leaf
*/
public class IDAllocDaoImpl implements IDAllocDao {
final SqlSessionFactory sqlSessionFactory;
public IDAllocDaoImpl(DataSource dataSource) {
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(IDAllocMapper.class);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
}
@Override
public List<LeafAlloc> getAllLeafAllocs() {
try (SqlSession sqlSession = sqlSessionFactory.openSession(false)) {
return sqlSession.selectList("com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.getAllLeafAllocs");
}
}
@Override
public LeafAlloc updateMaxIdAndGetLeafAlloc(String tag) {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
sqlSession.update("com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.updateMaxId", tag);
LeafAlloc result = sqlSession.selectOne("com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.getLeafAlloc", tag);
sqlSession.commit();
return result;
}
}
@Override
public LeafAlloc updateMaxIdByCustomStepAndGetLeafAlloc(LeafAlloc leafAlloc) {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
sqlSession.update("com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.updateMaxIdByCustomStep", leafAlloc);
LeafAlloc result = sqlSession.selectOne("com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.getLeafAlloc",
leafAlloc.getKey());
sqlSession.commit();
return result;
}
}
@Override
public List<String> getAllTags() {
try (SqlSession sqlSession = sqlSessionFactory.openSession(false)) {
return sqlSession.selectList("com.mall4j.cloud.leaf.segment.dao.IDAllocMapper.getAllTags");
}
}
}
package com.mall4j.cloud.leaf.segment.model;
/**
* @author leaf
*/
public class LeafAlloc {
private String key;
private long maxId;
private int step;
private String updateTime;
private int randomStep;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public long getMaxId() {
return maxId;
}
public void setMaxId(long maxId) {
this.maxId = maxId;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public String getUpdateTime() {
return updateTime;
}
public void setUpdateTime(String updateTime) {
this.updateTime = updateTime;
}
public int getRandomStep() {
return randomStep;
}
public void setRandomStep(int randomStep) {
this.randomStep = randomStep;
}
}
package com.mall4j.cloud.leaf.segment.model;
import java.util.concurrent.atomic.AtomicLong;
/**
* @author left
*/
public class Segment {
private AtomicLong value = new AtomicLong(0);
private volatile long max;
private volatile int step;
private volatile int randomStep;
private final SegmentBuffer buffer;
public Segment(SegmentBuffer buffer) {
this.buffer = buffer;
}
public AtomicLong getValue() {
return value;
}
public void setValue(AtomicLong value) {
this.value = value;
}
public long getMax() {
return max;
}
public void setMax(long max) {
this.max = max;
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public SegmentBuffer getBuffer() {
return buffer;
}
public long getIdle() {
return this.getMax() - getValue().get();
}
@Override
public String toString() {
return "Segment(" + "value:" +
value +
",max:" +
max +
",step:" +
step +
")";
}
public int getRandomStep() {
return randomStep;
}
public void setRandomStep(int randomStep) {
this.randomStep = randomStep;
}
}
package com.mall4j.cloud.leaf.segment.model;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 双buffer
*
* @author left
*/
public class SegmentBuffer {
private String key;
/**
* 双buffer
*/
private final Segment[] segments;
/**
* 当前的使用的segment的index
*/
private volatile int currentPos;
/**
* 下一个segment是否处于可切换状态
*/
private volatile boolean nextReady;
/**
* 是否初始化完成
*/
private volatile boolean initOk;
/**
* 线程是否在运行中
*/
private final AtomicBoolean threadRunning;
private final ReadWriteLock lock;
private volatile int step;
private volatile int minStep;
private volatile long updateTimestamp;
public SegmentBuffer() {
segments = new Segment[] { new Segment(this), new Segment(this) };
currentPos = 0;
nextReady = false;
initOk = false;
threadRunning = new AtomicBoolean(false);
lock = new ReentrantReadWriteLock();
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Segment[] getSegments() {
return segments;
}
public Segment getCurrent() {
return segments[currentPos];
}
public int getCurrentPos() {
return currentPos;
}
public int nextPos() {
return (currentPos + 1) % 2;
}
public void switchPos() {
currentPos = nextPos();
}
public boolean isInitOk() {
return !initOk;
}
public void setInitOk(boolean initOk) {
this.initOk = initOk;
}
public boolean isNextReady() {
return nextReady;
}
public void setNextReady(boolean nextReady) {
this.nextReady = nextReady;
}
public AtomicBoolean getThreadRunning() {
return threadRunning;
}
public Lock rLock() {
return lock.readLock();
}
public Lock wLock() {
return lock.writeLock();
}
public int getStep() {
return step;
}
public void setStep(int step) {
this.step = step;
}
public int getMinStep() {
return minStep;
}
public void setMinStep(int minStep) {
this.minStep = minStep;
}
public long getUpdateTimestamp() {
return updateTimestamp;
}
public void setUpdateTimestamp(long updateTimestamp) {
this.updateTimestamp = updateTimestamp;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("SegmentBuffer{");
sb.append("key='").append(key).append('\'');
sb.append(", segments=").append(Arrays.toString(segments));
sb.append(", currentPos=").append(currentPos);
sb.append(", nextReady=").append(nextReady);
sb.append(", initOk=").append(initOk);
sb.append(", threadRunning=").append(threadRunning);
sb.append(", step=").append(step);
sb.append(", minStep=").append(minStep);
sb.append(", updateTimestamp=").append(updateTimestamp);
sb.append('}');
return sb.toString();
}
}
package com.mall4j.cloud.leaf.service;
import com.mall4j.cloud.leaf.IDGen;
import com.mall4j.cloud.leaf.common.Result;
import com.mall4j.cloud.leaf.exception.InitException;
import com.mall4j.cloud.leaf.segment.SegmentIDGenImpl;
import com.mall4j.cloud.leaf.segment.dao.IDAllocDao;
import com.mall4j.cloud.leaf.segment.dao.impl.IDAllocDaoImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
/**
* @author left
*/
@Service("SegmentService")
public class SegmentService {
private final Logger logger = LoggerFactory.getLogger(SegmentService.class);
private final IDGen idGen;
public SegmentService(DataSource dataSource) throws InitException {
// Config Dao
IDAllocDao dao = new IDAllocDaoImpl(dataSource);
// Config ID Gen
idGen = new SegmentIDGenImpl();
((SegmentIDGenImpl) idGen).setDao(dao);
if (idGen.init()) {
logger.info("Segment Service Init Successfully");
}
else {
throw new InitException("Segment Service Init Fail");
}
}
public Result getId(String key) {
return idGen.get(key);
}
public SegmentIDGenImpl getIdGen() {
if (idGen instanceof SegmentIDGenImpl) {
return (SegmentIDGenImpl) idGen;
}
return null;
}
}
server:
port: 9100
spring:
application:
name: @artifactId@
cloud:
nacos:
discovery:
server-addr: ${NACOS_HOST:192.168.1.46}:${NACOS_PORT:8848}
username: nacos
password: nacos
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
namespace: @nacos.namespace@
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
username: ${spring.cloud.nacos.discovery.username}
password: ${spring.cloud.nacos.discovery.password}
profiles:
active: @profiles.active@
server:
port: 9100
spring:
application:
name: mall4cloud-leaf
cloud:
nacos:
discovery:
server-addr: ${NACOS_HOST:192.168.1.46}:${NACOS_PORT:8848}
username: nacos
password: nacos
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
namespace:
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
username: ${spring.cloud.nacos.discovery.username}
password: ${spring.cloud.nacos.discovery.password}
profiles:
active: dev
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment