5 Star 34 Fork 8

tinyservices / tinyservices-id

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
MIT

tinyservices-id

一、软件介绍

tinyservices-id 是一个高性能可扩展生成唯一id的服务。目前包含两种生成算法:雪花算法以及自增号段。 部署和使用都很便捷,无论是个人、团队、或是企业,都能够快速的使用 tinyservices-id 来生成唯一id。

二、软件架构

tinyservices-id

  • tinyservices-id 有两种id生成算法:基于美团leaf的号段算法以及基于推特推出的雪花算法

  • 分为三大模块:

    • id-server:server端,封装id生成算法以及对外提供http服务,可直接通过http获取id

    • id-sdk:sdk包,可直接依赖sdk获取id,省去了获取id的网络开销,性能极佳

    • id-portal:管理后台,通过管理后台新增/修改/删除的数据无需重启id-server服务,1分钟后可自动生效。每隔1分钟会自动同步数据到buffer中

  • 雪花算法对中间件(MYSQL、ZOOKEEPER)弱依赖,每隔几秒会自动将中间件里的workerId刷到本地文件当中,这样即使中间件挂了的话也不影响id-server的正常使用,因为会自动降级到本地文件,因此也不会影响到业务系统

  • 提供灵活配置以及可扩展能力,可自定义配置文件名称甚至无需配置文件,自定义实现类将配置放到配置中心。若雪花算法不希望用MYSQL或ZOOKEEPER,也可以自定义实现类进行实现,比如自定义ETCD等其他方式

三、安装教程

1、准备工作

1.1 Java

  • 版本要求:1.8+,在配置好后可以通过如下命令检查:

    java -version

1.2 MySQL

  • 版本要求:5.6.5+,连接上MySQL后,可以通过如下命令检查:

    SHOW VARIABLES WHERE Variable_name = 'version';

1.3 下载

2、安装步骤

2.1 创建数据库

  • 通过MySQL客户端导入如下sql文件即可:
scripts/sql/ts_id.sql
  • 导入成功后执行以下sql语句来验证:
use ts_id;
show tables;
  • sql执行结果如下则代表正常:
ts_id_segment
ts_id_token
ts_id_worker_id

2.2 配置数据库

  • 根据不同环境修改不同的配置值(dev/test/pre/prod),所修改文件的位置如下:

    scripts/build.sh
  • scripts/build.sh配置含义如下:

    配置项 配置含义 是否必填 默认值
    id_server_config_db_driver jdbc的driver 必填
    id_server_config_db_url jdbc的url 必填
    id_server_config_db_username mysql用户名 必填
    id_server_config_db_password mysql密码 必填
    id_server_config_db_initial_size 链接池初始化大小,不写则采取默认值 非必填 0
    id_server_config_db_min_idle 链接池最小空闲连接数,不写则采取默认值 非必填 0
    id_server_config_db_max_active 链接池最大活跃数,不写则采取默认值 非必填 8
    id_server_config_db_max_wait 链接池获取连接的最大等待时间,单位ms,不写则采取默认值 非必填 -1
    id_snowflake_mode 雪花算法模式:
    LOCAL(本地文件的方式)
    MYSQL(对应ts_id_worker_id表)
    ZOOKEEPER(每次都根据ip:port创建一个顺序持久节点)
    RECYCLABLE_ZOOKEEPER(如果ip:port经常变的话那1023个workerId很容易就被耗光,此种方式是可循环利用workerId的ZOOKEEPER方式)
    非必填 LOCAL
    id_snowflake_port 雪花算法端口,不管采取何种方式,都会根据ip:port生成唯一key与workerId一一对应。
    注:不会真正启动端口,只是作为唯一标识,所以和项目端口可重叠。
    非必填 8080
    id_snowflake_epoch 雪花算法epoch,起始值,默认值:1648742400000L 非必填 1648742400000L(2022-04-01 00:00:00)
    id_snowflake_zkConnectionAddr 如果雪花算法采取ZOOKEEPER或RECYCLABLE_ZOOKEEPER模式,则需要配置ZOOKEEPER地址, 非必填 localhost:2181
    id_server_log_dir id-server项目日志目录 必填
    id_portal_log_dir id-portal项目日志目录 必填
    id_server_port id-server项目端口号 非必填 8080
    id_portal_port id-portal项目端口号 非必填 8080

四、部署运行

1. 部署运行

1.1 编译打包

  • 可直接运行修改后的scripts/build.sh文件,比如:
sh scripts/build.sh dev id-server

sh scripts/build.sh dev id-portal

可选参数:

$1:dev/test/pre/prod,分别代表开发环境/测试环境/预生产环境/生产环境。

$2:id-server/id-portal,分别代表id-server/id-portal两个moudle,也就是给哪个moudle打包,配置就是上面所输入dev/test/pre/prod所对应的变量。

1.2 运行

  • 编译打包完成后,可直接执行启动脚本,如下:

    sh id-server/scripts/startup.sh
    
    sh id-portal/scripts/startup.sh
  • 验证id-server是否启动成功(也可以通过看日志的方式,日志位置就是id_server_log_dir对应的值)

    curl http(s)://ip:port/health/check

    返回如下代表成功:

    {
        "code": 0,
        "msg": "Processed successfully",
        "data": 666
    }
  • 验证id-portal是否启动成功(也可以通过看日志的方式,日志位置就是id_portal_log_dir对应的值)

    直接浏览器打开http(s)://ip:port,会出现如下页面:

    id-portal

五、使用说明

1. 准备工作

  • token是鉴权的唯一方式。所以需要在id-portal管理后台创建好token和业务类型的对应关系。
  • 如果是号段模式的话,则需要在id-portal管理后台创建好Segment。
  • 以上两种添加方式操作完无需重启服务,会有定时任务每一分钟去查数据库将其缓存到内存中,这样获取id的时候直接可用。

使用上有两种使用方式,分别是Server和Sdk,Server的使用很简单,直接对外提供获取id的http接口。Sdk则需要业务系统依赖jar包然后调用方法获取id。下面详细介绍下二者使用方式和区别。

2. Server

不管获取哪种算法的id,都需要添加如下header,否则会提示-4错误码,代表没权限:

tinyservice-id-token=token(token由id-portal管理后台Token菜单获取)

2.1 获取号段id

# 获取单个
GET http(s)://ip:port/segment/{业务类型}

# 批量获取
GET http(s)://ip:port/segment/{业务类型}/{获取的id数量}

2.2 获取雪花id

# 获取单个
GET http(s)://ip:port/snowflake/{业务类型}

# 批量获取
GET http(s)://ip:port/snowflake/{业务类型}/{获取的id数量}

3. Sdk

3.1 添加依赖

<dependency>
  <groupId>com.gitee.tinyservices</groupId>
  <artifactId>id-sdk</artifactId>
  <version>1.0.0</version>
</dependency>

3.2 添加配置

classpathspringboot项目通常为resources)下添加名为tinyservices_id_sdk.properties的配置文件,包含如下配置项:

# id-server的地址,多个用英文逗号隔开,会随机选择一个地址使用
tinyservices.id.server=http://localhost:9990
# 要访问业务类型的token。可在id-portal管理后台配置/查看
tinyservices.id.token=U2FsdGVkX18uip/K7pLiM4ZD5RKrHacD64eKWCNfmW4=

3.3 获取id

// IdSdkTypeEnum.SEGMENT   号段模式
// IdSdkTypeEnum.SNOWFLAKE 雪花模式
AbstractIdSdk idSdk = IdSdkFactory.getInstance().getIdSdk(IdSdkTypeEnum.SEGMENT).registerConfigSupport();
// 获取id
for (int i = 0; i < 10; i ++) {
    Long id = idSdk.getId("业务类型");
}

3.4 全部配置

配置项 配置含义 是否必填 默认值
tinyservices.id.token token,可从id-portal管理后台配置/查看 必填
tinyservices.id.server id-server服务列表,多个用逗号隔开,比如:http://localhost:9990 必填
tinyservices.id.readTimeout sdk和server的超时时间(ms) 非必填 5000ms
tinyservices.id.connectTimeout sdk和server的连接超时时间(ms) 非必填 5000ms
tinyservices.id.snowflake.epoch 雪花算法的开始时间戳 非必填 1648742400000L(2022-04-01 00:00:00)

4. 使用建议

Segment模式根据自身业务量规划好步长,比如业务QPS是10000,步长写了10,那可能瞬时流量进来的话会获取到少部分id为null的情况,因为步长太小,双buffer都被瞬时流量打满。

如果对性能有极高要求的话,推荐Sdk方式,此方式直接依赖jar包调用本地方法的方式生成id,由于Sdk的方式免去了网络开销,理论上QPS可达千万。

如果对性能要求不高的话可以使用Server方式,直接请求http接口,减少系统依赖。

六、FAQ

1. 如何在本地运行?

给项目添加对应环境变量即可,IDEA添加环境变量的方式如下:

add-env

1.1 id-server

添加如下环境变量:

spring.datasource.driver=com.mysql.cj.jdbc.Driver;spring.datasource.url=jdbc:mysql://localhost:3306/ts_id?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT;spring.datasource.username=root;spring.datasource.password=12345678;spring.datasource.initial-size=;spring.datasource.min-idle=;spring.datasource.max-active=;spring.datasource.max-wait=;id_server_log_dir=/data/logs/id-server;server_port=9990;id_server_snowflake_mode=MYSQL;id_server_snowflake_port=8888;id_server_snowflake_epoch=1648742400000;id_server_snowflake_zkConnectionAddr=localhost:2181

数据库连接、用户名、密码、端口等等参数都根据自身环境自行修改即可。

1.2 id-portal

添加如下环境变量:

spring.datasource.driver=com.mysql.cj.jdbc.Driver;spring.datasource.url=jdbc:mysql://localhost:3306/ts_id?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT;spring.datasource.username=root;spring.datasource.password=12345678;spring.datasource.initial-size=;spring.datasource.min-idle=;spring.datasource.max-active=;spring.datasource.max-wait=;id_portal_log_dir=/data/logs/id-portal;server_port=9990

数据库连接、用户名、密码、端口等等参数都根据自身环境自行修改即可。

2. id-portal添加配置后多久生效?

不管是Segment还是Token方式,新增或修改配置后都是一分钟生效,也就是一分钟后id-server服务可用这份配置。

3. 雪花算法如何自定义注册中心?

目前内置四种模式:LOCAL本地文件模式、MYSQL模式、ZOOKEEPER模式以及RECYCLABLE_ZOOKEEPER可回收利用workerId的ZOOKEEPER模式,若想采用其他中间件作为注册中心,那么如下步骤:

  • 首先自定义一个Class继承AbstractIdSnowflakeHolder类且重写相应的方法,可参考其他子类,比如:ZookeeperIdSnowflakeHolder

  • 其次在枚举类IdSnowflakeHolderTypeEnum当中新增相应类型(此类型必须和配置文件里的tinyservices.id.snowflake.mode配置一一对应)

  • 最后修改工厂类的方法IdSnowflakeHolderFactory#getIdSnowflakeHolder,为其新增case分支,值为新增的枚举类型

4. 雪花算法采取的是RECYCLABLE_ZOOKEEPER模式,启动很慢?

RECYCLABLE_ZOOKEEPER模式首次启动慢正常的,此模式会在启动的时候提前在Zookeeper创建1023个持久节点作为workerId池,利于workerId的复用。因为是持久节点,所以只有首次创建会很慢,之后启动会发现已存在1023个持久节点则不再重复创建。

5. MySQL驱动报错问题

如项目启动过程中出现MySQL驱动错误的话,则自行按需修改版本号,目前内置版本是8.0.21,在根pom.xml文件中。如下:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.21</version>
    <scope>runtime</scope>
</dependency>

修改后再打包的时候别忘了修改scripts/build.sh里的id_server_config_db_driver配置。

若是本地部署代码运行的话则别忘了修改环境变量里的id_server_config_db_driver配置。

6. Sdk模式配置文件如何修改名称?

如果不想采取默认的配置文件名称tinyservices_id_sdk.properties,那可以采取如下方式进行自定义:

AbstractIdSdk idSdk = IdSdkFactory.getInstance().getIdSdk(IdSdkTypeEnum.SNOWFLAKE, "自定义配置文件名称.properties").registerConfigSupport();

// 获取id
for (int i = 0; i < 10; i ++) {
    Long id = idSdk.getId("业务类型");
}

7. Sdk模式如何将配置放到注册中心?

如果不想采取配置文件的方式,公司规范都放到配置中心该怎么办?可以采取如下方式进行自定义:

7.1 自定义配置类

/**
 * 可选择性重写如下五个方法:
 * String getBizToken();
 * String getServerUrl();
 * int getReadTimeout();
 * int getConnectTimeout();
 * long getEpoch();
 */
public class CustomIdConfigSupport extends AbstractIdConfigSupport {
    @Override
    public String getServerUrl() {
        // 可通过配置中心获取
        return null;
    }

    @Override
    public String getBizToken() {
        // 可通过配置中心获取        
        return null;
    }
    
    // ... 省略其他非必需重写的方法
}

7.2 注册配置类

AbstractIdSdk idSdk = IdSdkFactory.getInstance().getIdSdk(IdSdkTypeEnum.SNOWFLAKE).registerConfigSupport(new CustomIdConfigSupport());

// 获取id
for (int i = 0; i < 10; i ++) {
    Long id = idSdk.getId("业务类型");
}

8. Sdk模式如何获取不同业务类型的id?

背景:sdk方式一个配置文件只允许配置一个token,若一个项目想获取不同业务类型的token该如何获取呢?

解答:有两种方式可以解决:

  1. 一个业务类型支持配置多个token,可以将不同业务类型都配置一个公共的token,后台目前只允许生成token,不允许自定义token,如需这么做可以二开下id-portal,放开token禁止输入的限制,也可以手动修改ts_id_worker_id表数据。

  2. 或者采取自定义配置文件的方式,比如要获取两个业务类型的id:

    第一个业务类型:

    AbstractIdSdk idSdk = IdSdkFactory.getInstance().getIdSdk(IdSdkTypeEnum.SEGMENT, "sdk_1.properties").registerConfigSupport();
    
    idSdk.getId("test1");

    第二个业务类型:

    AbstractIdSdk idSdk = IdSdkFactory.getInstance().getIdSdk(IdSdkTypeEnum.SEGMENT, "sdk_2.properties").registerConfigSupport();
    
    idSdk.getId("test2");

七、鸣谢

八、结束语

MIT License Copyright (c) 2022 编程界的小学生 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

简介

tinyservices-id 是一个高性能可扩展生成唯一id的服务。目前包含两种生成算法:雪花算法以及自增号段。 部署和使用都很便捷,无论是个人、团队、或是企业,都能够快速的使用 tinyservices-id 来生成唯一id。 展开 收起
MIT
取消

发行版 (1)

全部

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/tinyservices/tinyservices-id.git
git@gitee.com:tinyservices/tinyservices-id.git
tinyservices
tinyservices-id
tinyservices-id
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891