Go开源项目分布式唯一ID生成系统
作者:yongxinz 发布时间:2024-02-14 22:08:15
前言
今天跟大家介绍一个开源项目:id-maker,主要功能是用来在分布式环境下生成唯一 ID。上周停更了一周,也是用来开发和测试这个项目的相关代码。
美团有一个开源项目叫 Leaf,使用 Java 开发。本项目就是在此思路的基础上,使用 Go 开发实现的。
项目整体代码量并不多,不管是想要在实际生产环境中使用,还是想找个项目练手,我觉得都是一个不错的选择。
项目背景
在大部分系统中,全局唯一 ID 都是一个强需求。比如快递,外卖,电影等,都需要生成唯一 ID 来保证单号唯一。
那业务系统对 ID 号的要求有哪些呢?
全局唯一性:不能出现重复的 ID 号,既然是唯一标识,这是最基本的要求。
趋势递增:在 MySQL InnoDB 引擎中使用的是聚集索引,由于多数 RDBMS 使用 B-tree 的数据结构来存储索引数据,在主键的选择上面我们应该尽量使用有序的主键保证写入性能。
单调递增:保证下一个 ID 一定大于上一个 ID,例如事务版本号、IM 增量消息、排序等特殊需求。
信息安全:如果 ID 是连续的,恶意用户的扒取工作就非常容易做了,直接按照顺序下载指定 URL 即可;如果是订单号就更危险了,竞对可以直接知道我们一天的单量。所以在一些应用场景下,会需要 ID 无规则、不规则。
在此背景下,有一个高可用的唯一 ID 生成系统就很重要了。
项目使用
生成 ID 分两种方式:
根据数据库生成 ID。
根据雪花算法生成 ID。
使用上提供两种方式来调用接口:
HTTP 方式
gRPC 方式
HTTP 方式
1、健康检查:
curl http://127.0.0.1:8080/ping
2、获取 ID:
获取 tag 是 test 的 ID:
curl http://127.0.0.1:8080/v1/id/test
3、获取雪花 ID:
curl http://127.0.0.1:8080/v1/snowid
gRPC 方式
1、获取 ID:
grpcurl -plaintext -d '{"tag":"test"}' -import-path $HOME/src/id-maker/internal/controller/rpc/proto -proto segment.proto localhost:50051 proto.Gid/GetId
2、获取雪花 ID:
grpcurl -plaintext -import-path $HOME/src/id-maker/internal/controller/rpc/proto -proto segment.proto localhost:50051 proto.Gid/GetSnowId
本地开发
# Run MySQL
$ make compose-up
# Run app with migrations
$ make run
项目架构
项目使用 go-clean-template 架构模板开发,目录结构如下:
下面对各目录做一个简要说明:
cmd:程序入口
config:配置文件
docs:生成的项目文档
integration-test:整合测试
internal:业务代码
pkg:一些调用的包
借用官方的两张图:
整体的层次关系是这样的,最里面是 models,定义我们的表结构,然后中间是业务逻辑层,业务逻辑层会提供接口,给最外层的 API 来调用,最外层就是一些工具和调用入口。
这样做的最大好处就是解耦,不管最外层如何变化,只要在业务逻辑层实现对应接口即可,核心代码可能根本不需要改变。
所以,它们之间的调用关系看起来是这样的:
HTTP > usecase
usecase > repository (Postgres)
usecase < repository (Postgres)
HTTP < usecase
项目地址:https://github.com/yongxinz/id-maker
往期文章:
听说,99% 的 Go 程序员都被 defer 坑过
测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她
gRPC,爆赞
使用 grpcurl 通过命令行访问 gRPC 服务
推荐三个实用的 Go 开发工具
猜你喜欢
- 在CSS中,模式(pattern)匹配规则决定那种样式规则应用于文档树(document tree)的哪个元素。这些模式叫着选择符(sele
- 本文实例为大家分享了Python实现图书馆座位自动预约的具体代码,供大家参考,具体内容如下配置通过公网主机定时运行脚本,并发送邮件到自己的q
- 对一名开发者来说最糟糕的情况,莫过于要弄清楚一个不熟悉的应用为何不工作。有时候,你甚至不知道系统运行,是否跟原始设计一致。在线运行的应用就是
- 最近忙成了狗,五六个项目堆在一起,头疼的是测试还失惊无神的给我丢来一个几十甚至上百M的日志文件,动不动就几十上百万行,就算是搜索也看得头昏眼
- OS模块import os1.返回操作系统类型 :posix 是linux操作系统,nt 是windows操作系统print(os.name
- python中捕获键盘操作一共有两种方法第一种方法:使用pygame中event方法使用方式如下:使用键盘右键为例if event.type
- 由于Access数据库是一种文件型数据库,所以无法跨服务器进行访问。下面我们来介绍一下如何利用SQL Server 的链接服务器,把地理上分
- 前言本文介绍如何使用Python制作一个简单的猜数字游戏。游戏规则玩家将猜测一个数字。如果猜测是正确的,玩家赢。如果不正确,程序会提示玩家所
- 1 索引索引概念索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引,并指定索引的类型,各类索引有各自的
- 上一篇博客介绍了 如何使用Python,OpenCV上下左右(或任意组合)平移图像。这篇博客将介绍如何使用OpenCV旋转图像任意角度。并演
- 本文实例为大家分享了树回归的具体代码,供大家参考,具体内容如下#-*- coding:utf-8 -*- #!/usr/bin/python
- 这个教程,我们将展示如何用python创建一个井字游戏。 其中我们将使用函数、数组、if条件语句、while循环语句和错误捕获等
- 一、使用sklearn转换器处理sklearn提供了model_selection模型选择模块、preprocessing数据预处理模块、d
- 1. python三维图表绘制方法简介python三维图表的绘制算是二维图表的一个进阶版本,本质上和二维图表的绘制并无差别,唯一的区别在于使
- 前言:内容提要:本文比较了 Python 中用于列表排序的两种函数 sort() 和 sorted(),帮助您选择合适的排序函数。对列表排序
- 1. 问题homebrew用以下命令安装pythonbrew install python3然后用以下命令查看python安装版本pytho
- doctest库就是一个测试用的标准库,从意义上我们可以看出是关于测试有关系的,基本上就是测试是否和自己想要的结果是否一致,经常能在编写文档
- 引言最近在学习python,先说一下我学Python得原因,一个是因为它足够好用,完成同样的功能,代码量会比其他语言少很多,有大量的丰富的库
- 一、Golang环境安装及配置Go Modulehttps://go-zero.dev/cn/docs/prepare/golang-ins
- 本文实例讲述了Python Socket实现简单TCP Server/client功能。分享给大家供大家参考,具体如下:网络上关于socke