package com.jthink.skyeye.trace.generater; import com.jthink.skyeye.base.constant.Constants; import com.jthink.skyeye.trace.dto.RegisterDto; import org.I0Itec.zkclient.ZkClient; import org.apache.zookeeper.data.Stat; /** * JThink@JThink * * @author JThink * @version 0.0.1 * @desc 自增长ID生成器,用来给app和host的服务进行编号(利用zk节点的版本号每写一次就自增的机制来实现) * @date 2017-03-24 11:25:31 */ public class IncrementIdGen implements IdGen { // 为某台机器上的某个项目分配的serviceId(注意区分Span中的serviceId) private static String serviceId = null; // register info private RegisterDto registerDto; /** * 利用zookeeper * @return */ @Override public String nextId() { String app = this.registerDto.getApp(); String host = this.registerDto.getHost(); ZkClient zkClient = this.registerDto.getZkClient(); String path = Constants.ZK_REGISTRY_ID_ROOT_PATH + Constants.SLASH + app + Constants.SLASH + host; if (zkClient.exists(path)) { // 如果已经有该节点,表示已经为当前的host上部署的该app分配的编号(应对某个服务重启之后编号不变的问题),直接获取该id,而无需生成 return zkClient.readData(Constants.ZK_REGISTRY_ID_ROOT_PATH + Constants.SLASH + app + Constants.SLASH + host); } else { // 节点不存在,那么需要生成id,利用zk节点的版本号每写一次就自增的机制来实现 Stat stat = zkClient.writeDataReturnStat(Constants.ZK_REGISTRY_SEQ, new byte[0], -1); // 生成id String id = String.valueOf(stat.getVersion()); // 将数据写入节点 zkClient.createPersistent(path, true); zkClient.writeData(path, id); return id; } } /** * 获取ID * @return */ public static String getId() { return serviceId; } /** * 对ID赋值 * @param id * @return */ public static void setId(String id) { serviceId = id; } public IncrementIdGen() { } public IncrementIdGen(RegisterDto registerDto) { this.registerDto = registerDto; } public RegisterDto getRegisterDto() { return registerDto; } public IncrementIdGen setRegisterDto(RegisterDto registerDto) { this.registerDto = registerDto; return this; } }