/rabbitID

高性能分布式的ID生成器,QPS达到每秒4.5万。

Primary LanguageJavaMIT LicenseMIT

rabbitID 介绍

兔子ID生成器,名子和RabbitMQ一点关系没有,只是觉得性能还能就起了一个叫免子ID生成器。 现在ID生成器很多。百度的,美团的,还有雪花算法等等等等。这个就是仿的美团的,纯属小菜鸟练手。

刚开始的时候,觉得好难好难,这样包命名都不能理解。 看源码的时候也看不懂,里面会有一些多线程的东西,觉得用的好巧妙。 后来能看懂,能改一点,要真的感谢我的一个好朋友,教了我很多东西,超级牛。

看源码有一个捷径就是看设计模式,而且要在开发当中应用一些。不能只是应付面试,还有多线程,也一样。不能只是背背面试题,应付一下面试。当然我自己做的也不多,设计模式和多线程用的也不多。以后还要经常用。当然得有适合的应用场景。

用到关于锁的知识有:分布式锁,读写锁,自旋锁等。 设计模式工厂:构建,领域驱动,策略等。 架构设计:双BUFFER号段设计。

有以下几个优点

  1. id生成是连续的,递增的,对索引比较友好。
  2. 使用预申请号段,可以在redis挂掉的情况下使用一段时间。
  3. 使用双Segment号段,性能好

下一步需要做的:

  1. 框架依赖于redis,这一点完全也可抽离出来,可以使用zk,或者mq。 这里面大概又会用到工厂模式和建造者模式,要对持久化进行解耦。 预计今年十一月开始开发。。。。。。
  2. flux改造,听说可以提升吞吐量。

性能

在本地电脑跑了跑10万个ID大约是在6秒左右。 找朋友MAC本测试结果是4.5秒。 MAC本就是强啊 !!!!!

已经经过生产环境应用,大家可以使用

联系作者

微信号:canghaihongxin 邮箱: canghaihongxin@163.com

使用方法

第一步: 添加依赖

        <dependency>
            <groupId>com.budongfeng</groupId>
            <artifactId>rabbitId</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.1</version>
        </dependency>

第二步: 添加配置

注: 这里并不是强依赖于springboot,只是RabbitId在启动程序的时候需要启动构建,如果使用spring的时候也只是需要让应用一启动的时候执行 run方法中的代码就可以了。

package com.budongfeng.tboot.config.rabbitid;

import com.bdf.rabbitId.BufferAllocatorTemplate;
import com.bdf.rabbitId.cache.RedisClient;
import com.bdf.rabbitId.model.IdStore;
import com.bdf.rabbitId.utils.RedisConnectionFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

/**
 * description: 配置RabbitID
 * author: 田培融
 * date: 2020-08-28 11:15
 */
@Component
public class RabbitIDConfig implements CommandLineRunner {


    @Override
    public void run(String... args) throws Exception {


        RedisConnectionFactory.RedisProperties properties = new RedisConnectionFactory.RedisProperties();
        properties.setHost("192.168.4.26");
        properties.setDatabase(3);
        properties.setPort(6379);
        properties.setPassword("");
        properties.setPrefix("id");
        RedisConnectionFactory factory =  RedisConnectionFactory.with(properties).build();

        RedisClient redisClient = new RedisClient();
        redisClient.setRedisClientFactory( () -> {
            Jedis jedis = factory.getJedisConnection();
            jedis.select(3);
            return jedis;
        });
        /**
         * @description:  配置id 
         * @author: 田培融
         * @date: 2020/8/28 14:19
          * @param args	 id 名称  step 申请号段步长   factor 申请号段因子   wasteQuota 损耗额度
         */
        BufferAllocatorTemplate.start(redisClient).build(new IdStore().setKey("user_id").setStep(1000).setFactor(30).setWasteQuota(10));
        BufferAllocatorTemplate.start(redisClient).build(new IdStore().setKey("order_id").setStep(1000).setFactor(30).setWasteQuota(10));
    }
}

第三步: 使用

  /**
     * @description:  通过RabbitID 获取id
     * @author: 田培融
     * @date: 2020/8/28 13:06
     */
    @GetMapping("/id")
    @ResponseBody
    public String getId() {
        BufferAllocator allocator = BufferAllocatorTemplate.getAllocator("user_id");
        com.bdf.rabbitId.model.Result res = allocator.get();
        if (res.isSuccess()) {
            System.out.println(res.getId());
        }
        return String.valueOf(res.getId());
    }