java发号器_分布式发号器的三种同步实现方式

先定义一个发号器接口

package com.robert.vesta.service.intf;

import com.robert.vesta.service.bean.Id;

import java.util.Date;

public interface IdService {

/**

* 发号器的主要API,用来产生唯一ID

* @return

*/

public long genId();

/**

* 解读ID,人可识别

* @param id

* @return

*/

public Id expId(long id);

/**

* 用来伪造某一时间的ID

* @param time

* @param seq

* @return

*/

public long makeId(long time, long seq);

public long makeId(long time, long seq, long machine);

public long makeId(long genMethod, long time, long seq, long machine);

public long makeId(long type, long genMethod, long time,

long seq, long machine);

public long makeId(long version, long type, long genMethod,

long time, long seq, long machine);

/**

* 将整形时间翻译成格式化时间

* @param time

* @return

*/

public Date transTime(long time);

}

因为有3种同步方式,先给一个抽象类,实现共性.分布式ID由机器号+生产方式+版本号+实现号+时间戳+流水号组成

package com.robert.vesta.service.impl;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdMeta;

import com.robert.vesta.service.impl.bean.IdMetaFactory;

import com.robert.vesta.service.impl.bean.IdType;

import com.robert.vesta.service.impl.converter.IdConverter;

import com.robert.vesta.service.impl.converter.IdConverterImpl;

import com.robert.vesta.service.impl.provider.MachineIdProvider;

import com.robert.vesta.service.impl.timer.SimpleTimer;

import com.robert.vesta.service.impl.timer.Timer;

import com.robert.vesta.service.intf.IdService;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import java.util.Date;

public abstract class AbstractIdServiceImpl implements IdService {

protected final Logger log = LoggerFactory.getLogger(this.getClass());

/**

* 机器ID

*/

protected long machineId = -1;

/**

* 生产方式

*/

protected long genMethod = 0;

/**

* 版本

*/

protected long version = 0;

/**

* 实现类型

*/

protected IdType idType;

/**

* ID元数据

*/

protected IdMeta idMeta;

/**

* 元数据,长整型转换器

*/

protected IdConverter idConverter;

/**

* 机器ID生成器

*/

protected MachineIdProvider machineIdProvider;

/**

* 时间处理类

*/

protected Timer timer;

public AbstractIdServiceImpl() {

idType = IdType.SECONDS;

}

public AbstractIdServiceImpl(String type) {

idType = IdType.parse(type);

}

public AbstractIdServiceImpl(long type) {

idType = IdType.parse(type);

}

public AbstractIdServiceImpl(IdType type) {

idType = type;

}

/**

* 实现共有属性

*/

public void init() {

if (this.idMeta == null) {

setIdMeta(IdMetaFactory.getIdMeta(idType));

}

if (this.idConverter == null) {

setIdConverter(new IdConverterImpl());

}

if (this.timer == null) {

setTimer(new SimpleTimer());

}

this.timer.init(idMeta, idType);

this.machineId = machineIdProvider.getMachineId();

validateMachineId(this.machineId);

}

/**

* 生成ID

* @return

*/

public long genId() {

Id id = new Id();

id.setMachine(machineId);

id.setGenMethod(genMethod);

id.setType(idType.value());

id.setVersion(version);

//抽象方法,由子类各自实现,意思就是由不同的方法进行同步

populateId(id);

long ret = idConverter.convert(id, this.idMeta);

// Use trace because it cause low performance

if (log.isTraceEnabled())

log.trace(String.format("Id: %s => %d", id, ret));

return ret;

}

public void validateMachineId(long machineId){

if (machineId < 0) {

log.error("The machine ID is not configured properly (" + machineId + " < 0) so that Vesta Service refuses to start.");

throw new IllegalStateException(

"The machine ID is not configured properly (" + machineId + " < 0) so that Vesta Service refuses to start.");

} else if (machineId >= (1 << this.idMeta.getMachineBits())) {

log.error("The machine ID is not configured properly ("

+ machineId + " >= " + (1 << this.idMeta.getMachineBits()) + ") so that Vesta Service refuses to start.");

throw new IllegalStateException("The machine ID is not configured properly ("

+ machineId + " >= " + (1 << this.idMeta.getMachineBits()) + ") so that Vesta Service refuses to start.");

}

}

protected abstract void populateId(Id id);

public Date transTime(final long time) {

return timer.transTime(time);

}

public Id expId(long id) {

return idConverter.convert(id, this.idMeta);

}

public long makeId(long time, long seq) {

return makeId(time, seq, machineId);

}

public long makeId(long time, long seq, long machine) {

return makeId(genMethod, time, seq, machine);

}

public long makeId(long genMethod, long time, long seq, long machine) {

return makeId(idType.value(), genMethod, time, seq, machine);

}

public long makeId(long type, long genMethod, long time,

long seq, long machine) {

return makeId(version, type, genMethod, time, seq, machine);

}

public long makeId(long version, long type, long genMethod,

long time, long seq, long machine) {

Id id = new Id(machine, seq, time, genMethod, type, version);

return idConverter.convert(id, this.idMeta);

}

public void setMachineId(long machineId) {

this.machineId = machineId;

}

public void setGenMethod(long genMethod) {

this.genMethod = genMethod;

}

public void setVersion(long version) {

this.version = version;

}

public void setIdConverter(IdConverter idConverter) {

this.idConverter = idConverter;

}

public void setIdMeta(IdMeta idMeta) {

this.idMeta = idMeta;

}

public void setMachineIdProvider(MachineIdProvider machineIdProvider) {

this.machineIdProvider = machineIdProvider;

}

public void setTimer(Timer timer) {

this.timer = timer;

}

}

实现类,再根据不同的参数进行不同的调用

package com.robert.vesta.service.impl;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdType;

import com.robert.vesta.service.impl.populater.AtomicIdPopulator;

import com.robert.vesta.service.impl.populater.IdPopulator;

import com.robert.vesta.service.impl.populater.LockIdPopulator;

import com.robert.vesta.service.impl.populater.SyncIdPopulator;

import com.robert.vesta.util.CommonUtils;

public class IdServiceImpl extends AbstractIdServiceImpl {

/**

* 同步锁

*/

private static final String SYNC_LOCK_IMPL_KEY = "vesta.sync.lock.impl.key";

/**

* 无锁

*/

private static final String ATOMIC_IMPL_KEY = "vesta.atomic.impl.key";

protected IdPopulator idPopulator;

public IdServiceImpl() {

super();

}

public IdServiceImpl(String type) {

super(type);

}

public IdServiceImpl(long type) {

super(type);

}

public IdServiceImpl(IdType type) {

super(type);

}

@Override

public void init() {

super.init();

initPopulator();

}

/**

* 根据不同的方式调用不同的同步机制

*/

public void initPopulator() {

if (idPopulator != null){

log.info("The " + idPopulator.getClass().getCanonicalName() + " is used.");

} else if (CommonUtils.isPropKeyOn(SYNC_LOCK_IMPL_KEY)) {

log.info("The SyncIdPopulator is used.");

idPopulator = new SyncIdPopulator();

} else if (CommonUtils.isPropKeyOn(ATOMIC_IMPL_KEY)) {

log.info("The AtomicIdPopulator is used.");

idPopulator = new AtomicIdPopulator();

} else {

log.info("The default LockIdPopulator is used.");

idPopulator = new LockIdPopulator();

}

}

protected void populateId(Id id) {

idPopulator.populateId(timer, id, idMeta);

}

public void setIdPopulator(IdPopulator idPopulator) {

this.idPopulator = idPopulator;

}

}

因为无锁跟重入锁或者synchronized不同,所以会有接口,一个抽象类

package com.robert.vesta.service.impl.populater;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdMeta;

import com.robert.vesta.service.impl.timer.Timer;

public interface IdPopulator {

/**

* 同秒内产生流水号

* @param timer

* @param id

* @param idMeta

*/

void populateId(Timer timer, Id id, IdMeta idMeta);

/**

* 不同秒内重置

*/

void reset();

}

package com.robert.vesta.service.impl.populater;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdMeta;

import com.robert.vesta.service.impl.timer.Timer;

public abstract class BasePopulator implements IdPopulator {

/**

* 流水号

*/

protected long sequence = 0;

/**

* 上一次的时间

*/

protected long lastTimestamp = -1;

public BasePopulator() {

super();

}

/**

* 产生流水ID的算法

* @param timer

* @param id

* @param idMeta

*/

public void populateId(Timer timer, Id id, IdMeta idMeta) {

long timestamp = timer.genTime();

timer.validateTimestamp(lastTimestamp, timestamp);

if (timestamp == lastTimestamp) {

sequence++;

sequence &= idMeta.getSeqBitsMask();

if (sequence == 0) {

timestamp = timer.tillNextTimeUnit(lastTimestamp);

}

} else {

lastTimestamp = timestamp;

sequence = 0;

}

id.setSeq(sequence);

id.setTime(timestamp);

}

public void reset() {

this.sequence = 0;

this.lastTimestamp = -1;

}

}

其实前面只是铺垫------------------------------

package com.robert.vesta.service.impl.populater;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdMeta;

import com.robert.vesta.service.impl.timer.Timer;

public class SyncIdPopulator extends BasePopulator {

public SyncIdPopulator() {

super();

}

public synchronized void populateId(Timer timer, Id id, IdMeta idMeta) {

super.populateId(timer, id, idMeta);

}

}

package com.robert.vesta.service.impl.populater;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdMeta;

import com.robert.vesta.service.impl.timer.Timer;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

public class LockIdPopulator extends BasePopulator {

private Lock lock = new ReentrantLock();

public LockIdPopulator() {

super();

}

public void populateId(Timer timer, Id id, IdMeta idMeta) {

lock.lock();

try {

super.populateId(timer, id, idMeta);

} finally {

lock.unlock();

}

}

}

以上是两个同步方法的实现,都继承于抽象类

原子类无锁只实现接口,不继承于抽象类

package com.robert.vesta.service.impl.populater;

import com.robert.vesta.service.bean.Id;

import com.robert.vesta.service.impl.bean.IdMeta;

import com.robert.vesta.service.impl.timer.Timer;

import java.util.concurrent.atomic.AtomicReference;

public class AtomicIdPopulator implements IdPopulator {

class Variant {

private long sequence = 0;

private long lastTimestamp = -1;

}

private AtomicReference variant = new AtomicReference(new Variant());

public AtomicIdPopulator() {

super();

}

public void populateId(Timer timer, Id id, IdMeta idMeta) {

Variant varOld, varNew;

long timestamp, sequence;

while (true) {

// Save the old variant

varOld = variant.get();

// populate the current variant

timestamp = timer.genTime();

timer.validateTimestamp(varOld.lastTimestamp, timestamp);

sequence = varOld.sequence;

if (timestamp == varOld.lastTimestamp) {

sequence++;

sequence &= idMeta.getSeqBitsMask();

if (sequence == 0) {

timestamp = timer.tillNextTimeUnit(varOld.lastTimestamp);

}

} else {

sequence = 0;

}

// Assign the current variant by the atomic tools

varNew = new Variant();

varNew.sequence = sequence;

varNew.lastTimestamp = timestamp;

if (variant.compareAndSet(varOld, varNew)) {

id.setSeq(sequence);

id.setTime(timestamp);

break;

}

}

}

public void reset() {

variant = new AtomicReference(new Variant());

}

}


版权声明:本文为weixin_42501035原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。