基于百度的UidGenerator改造的全局唯一id生成器

其实百度的UidGenerator生成器也是基于snowflake算法的,在原生的项目中使用的基于数据库的,我改造成了基于zookpeer的,用zookpeer的序列号实现分布式seq的生成(代替了算法中的机器码);

关于uidgenerator我这里就不多说了,不了解的可以去看下资料http://blog.csdn.net/littlesmallless/article/details/69663640

修改的关键代码:

/**
     * 提前创建好存储Seq的"/createSeq"结点 CreateMode.PERSISTENT
     */
    public static final String SEQ_ZNODE = "/parent";

    /**
     * session失效时间
     */
    public static final int SESSION_TIMEOUT = 3000;

    /**
     * connection连接时间
     */
    public static final int CONNECTION_TIMEOUT = 3000;

    @Value("${zookeeper.connection}")
    public String connectString;

    /**
     * 通过znode数据版本实现分布式seq生成
     */
    public long znodeSeq(){
        ZkClient zkClient = new ZkClient(connectString, SESSION_TIMEOUT, CONNECTION_TIMEOUT);
        Stat stat =zkClient.writeData(SEQ_ZNODE, new byte[0], -1);
        long versionAsSeq = stat.getVersion();
        System.out.println("obtain seq=" +versionAsSeq );
        zkClient.close();
        return versionAsSeq;
    }
我这里已经修改好了jar包,可以去下载 http://download.csdn.net/download/gaoshili001/10217478

使用方法也比较简单:

 1、在项目中的pom.xml文件中引入

<!-- 添加百度uid-generator -->
        <dependency>
            <groupId>com.baidu.fsg</groupId>
            <artifactId>uid-generator</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

 2、引入xml文件:我使用的是cached-uid-spring.xml

 cached-uid-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">

	<!-- UID generator -->
	<bean id="disposableWorkerIdAssigner" class="com.baidu.fsg.uid.worker.DisposableWorkerIdAssigner" />

	<bean id="cachedUidGenerator" class="com.baidu.fsg.uid.impl.CachedUidGenerator">
		<property name="workerIdAssigner" ref="disposableWorkerIdAssigner" />

		<!-- 以下为可选配置, 如未指定将采用默认值 -->
		<!-- Specified bits & epoch as your demand. No specified the default value will be used -->
		<property name="timeBits" value="31"/>
		<property name="workerBits" value="23"/>
		<property name="seqBits" value="9"/>
		<property name="epochStr" value="2016-09-20"/>

		<!-- 以下为可选配置, 如未指定将采用默认值 -->
		<!-- RingBuffer size扩容参数, 可提高UID生成的吞吐量. --> 
		<!-- 默认:3, 原bufferSize=8192, 扩容后bufferSize= 8192 << 3 = 65536 -->
		<property name="boostPower" value="3"></property>
		
		<!-- 指定何时向RingBuffer中填充UID, 取值为百分比(0, 100), 默认为50 -->
		<!-- 举例: bufferSize=1024, paddingFactor=50 -> threshold=1024 * 50 / 100 = 512. -->
		<!-- 当环上可用UID数量 < 512时, 将自动对RingBuffer进行填充补全 -->
		<!--<property name="paddingFactor" value="50"></property> -->
		
		<!-- 另外一种RingBuffer填充时机, 在Schedule线程中, 周期性检查填充 -->
		<!-- 默认:不配置此项, 即不实用Schedule线程. 如需使用, 请指定Schedule线程时间间隔, 单位:秒 -->
		<!--<property name="scheduleInterval" value="60"></property>--> 
		
		<!-- 拒绝策略: 当环已满, 无法继续填充时 -->
		<!-- 默认无需指定, 将丢弃Put操作, 仅日志记录. 如有特殊需求, 请实现RejectedPutBufferHandler接口(支持Lambda表达式) -->
		<!--<property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property>--> 
		
		<!-- 拒绝策略: 当环已空, 无法继续获取时 -->
		<!-- 默认无需指定, 将记录日志, 并抛出UidGenerateException异常. 如有特殊需求, 请实现RejectedTakeBufferHandler接口(支持Lambda表达式) -->
		<!--<property name="rejectedPutBufferHandler" ref="XxxxYourPutRejectPolicy"></property>--> 
		
	</bean>

</beans>

 3、我使用的是springboot框架(其他框架的自行配置),在application.properties中配置zookpeer的连接地址:

## id生成器zookpeer地址
zookeeper.connection=192.168.40.23:2181

 4、uid生成器配置

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

/**
 * id生成器配置
 *
 * @author 高仕立
 * @date 2017/12/21 21:34
 */
@Configuration
@ImportResource(locations = { "classpath:uid/cached-uid-spring.xml" })
public class UidConfig {
}
 5、工具类

import com.baidu.fsg.uid.UidGenerator;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Set;

/**
 * id生成器工具类
 *
 * @author 高仕立
 * @date 2017/12/21 19:31
 */
@Component
public class UidGeneratorComponent {

    @Resource
    private UidGenerator uidGenerator;

    public long doGenerate(Set<Long> uidSet) {
        long uuid = 0;
        long uid = uidGenerator.getUID();
        boolean existed = uidSet.add(uid);
        if (existed) {
            uuid = uid;
        }
        return uuid;
    }
}

6、项目中的配置完成了,只需要在服务中注入这个工具类就可以生成全局唯一id了,但是还需要比较重要的一步 ,这个跟

项目本身关系不大,我当时写工具类的时候没有封装的太好,zookpeer的parent节点需要在zookpeer中手动去创建,后续

有时间再改吧,先这样用。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值