美团Leaf-Segment 生成ID使用说明

美团Leaf-Segment 生成ID使用说明

最近在搭建分布式项目时需要考虑全局ID的唯一性,经过对比百度、滴滴、美团开源的ID生成系统,最终选择了美团。然后根据自身项目情况稍微进行了一点修改,读者可根据下面的操作步骤进行配置后可直接使用。在本代码中不包含雪花算法生成ID的相关代码,如需了解可查看原开源地址

第一步

代码下载地址

第二步

pom中引入maven配置

	<!--美团ID生产系统-->
    <dependency>
        <groupId>com.sankuai.inf.leaf</groupId>
        <artifactId>leaf-core</artifactId>
        <version>1.0.1-RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

第三步

启动类中加入@EnableLeafServer注解启用ID服务

    @SpringBootApplication
    @EnableLeafServer // ID 服务注解
    public class TestApplication {
        public static void main(String[] args) {
            SpringApplication.run(TestApplication.class, args);
        }
    }

第四步

application.yml配置文件加入如下配置

leaf:
    segment:
        url: jdbc:mysql://127.0.0.1:3306/leaf?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&nullCatalogMeansCurrent=true
        driver-class-name: com.mysql.cj.jdbc.Driver
        password: root
        username: root
    name: test #默认为leaf-id

第五步

在第四步使用的数据库中创建数据表

CREATE TABLE `leaf_alloc` (
    `biz_tag`  varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT 'ID标签,如活动模块则可设置标签为activity' ,
    `max_id`  bigint(20) NOT NULL DEFAULT 1 COMMENT '当前最大ID值' ,
    `step`  int(11) NOT NULL COMMENT '步长,每一次请求获取的ID个数' ,
    `description`  varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '说明' ,
    `update_time`  timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' ,
    PRIMARY KEY (`biz_tag`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8mb4 COLLATE=utf8mb4_general_ci
COMMENT='ID管理数据表'
ROW_FORMAT=DYNAMIC;

要生成不同模块的ID只需要在该数据表中插入插入一条数据即可。例如要生成活动的ID,则执行如下insert语句:

    # biz_tag 为ID标签可随意定义,确保唯一性即可
    # max_id 当前最大ID值,如果是原来已经是自增ID且ID已经达到某值(如:92),则这里max_id可以设置为93。
    # step 每次请求获取的ID个数,当系统用完缓存中的ID后会再创请求获取ID号段并更新max_id值
    # description 备注说明,注明当前行是哪个模块的ID
    INSERT INTO `leaf_alloc` (`biz_tag`, `max_id`, `step`, `description`) VALUES ('activity', '1', '10000', '说明的信息ID');

第六步

创建自定义ID生成策略类,注:该策略只适用于JPA或Hibernate框架

import com.sankuai.inf.leaf.SegmentServiceUtil;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.id.Configurable;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.type.Type;
import java.io.Serializable;
import java.util.Properties;

/**
* 生成自定义ID策略,这里通过使用引用美团ID生成ID进行处理
* @author lizebin
* @version 1.0
* @date 2021/2/19 9:34 下午
*
**/
public class CustomIDGenerator implements IdentifierGenerator, Configurable {

    /**对应ID管理表中biz-tag字段的值*/
    private String bizTag;

    @Override
    public Serializable generate(SharedSessionContractImplementor sharedSessionContractImplementor, Object o) throws HibernateException {
       return SegmentServiceUtil.getId(this.bizTag);
    }

    @Override
    public boolean supportsJdbcBatchInserts() {
        return true;
    }

    @Override
    public void configure(Type type, Properties properties, ServiceRegistry serviceRegistry) throws MappingException {
        this.bizTag = properties.getProperty("biz-tag");
    }
}

第六步

实体类中使用CustomIDGenerator策略生成ID,在主键字段中增加 @GeneratedValue @GenericGenerator两个注解,配置如下代码所示。需要注意GeneratedValuegenerator属性的值必须与GenericGeneratorname属性的值一致。

GenericGenerator中的strategy属性值为CustomIDGenerator类的路径名称(含包路径)

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO, generator = "custom-id")
  @GenericGenerator(name = "custom-id", strategy = "com.test.CustomIDGenerator", parameters = { @org.hibernate.annotations.Parameter(name = "biz-tag", value = "activity")})
  @Column(name = "id", length = 20)
  private Long id;

补充说明

如果不想通过第六步方式进行ID的设置可以用以下方式获取ID的值

// 方式一,调用工具类传入ID标签获取ID
SegmentServiceUtil.getId(String bizTag);

// 方式二,注入SegmentService类传入ID标签获取ID
@Autowired
private SegmentService segmentService;
segmentService.getId("bizTag").getId();

美团 Leaf 在 GitHub 上的开源项目仓库

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L-zbin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值