TinyID适配GaussDB验证过程

举报
纷纷扰扰 发表于 2024/12/12 18:24:18 2024/12/12
【摘要】 在互联网系统设计开发中,我们需要接口能够达到高性能,高并发和高可用要求,同时需要保证数据的唯一性,传统的数据库自增,uuid等方式无法满足要求,就需要一个性能好,可靠的分布式id组件来解决这个痛点,滴滴TinyId采用数据库号段模式来实现分布式ID。

背景目的

在互联网系统设计开发中,我们需要接口能够达到高性能,高并发和高可用要求,同时需要保证数据的唯一性,传统的数据库自增,uuid等方式无法满足要求,就需要一个性能好,可靠的分布式id组件来解决这个痛点,滴滴TinyId采用数据库号段模式来实现分布式ID。官方代码和文档中只有mysql支持且是老版本,本次修改希望扩展tinyid的数据库支持,例如GaussDB等。通过适配多数据库验证方便大家直接选用。

Demo设计

在华为云开源示例项目servicecomb-fenece/resource-server服务模块中集成tinyid-client,打包构建TinyId和servicecomb-fenece镜像部署,通过接口验证。

代码修改

修改思路:扩展数据库支持,例如GaussDB,PostgreSql,Sqlserver,Mysql8等;基础框架升级到长期支持版本。

1.扩展支持其它数据库

TinyId开源项目中只支持mysql,并且引用的是低版本5.1.44,修改后升级到8版本驱动。同时引入其它数据库驱动验证。

       <!--mysql8-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.33</version>
        </dependency>

        <!--gaussdb-->
        <dependency>
            <groupId>com.huaweicloud.gaussdb</groupId>
            <artifactId>opengaussjdbc</artifactId>
            <version>503.2.T35</version>
        </dependency>

        <!-- /postgresql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.7.4</version>
        </dependency>

        <!-- sqlserver/mssql-jdbc -->
        <dependency>
            <groupId>com.microsoft.sqlserver</groupId>
            <artifactId>mssql-jdbc</artifactId>
            <version>12.8.1.jre11</version>
        </dependency>

        <!-- Dameng -->
        <dependency>
            <groupId>com.dameng</groupId>
            <artifactId>DmJdbcDriver18</artifactId>
            <version>8.1.3.140</version>
        </dependency>

2.基础框架版本升级

项目中master分支中的springboot版本是 1.5.9.RELEASE,相关框架过于陈旧了,本次修改决定升级到长期支持版本。升级版本如下:

依赖名称\版本 旧版本 新版本
spring-boot 1.5.9.RELEASE 3.4.0
JDK 1.7 17
mysql-connector-java 5.1.38 8.0.33
maven-shade-plugin 3.0.0 3.6.0

sprinboot升级可参考官方支持https://spring.io/projects/spring-boot#support

升级到springboot3版本需要注意

import javax.*.*;

变更为

import jakarta.*.*;

controller类中方法参数需要添加@RequestParam注解

适配过程

1.验证代码运行

修改代码之后测试mysql8,配置如下;

初始化项目中提供的初始化脚本,启动项目

接口验证

2.本地GaussDB验证

配置信息:

脚本:

CREATE TABLE `tiny_id_info` (
  `id` int8 NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '业务类型,唯一',
  `begin_id` int8 NOT NULL DEFAULT '0' COMMENT '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同',
  `max_id` int8 NOT NULL DEFAULT '0' COMMENT '当前最大id',
  `step` int4 DEFAULT '0' COMMENT '步长',
  `delta` int4 NOT NULL DEFAULT '1' COMMENT '每次id增量',
  `remainder` int4 NOT NULL DEFAULT '0' COMMENT '余数',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `version` int8 NOT NULL DEFAULT '0' COMMENT '版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'id信息表';
CREATE UNIQUE INDEX "idx_uniq_biz_type" ON "tiny_id_info" ("biz_type");

CREATE TABLE `tiny_id_token` (
  `id` int4 unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `token` varchar(255) NOT NULL DEFAULT '' COMMENT 'token',
  `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '此token可访问的业务类型标识',
  `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'token信息表';

INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
VALUES
	(1, 'test', 1, 1, 100000, 1, 0, now(), now(), 1);

INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
VALUES
	(2, 'test_odd', 1, 1, 100000, 2, 1, now(), now(), 3);


INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
VALUES
	(1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', now(), now());

INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
VALUES
	(2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', now(), now());

启动和接口验证

3.适配GaussDB的Demo验证

根据Demo设计,在华为云开源示例项目servicecomb-fence/resource微服务中引入tinyid-client,编译构建镜像部署到华为云CCE,配置相关参数运行验证。

servicecomb-fence/resource微服务中引入tinyid-client

目前tinyid-client在maven中央仓库中没有依赖,所以打包的jar包包含依赖

创建Dockerfile

初始化脚本:

CREATE TABLE `tiny_id_info` (
  `id` int8 NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '业务类型,唯一',
  `begin_id` int8 NOT NULL DEFAULT '0' COMMENT '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同',
  `max_id` int8 NOT NULL DEFAULT '0' COMMENT '当前最大id',
  `step` int4 DEFAULT '0' COMMENT '步长',
  `delta` int4 NOT NULL DEFAULT '1' COMMENT '每次id增量',
  `remainder` int4 NOT NULL DEFAULT '0' COMMENT '余数',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  `version` int8 NOT NULL DEFAULT '0' COMMENT '版本号',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'id信息表';
CREATE UNIQUE INDEX "idx_uniq_biz_type" ON "tiny_id_info" ("biz_type");

CREATE TABLE `tiny_id_token` (
  `id` int4 unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',
  `token` varchar(255) NOT NULL DEFAULT '' COMMENT 'token',
  `biz_type` varchar(63) NOT NULL DEFAULT '' COMMENT '此token可访问的业务类型标识',
  `remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT 'token信息表';

INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
VALUES(1, 'test', 1, 1, 100000, 1, 0, now(), now(), 1);

INSERT INTO `tiny_id_info` (`id`, `biz_type`, `begin_id`, `max_id`, `step`, `delta`, `remainder`, `create_time`, `update_time`, `version`)
VALUES(2, 'test_odd', 1, 1, 100000, 2, 1, now(), now(), 3);

INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
VALUES (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', now(), now());

INSERT INTO `tiny_id_token` (`id`, `token`, `biz_type`, `remark`, `create_time`, `update_time`)
VALUES (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', now(), now());

部署tinyid-server:

部署servicecomb-fence

接口测试:

3.验证其它数据库

除了GaussDB之外的其它数据库我们直接在本地进行验证。

PostgreSQL 16.4验证:

脚本:

CREATE TABLE "tiny_id_info" (
  "id" int8 NOT NULL ,
  "biz_type" varchar(63) NOT NULL UNIQUE DEFAULT '',
  "begin_id" int8 NOT NULL DEFAULT '0' ,
  "max_id" int8 NOT NULL DEFAULT '0' ,
  "step" int4 DEFAULT '0' ,
  "delta" int4 NOT NULL DEFAULT '1' ,
  "remainder" int4 NOT NULL DEFAULT '0' ,
  "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  "version" int8 NOT NULL DEFAULT '0' ,
  PRIMARY KEY ("id")
) ;
COMMENT ON TABLE "tiny_id_info" is 'id信息表';
COMMENT ON COLUMN "tiny_id_info"."id" IS '自增主键';
COMMENT ON COLUMN "tiny_id_info"."biz_type" IS '业务类型,唯一';
COMMENT ON COLUMN "tiny_id_info"."begin_id" IS '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同';
COMMENT ON COLUMN "tiny_id_info"."max_id" IS '当前最大id';
COMMENT ON COLUMN "tiny_id_info"."step" IS '步长';
COMMENT ON COLUMN "tiny_id_info"."delta" IS '每次id增量';
COMMENT ON COLUMN "tiny_id_info"."remainder" IS '余数';
COMMENT ON COLUMN "tiny_id_info"."create_time" IS '创建时间';
COMMENT ON COLUMN "tiny_id_info"."update_time" IS '更新时间';
COMMENT ON COLUMN "tiny_id_info"."version" IS '版本号';

CREATE TABLE "tiny_id_token" (
  "id" int4 CHECK (id >= 0) NOT NULL ,
  "token" varchar(255) NOT NULL DEFAULT '' ,
  "biz_type" varchar(63) NOT NULL DEFAULT '' ,
  "remark" varchar(255) NOT NULL DEFAULT '',
  "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ,
  PRIMARY KEY ("id")
);
COMMENT ON TABLE "tiny_id_token" is 'token信息表';
COMMENT ON COLUMN "tiny_id_token"."id" IS '自增id';
COMMENT ON COLUMN "tiny_id_token"."token" IS 'token';
COMMENT ON COLUMN "tiny_id_token"."biz_type" IS '此token可访问的业务类型标识';
COMMENT ON COLUMN "tiny_id_token"."remark" IS '备注';
COMMENT ON COLUMN "tiny_id_token"."create_time" IS '创建时间';
COMMENT ON COLUMN "tiny_id_token"."update_time" IS '更新时间';

INSERT INTO tiny_id_info (id, biz_type, begin_id, max_id, step, delta, remainder, create_time, update_time, version)
VALUES(1, 'test', 1, 1, 100000, 1, 0, now(), now(), 1);
INSERT INTO tiny_id_info (id, biz_type, begin_id, max_id, step, delta, remainder, create_time, update_time, version)
VALUES(2, 'test_odd', 1, 1, 100000, 2, 1, now(), now(), 3);
INSERT INTO tiny_id_token (id, token, biz_type, remark, create_time, update_time)
VALUES (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', now(), now());
INSERT INTO tiny_id_token (id, token, biz_type, remark, create_time, update_time)
VALUES (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', now(), now());

配置参数

datasource.tinyid.primary.driver-class-name=org.postgresql.Driver
datasource.tinyid.primary.url=jdbc:postgresql://xxxxx.xx.xx.xx:5432/tinyid?currentSchema=public
datasource.tinyid.primary.username=root
datasource.tinyid.primary.password=xxxxx

验证结果:

Microsoft SQL Server 2022验证:

脚本:

CREATE TABLE tiny_id_info (
  id bigint NOT NULL ,
  biz_type varchar(63) NOT NULL UNIQUE DEFAULT '' ,
  begin_id bigint NOT NULL DEFAULT '0' ,
  max_id bigint NOT NULL DEFAULT '0' ,
  step int DEFAULT '0',
  delta int NOT NULL DEFAULT '1' ,
  remainder int NOT NULL DEFAULT '0',
  create_time datetime  NOT NULL DEFAULT CURRENT_TIMESTAMP,
  update_time datetime  NOT NULL DEFAULT CURRENT_TIMESTAMP,
  version bigint NOT NULL DEFAULT '0',
  PRIMARY KEY (id)
);

CREATE TABLE tiny_id_token (
  id int  NOT NULL ,
  token varchar(255) NOT NULL DEFAULT '' ,
  biz_type varchar(63) NOT NULL DEFAULT '' ,
  remark varchar(255) NOT NULL DEFAULT '' ,
  create_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  update_time datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (id)
);

INSERT INTO tiny_id_info (id, biz_type, begin_id, max_id, step, delta, remainder, create_time, update_time, version)
VALUES(1, 'test', 1, 1, 100000, 1, 0, GETDATE(), GETDATE(), 1);
INSERT INTO tiny_id_info (id, biz_type, begin_id, max_id, step, delta, remainder, create_time, update_time, version)
VALUES(2, 'test_odd', 1, 1, 100000, 2, 1, GETDATE(), GETDATE(), 3);
INSERT INTO tiny_id_token (id, token, biz_type, remark, create_time, update_time)
VALUES (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', GETDATE(), GETDATE());
INSERT INTO tiny_id_token (id, token, biz_type, remark, create_time, update_time)
VALUES (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', GETDATE(), GETDATE());

配置参数

datasource.tinyid.primary.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver 
datasource.tinyid.primary.url=jdbc:sqlserver://xx.xx.xx.xx:1433;databaseName=leaf;encrypt=false;trustServerCertificate=true;
datasource.tinyid.primary.username=rdsuser
datasource.tinyid.primary.password=xxxxx

遇到问题:

Sqlserver获取时间的函数是GETDATE(),不支持now()函数,请求接口报错,定位代码如下,修改为程序设置更新时间。

验证结果:

达梦数据库验证:

脚本:

CREATE TABLE tiny_id_info (
  id bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  biz_type varchar(63) NOT NULL UNIQUE DEFAULT '' COMMENT '业务类型,唯一',
  begin_id bigint NOT NULL DEFAULT '0' COMMENT '开始id,仅记录初始值,无其他含义。初始化时begin_id和max_id应相同',
  max_id bigint NOT NULL DEFAULT '0' COMMENT '当前最大id',
  step int DEFAULT '0' COMMENT '步长',
  delta int NOT NULL DEFAULT '1' COMMENT '每次id增量',
  remainder int NOT NULL DEFAULT '0' COMMENT '余数',
  create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() COMMENT '创建时间',
  update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() COMMENT '更新时间',
  version bigint NOT NULL DEFAULT '0' COMMENT '版本号',
  PRIMARY KEY (id)
);

CREATE TABLE tiny_id_token (
  id int NOT NULL AUTO_INCREMENT COMMENT '自增id',
  token varchar(255) NOT NULL DEFAULT '' COMMENT 'token',
  biz_type varchar(63) NOT NULL DEFAULT '' COMMENT '此token可访问的业务类型标识',
  remark varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
  create_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() COMMENT '创建时间',
  update_time timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP() COMMENT '更新时间',
  PRIMARY KEY (id)
);

INSERT INTO tiny_id_info (id, biz_type, begin_id, max_id, step, delta, remainder, create_time, update_time, version)
VALUES(1, 'test', 1, 1, 100000, 1, 0, now(), now(), 1);
INSERT INTO tiny_id_info (id, biz_type, begin_id, max_id, step, delta, remainder, create_time, update_time, version)
VALUES(2, 'test_odd', 1, 1, 100000, 2, 1, now(), now(), 3);
INSERT INTO tiny_id_token (id, token, biz_type, remark, create_time, update_time)
VALUES (1, '0f673adf80504e2eaa552f5d791b644c', 'test', '1', now(), now());
INSERT INTO tiny_id_token (id, token, biz_type, remark, create_time, update_time)
VALUES (2, '0f673adf80504e2eaa552f5d791b644c', 'test_odd', '1', now(), now());

参数配置

datasource.tinyid.primary.driver-class-name=dm.jdbc.driver.DmDriver
datasource.tinyid.primary.url=jdbc:dm://localhost:5236
datasource.tinyid.primary.username=SYSDBA
datasource.tinyid.primary.password=xxxx

验证结果:

总结

结果上述多种数据库的测试,成功适配验证了GaussDB,Mysql8,Sqlserrver,达梦,Postgressql,其它的数据库如果需要适配大家可自行实验,操作大同小异,主要区别在于初始化脚本,可根据项目中的db.sql作为依据修改为对于数据库脚本。后续通过评审希望发布tinyid-server的镜像,给大家快速部署。tinyid-client期望也能发布到maven仓库发布依赖使用。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。