snowflake

封装一个流水号ID生成器:id-spring-boot-starter

拈花ヽ惹草 提交于 2019-12-09 18:33:59
概述 ID号生成器(或:全局唯一ID生成器)是服务端系统的基础设施,而且ID号这个东西基本搞后端开发的程序员天天都要接触。而关于ID生成的算法现在业界首屈一指的当属 Snowflake 雪花算法。 UidGenerator 正是百度开源的一款基于 Snowflake 雪花算法实现的高性能唯一ID生成器。在本号前文中已经详细使用过 UidGenerator ,但使用过程还是比较繁杂,还需要自己去引 UidGenerator 组件的源码,感觉有点不方便。为此本文基于 UidGenerator ,再来封装一套更利于 Spring Boot 项目使用的 ID 号生成组件,命名为 id-spring-boot-starter ,一看名字就知道是开箱即用的。 用法 导入SQL脚本 DROP TABLE IF EXISTS WORKER_NODE; CREATE TABLE WORKER_NODE ( ID BIGINT NOT NULL AUTO_INCREMENT COMMENT 'auto increment id', HOST_NAME VARCHAR(64) NOT NULL COMMENT 'host name', PORT VARCHAR(64) NOT NULL COMMENT 'port', TYPE INT NOT NULL COMMENT 'node type:

分库分表

99封情书 提交于 2019-12-07 08:38:23
分库分表前的问题 任何问题都是太大或者太小的问题,我们这里面对的数据量太大的问题。 用户请求量太大 因为单服务器TPS,内存,IO都是有限的。 解决方法:分散请求到多个服务器上; 其实用户请求和执行一个sql查询是本质是一样的,都是请求一个资源,只是用户请求还会经过网关,路由,http服务器等。 单库太大 单个数据库处理能力有限;单库所在服务器上磁盘空间不足;单库上操作的IO瓶颈 解决方法:切分成更多更小的库 单表太大 CRUD都成问题;索引膨胀,查询超时 解决方法:切分成多个数据集更小的表。 分库分表方法 分库分表有两个维度的分法:垂直拆分,水平拆分。 垂直拆分 垂直拆分是按列拆分,例如表有:a,b,c,d,e五列,垂直拆分时a,b,c拆成一个新表,d,e拆成一个新表。 垂直拆分分为:垂直分表和垂直分库。 在实践中通常按照下面两点拆分: 按照主要数据和扩展数据拆分。 按照功能或业务拆分。例如:把表中的User数据拆成一个新表,Product拆成一个新表。 水平拆分 水平拆分分为:水平分表和水平分库。 水平分库分表切分规则 RANGE:从0到10000一个表,10001到20000一个表; HASH取模:一个商场系统,一般都是将用户,订单作为主表,然后将和它们相关的作为附表,这样不会造成跨库事务之类的问题。 取用户id,然后hash取模,分配到不同的数据库上。 地理区域

雪花算法-snowflake

对着背影说爱祢 提交于 2019-12-07 07:46:19
snowflake 算法 snowflake 算法是 twitter 开源的分布式 id 生成算法,就是把一个 64 位的 long 型的 id,1 个bit是不用的,用其中的 41 bit 作为毫秒数,用 10 bit 作为工作机器 id,12 bit 作为序列号。 1 bit:不用,为啥呢?因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。 41 bit:表示的是时间戳,单位是毫秒。41 bit 可以表示的数字多达 2^41 - 1 ,也就是可以标识 2^41 - 1 个毫秒值,换算成年就是表示69年的时间。 10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10台机器上哪,也就是1024台机器。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 2^5 个机房(32个机房),每个机房里可以代表 2^5 个机器(32台机器)。 12 bit:这个是用来记录同一个毫秒内产生的不同 id,12 bit 可以代表的最大正整数是 2^12 - 1 = 4096 ,也就是说可以用这个 12 bit 代表的数字来区分 同一个毫秒内 的 4096 个不同的 id。 0 | 0001100 10100010 10111110 10001001

Twitter的分布式雪花算法 SnowFlake

て烟熏妆下的殇ゞ 提交于 2019-12-07 07:45:59
原理 Twitter的雪花算法SnowFlake,使用Java语言实现。 SnowFlake算法产生的ID是一个64位的整型,结构如下(每一部分用“-”符号分隔): 1位标识部分 ,在java中由于long的最高位是符号位,正数是0,负数是1,一般生成的ID为正数,所以为0; 41位时间戳部分 ,这个是毫秒级的时间,一般实现上不会存储当前的时间戳,而是时间戳的差值(当前时间-固定的开始时间),这样可以使产生的ID从更小值开始;41位的时间戳可以使用69年,(1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69年; 10位节点部分 ,Twitter实现中使用前5位作为数据中心标识,后5位作为机器标识,可以部署1024个节点; 12位序列号部分 ,支持同一毫秒内同一个节点可以生成4096个ID; SnowFlake算法生成的ID大致上是按照时间递增的,用在分布式系统中时,需要注意数据中心标识和机器标识必须唯一,这样就能保证每个节点生成的ID都是唯一的。或许我们不一定都需要像上面那样使用5位作为数据中心标识,5位作为机器标识,可以根据我们业务的需要,灵活分配节点部分,如:若不需要数据中心,完全可以使用全部10位作为机器标识;若数据中心不多,也可以只使用3位作为数据中心,7位作为机器标识。 snowflake生成的ID整体上按照时间自增排序

如何设计一个安全的对外接口

情到浓时终转凉″ 提交于 2019-12-07 00:21:53
前言 最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要;这里整理了一下常用的一些安全措施以及具体如何去实现。 安全措施 个人觉得安全措施大体来看主要在两个方面,一方面就是如何保证数据在传输过程中的安全性,另一个方面是数据已经到达服务器端,服务器端如何识别数据,如何不被攻击;下面具体看看都有哪些安全措施。 1.数据加密 我们知道数据在传输过程中是很容易被抓包的,如果直接传输比如通过http协议,那么用户传输的数据可以被任何人获取;所以必须对数据加密,常见的做法对关键字段加密比如用户密码直接通过md5加密;现在主流的做法是使用https协议,在http和tcp之间添加一层加密层(SSL层),这一层负责数据的加密和解密; 2.数据加签 数据加签就是由发送者产生一段无法伪造的一段数字串,来保证数据在传输过程中不被篡改;你可能会问数据如果已经通过https加密了,还有必要进行加签吗?数据在传输过程中经过加密,理论上就算被抓包,也无法对数据进行篡改;但是我们要知道加密的部分其实只是在外网,现在很多服务在内网中都需要经过很多服务跳转,所以这里的加签可以防止内网中数据被篡改; 3.时间戳机制 数据是很容易被抓包的,但是经过如上的加密,加签处理,就算拿到数据也不能看到真实的数据;但是有不法者不关心真实的数据,而是直接拿到抓取的数据包进行恶意请求

分库分表

懵懂的女人 提交于 2019-12-06 16:52:23
分库分表前的问题 任何问题都是太大或者太小的问题,我们这里面对的数据量太大的问题。 用户请求量太大 因为单服务器TPS,内存,IO都是有限的。 解决方法:分散请求到多个服务器上; 其实用户请求和执行一个sql查询是本质是一样的,都是请求一个资源,只是用户请求还会经过网关,路由,http服务器等。 单库太大 单个数据库处理能力有限;单库所在服务器上磁盘空间不足;单库上操作的IO瓶颈 解决方法:切分成更多更小的库 单表太大 CRUD都成问题;索引膨胀,查询超时 解决方法:切分成多个数据集更小的表。 分库分表方法 分库分表有两个维度的分法:垂直拆分,水平拆分。 垂直拆分 垂直拆分是按列拆分,例如表有:a,b,c,d,e五列,垂直拆分时a,b,c拆成一个新表,d,e拆成一个新表。 垂直拆分分为:垂直分表和垂直分库。 在实践中通常按照下面两点拆分: 按照主要数据和扩展数据拆分。 按照功能或业务拆分。例如:把表中的User数据拆成一个新表,Product拆成一个新表。 水平拆分 水平拆分分为:水平分表和水平分库。 水平分库分表切分规则 RANGE:从0到10000一个表,10001到20000一个表; HASH取模:一个商场系统,一般都是将用户,订单作为主表,然后将和它们相关的作为附表,这样不会造成跨库事务之类的问题。 取用户id,然后hash取模,分配到不同的数据库上。 地理区域

如何设计一个安全的对外接口

依然范特西╮ 提交于 2019-12-06 16:10:15
前言 最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要;这里整理了一下常用的一些安全措施以及具体如何去实现。 安全措施 个人觉得安全措施大体来看主要在两个方面,一方面就是如何保证数据在传输过程中的安全性,另一个方面是数据已经到达服务器端,服务器端如何识别数据,如何不被攻击;下面具体看看都有哪些安全措施。 1.数据加密 我们知道数据在传输过程中是很容易被抓包的,如果直接传输比如通过http协议,那么用户传输的数据可以被任何人获取;所以必须对数据加密,常见的做法对关键字段加密比如用户密码直接通过md5加密;现在主流的做法是使用https协议,在http和tcp之间添加一层加密层(SSL层),这一层负责数据的加密和解密; 2.数据加签 数据加签就是由发送者产生一段无法伪造的一段数字串,来保证数据在传输过程中不被篡改;你可能会问数据如果已经通过https加密了,还有必要进行加签吗?数据在传输过程中经过加密,理论上就算被抓包,也无法对数据进行篡改;但是我们要知道加密的部分其实只是在外网,现在很多服务在内网中都需要经过很多服务跳转,所以这里的加签可以防止内网中数据被篡改; 3.时间戳机制 数据是很容易被抓包的,但是经过如上的加密,加签处理,就算拿到数据也不能看到真实的数据;但是有不法者不关心真实的数据,而是直接拿到抓取的数据包进行恶意请求

雪花算法生成id

南笙酒味 提交于 2019-12-05 07:04:46
1、新建一个id生成的类 SnowFlake /** * @Auther: lyl * @Date: 2019/11/21 17:49 * @Description: */ public class SnowFlake { /** * 起始的时间戳 */ private final static long START_STMP = 1480166465631L; /** * 每一部分占用的位数 */ private final static long SEQUENCE_BIT = 12; //序列号占用的位数 private final static long MACHINE_BIT = 5; //机器标识占用的位数 private final static long DATACENTER_BIT = 5;//数据中心占用的位数 /** * 每一部分的最大值 */ private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT); private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT); private final static long MAX_SEQUENCE = -1L ^ (-1L <<

如何设计一个安全的对外接口

ぃ、小莉子 提交于 2019-12-05 02:58:36
前言 最近有个项目需要对外提供一个接口,提供公网域名进行访问,而且接口和交易订单有关,所以安全性很重要;这里整理了一下常用的一些安全措施以及具体如何去实现。 安全措施 个人觉得安全措施大体来看主要在两个方面,一方面就是如何保证数据在传输过程中的安全性,另一个方面是数据已经到达服务器端,服务器端如何识别数据,如何不被攻击;下面具体看看都有哪些安全措施。 1.数据加密 我们知道数据在传输过程中是很容易被抓包的,如果直接传输比如通过http协议,那么用户传输的数据可以被任何人获取;所以必须对数据加密,常见的做法对关键字段加密比如用户密码直接通过md5加密;现在主流的做法是使用https协议,在http和tcp之间添加一层加密层(SSL层),这一层负责数据的加密和解密; 2.数据加签 数据加签就是由发送者产生一段无法伪造的一段数字串,来保证数据在传输过程中不被篡改;你可能会问数据如果已经通过https加密了,还有必要进行加签吗?数据在传输过程中经过加密,理论上就算被抓包,也无法对数据进行篡改;但是我们要知道加密的部分其实只是在外网,现在很多服务在内网中都需要经过很多服务跳转,所以这里的加签可以防止内网中数据被篡改; 3.时间戳机制 数据是很容易被抓包的,但是经过如上的加密,加签处理,就算拿到数据也不能看到真实的数据;但是有不法者不关心真实的数据,而是直接拿到抓取的数据包进行恶意请求

分布式雪花算法

匿名 (未验证) 提交于 2019-12-02 23:42:01
public class SnowFlake { /** * 起始的时间戳 */ private final static long START_STMP = 1480166465631L; /** * 每一部分占用的位数 */ private final static long SEQUENCE_BIT = 12; //序列号占用的位数 private final static long MACHINE_BIT = 5; //机器标识占用的位数 private final static long DATACENTER_BIT = 5;//数据中心占用的位数 /** * 每一部分的最大值 */ private final static long MAX_DATACENTER_NUM = -1L ^ (-1L << DATACENTER_BIT); private final static long MAX_MACHINE_NUM = -1L ^ (-1L << MACHINE_BIT); private final static long MAX_SEQUENCE = -1L ^ (-1L << SEQUENCE_BIT); /** * 每一部分向左的位移 */ private final static long MACHINE_LEFT = SEQUENCE_BIT;