专栏电商日志财经减肥爱情
投稿投诉
爱情常识
搭配分娩
减肥两性
孕期塑形
财经教案
论文美文
日志体育
养生学堂
电商科学
头戴业界
专栏星座
用品音乐

上千star的分布式ID生产黑科技,开箱即用,附源码

  sequence介绍
  sequence是一个基于雪花算法(Snowflake)实现的64位自增ID算法,实现语言是JAVA。
  其在雪花算法的基础上,做了一些优化,解决了原生算法的一些痛点:支持用户自定义允许时间回拨的范围;解决了跨毫秒时起始值从0开始增长的问题;解决了高并发场景中获取时间戳性能的问题;
  雪花算法的介绍可以参考博主上篇文章:还在用数据库自增ID做主键?建议了解一下雪花算法生成的分布式ID性能
  从官方的性能测试数据来看,sequence每秒可以生成最多418万个有序的ID,即TPS400ws,已经基本满足绝大部分的业务场景。
  源代码及使用
  核心代码一共两个类,分别是Sequence。java和SystemClock。java。
  Sequence是产生分布式ID的核心,SystemClock主要解决了高并发场景下System。currentTimeMills()的性能问题。
  大家也可根据自己的需要,修改其中的部署属性值,比如自定义机器标识,起始时间戳等。
  Sequence。java:publicclassSequence{privatestaticfinalLoggerlogLoggerFactory。getLogger(Sequence。class);时间起始标记点,作为基准,一般取系统的最近时间一旦确定不能变动,确定后改变此值可能造成id重复privatefinallongtwepoch1519740777809L;5位的机房idprivatefinallongdatacenterIdBits5L;5位的机器idprivatefinallongworkerIdBits5L;每毫秒内产生的id数:2的12次方个privatefinallongsequenceBits12L;protectedfinallongmaxDatacenterId1L(1LdatacenterIdBits);protectedfinallongmaxWorkerId1L(1LworkerIdBits);privatefinallongworkerIdShiftsequenceBits;privatefinallongdatacenterIdShiftsequenceBitsworkerIdBits;privatefinallongtimestampLeftShiftsequenceBitsworkerIdBitsdatacenterIdBits;privatefinallongsequenceMask1L(1LsequenceBits);所属机房idprivatefinallongdatacenterId;所属机器idprivatefinallongworkerId;并发控制序列privatelongsequence0L;上次生产ID时间戳privatelonglastTimestamp1L;获取IPprivatestaticvolatileInetAddressLOCALADDRESSnull;privatestaticfinalPatternIPPATTERNPattern。compile(d{1,3}(。d{1,3}){3,5}34;);默认的无参构造publicSequence(){this。datacenterIdgetDatacenterId();this。workerIdgetMaxWorkerId(datacenterId);}有参构造器,我们可以自定义机器id和机房idpublicSequence(longworkerId,longdatacenterId){if(workerIdmaxWorkerIdworkerId0){thrownewIllegalArgumentException(String。format(WorkerIdcantbegreaterthandorlessthan0,maxWorkerId));}if(datacenterIdmaxDatacenterIddatacenterId0){thrownewIllegalArgumentException(String。format(DatacenterIdcantbegreaterthandorlessthan0,maxDatacenterId));}this。workerIdworkerId;this。datacenterIddatacenterId;}基于网卡MAC地址计算余数作为数据中心,如果不想用网卡可以自定义protectedlonggetDatacenterId(){longid0L;try{NetworkInterfacenetworkNetworkInterface。getByInetAddress(getLocalAddress());if(nullnetwork){id1L;}else{byte〔〕macnetwork。getHardwareAddress();if(null!mac){id((0x000000FF(long)mac〔mac。length2〕)(0x0000FF00(((long)mac〔mac。length1〕)8)))6;idid(maxDatacenterId1);}}}catch(Exceptione){log。warn(getDatacenterId:e。getMessage());}returnid;}基于MACPID的hashcode获取16个低位protectedlonggetMaxWorkerId(longdatacenterId){StringBuildermpIdnewStringBuilder();mpId。append(datacenterId);StringnameManagementFactory。getRuntimeMXBean()。getName();if(name!nullname。length()0){GETjvmPidmpId。append(name。split()〔0〕);}MACPID的hashcode获取16个低位return(mpId。toString()。hashCode()0xffff)(maxWorkerId1);}获取下一个IDpublicsynchronizedlongnextId(){获取当前时间戳,这里通过SystemClock优化获取性能longtimestamptimeGen();时间回拨了if(timestamplastTimestamp){longoffsetlastTimestamptimestamp;if(offset5){try{休眠双倍差值后重新获取,再次校验wait(offset1);timestamptimeGen();if(timestamplastTimestamp){thrownewRuntimeException(String。format(Clockmovedbackwards。Refusingtogenerateidfordmilliseconds,offset));}}catch(Exceptione){thrownewRuntimeException(e);}}else{thrownewRuntimeException(String。format(Clockmovedbackwards。Refusingtogenerateidfordmilliseconds,offset));}}if(lastTimestamptimestamp){相同毫秒内,序列号自增sequence(sequence1)sequenceMask;if(sequence0){同一毫秒的序列数已经达到最大timestamptilNextMillis(lastTimestamp);}}else{不同毫秒内,序列号置为13随机数sequenceThreadLocalRandom。current()。nextLong(1,3);}lastTimestamptimestamp;时间戳部分数据中心部分机器标识部分序列号部分return((timestamptwepoch)timestampLeftShift)(datacenterIddatacenterIdShift)(workerIdworkerIdShift)sequence;}protectedlongtilNextMillis(longlastTimestamp){longtimestamptimeGen();while(timestamplastTimestamp){timestamptimeGen();}returntimestamp;}protectedlongtimeGen(){returnSystemClock。INSTANCE。currentTimeMillis();}FindfirstvalidIPfromlocalnetworkcardreturnfirstvalidlocalIPpublicstaticInetAddressgetLocalAddress(){if(LOCALADDRESS!null){returnLOCALADDRESS;}LOCALADDRESSgetLocalAddress0();returnLOCALADDRESS;}privatestaticInetAddressgetLocalAddress0(){InetAddresslocalAddressnull;try{localAddressInetAddress。getLocalHost();if(isValidAddress(localAddress)){returnlocalAddress;}}catch(Throwablee){log。warn(Failedtoretrievingipaddress,e。getMessage(),e);}try{EnumerationNetworkInterfaceinterfacesNetworkInterface。getNetworkInterfaces();if(interfaces!null){while(interfaces。hasMoreElements()){try{NetworkInterfacenetworkinterfaces。nextElement();EnumerationInetAddressaddressesnetwork。getInetAddresses();while(addresses。hasMoreElements()){try{InetAddressaddressaddresses。nextElement();if(isValidAddress(address)){returnaddress;}}catch(Throwablee){log。warn(Failedtoretrievingipaddress,e。getMessage(),e);}}}catch(Throwablee){log。warn(Failedtoretrievingipaddress,e。getMessage(),e);}}}}catch(Throwablee){log。warn(Failedtoretrievingipaddress,e。getMessage(),e);}log。error(Couldnotgetlocalhostipaddress,willuse127。0。0。1instead。);returnlocalAddress;}privatestaticbooleanisValidAddress(InetAddressaddress){if(addressnulladdress。isLoopbackAddress()){returnfalse;}Stringnameaddress。getHostAddress();return(name!null!0。0。0。0。equals(name)!127。0。0。1。equals(name)IPPATTERN。matcher(name)。matches());}}
  SystemClock。java:利用ScheduledExecutorService实现高并发场景下System。curentTimeMillis()的性能问题的优化。publicenumSystemClock{INSTANCE(1);privatefinallongperiod;privatefinalAtomicLongnowTime;privatebooleanstartedfalse;privateScheduledExecutorServiceexecutorService;SystemClock(longperiod){this。periodperiod;this。nowTimenewAtomicLong(System。currentTimeMillis());}publicvoidinitialize(){if(started){return;}this。executorServicenewScheduledThreadPoolExecutor(1,r{ThreadthreadnewThread(r,systemclock);thread。setDaemon(true);returnthread;});executorService。scheduleAtFixedRate(()nowTime。set(System。currentTimeMillis()),this。period,this。period,TimeUnit。MILLISECONDS);Runtime。getRuntime()。addShutdownHook(newThread(this::destroy));startedtrue;}publiclongcurrentTimeMillis(){returnstarted?nowTime。get():System。currentTimeMillis();}publicStringcurrentTime(){returnnewTimestamp(currentTimeMillis())。toString();}publicvoiddestroy(){if(executorService!null){executorService。shutdown();}}}最后
  sequence虽然大幅提升了性能,但是在某些情况下仍然可能出现重复的情况,比如机器标识重复、起始时间戳被修改重置等,这些问题需要我们特别注意。
  总得来说,sequence被称为分布式高效ID生产黑科技并不为过,著名的ORM框架mybatisplus用的也是这个组件,大家有兴趣也可以去了解一下。
  头条创作挑战赛
  学习技术,分享技术,期待与大家共同进步,也感谢您的点赞与关注。

过年丨阿里披露平台数据热腾腾的团圆经济回来了1月20日,市民在江苏省如皋市如城街道的一家年货集市上选购节庆用品。(吴树建摄)新华社北京1月21日电(记者叶心可)作为我国疫情防控进入新阶段后迎来的首个春节,据预计今年春运客流总2023年新能源车的11个趋势丨南财号联播mpId1662022年中国经济数据出炉GDP达121。02万亿元,同比增长31月17日,国家统计局发布的2022年经济数据。初步核算,全年国内生产总值1210207亿元,按不变价陕西工会搭建平台助推职工技术创新1月3日,由三秦工匠国网陕西省电力有限公司榆林供电公司运维检修部状态评价班班长豆河伟牵头的一体化配网带电清洗喷涂检测机器人项目,获得2022年度职工创新补助资金20万元。这是豆河伟美文欣赏望春(写在除夕前夜)作者东方春晓跌跌撞撞的日子,除了心累,还有周身凉透的悸动。比想象更困难的时刻,真想有一个温暖的怀抱,呵护周全,避进怡然与安全的港湾。再漫长的日子也要走过,无论青春结伴,还是暮年孤往徜徉在古城大同的暮色里压题图片徜徉在古城大同的暮色里我的山西之旅第四十八集山东昌乐刘福新题目拟好之后,想写一篇不长的散文,就用百度搜索自己的文章,但翻阅了好长时间,彼时所有背景皆不相同,如何写得出?只想早安,花瑶!我的2023年旅游计划晨光下的隆回花瑶(实拍)2023年央视春晚名单公布,湖南的好抖友们疯狂推送早安,隆回要上春晚!我把目录查出来一看,修改版的早安,阳光果然在列。春晚名单我赶紧艾来赣州过客家年春节门票免费送!开启童年回忆之旅!来赣州石城过客家年2023年石城县迎新春活动预告来啦!石城文旅回顾2022精彩足迹,携手展望2023!你是否喜欢这样的画面浪漫阳光草地萌宠游艺如果还有一群萌宠追着你跑那大概是梦里的秋高气爽山西行三9月22日上午我们赴山西旅行团,游览了大同市的古城墙,又去了大同市内的华严寺和九龙壁景区。中午饭后我们离开了大同市,去了山西忻州代县的雁门关。雁门关位于忻州代县的勾注山上,是长城上新年新游到即墨古城解锁不一样的新年人间烟火处,年味渐浓时。旧岁将辞,新春将至,来即墨古城,逛庙会赏花灯品美食看演绎听戏剧观民俗年味足氛围浓,解锁不一样的兔年新春!2023年1月22日(正月初一)至2023年2月5日正月初一至初六!唐山公交开通2条春节专线2023年新春佳节唐山公交将开通2条春节专线为丰富唐山市民春节期间的文化娱乐生活,满足市民新春佳节游玩出行需求,公交总公司拟于2023年1月22日至27日(正月初一至初六)开通春节2023春节假期目的地为西安的订单量同比增长375兔年新春佳节临近,伴随着人们探亲访友休闲娱乐出行旅游的高峰期,国内旅游市场复苏期或将迎来重大转折点。近日,文化和旅游部开展打卡旅游休闲打开欢乐春节2023年新春旅游休闲宣传推广活动
短道速滑世锦赛开赛,中国队单项悉数晋级3月10日,2023年短道速滑世锦赛在韩国首尔开赛,中国选手在首日个单项赛中悉数晋级,顺利拿到明年世锦赛全部个人单项每项两个参赛名额。接力项目中,中国男队和混合团体接力进入半决赛,一觉醒来,中国男足出线了?!2023年U20男足亚洲杯正在乌兹别克斯坦进行。9日晚上小组赛第三轮,U20中国队11战平吉尔吉斯斯坦队,成功从死亡之组出线!这是U20国足时隔9年,再次打进U20亚洲杯淘汰赛。第尘埃落定!中国男足被亚足联禁赛悬念揭晓,队长回应你们随便查U20亚洲杯即将开打4场8强战,中国男足跟韩国男足的比赛于明晚18点开打,胜者晋级2023年世青赛。不过,赛前网传中国男足可能会被亚足联禁赛,因为前几日有人晒图质疑队长艾菲尔丁的年56!澳大利亚遭淘汰,U20亚洲杯4强决出2席,中国男足企盼克韩晋级北京时间3月12日凌晨,U20亚洲杯14决赛迎来焦点对决,东道主乌兹别克斯坦对阵澳大利亚,双方的胜者将晋级半决赛并获得世青赛决赛阶段资格。双方在上半场都未能进球,下半场,加布里埃尔字母哥本赛季下滑了吗?ESPN专家KevinPelton今日回答球迷提问为什么本赛季扬尼斯阿德托孔博在数据上的统治力和他的高阶数据并不匹配,他下滑了吗?这个两届MVP球员本赛季场均数据为生涯最佳,场均3塞尔达传说之旷野之息全神庙位置(五)塔邦挞之塔塞尔达传说中的海拉鲁王国全图主线神庙共有120个,其中有42个是有前置任务的神庙。本文将按照主线任务开塔及地图点亮的顺序,逐一列出神庙的位置。六塔邦挞之塔6个神庙1提纳裘扎神庙力之本赛季哈登果真不具备全明星实力?事实非然,只是成功转型而已如果一个NBA球星单靠超强得分表现就能夺冠的话,那么哈登早已摆脱无冠宿命了。遥想当年休斯敦火箭时期,当每一个夜晚哈登火力全开动辄砍下4050得分,当他贡献一场场得分饕餮盛宴之后,甚别出心裁的宇宙飞船发射方式,用深海高压为航天发射提供初始动力美国液压气动加速器公司的业余火箭设计爱好者斯特科。泰勒最近提出一种别出心栽的发射宇宙飞船的新方法,他认为可以利用深海的高压和压缩空气制造海洋宇宙飞船发射井来发射宇宙飞船,从而大大节曾莲英代表建议完善导游底薪制,增强导游职业吸引力凝聚力今年全国两会,全国人大代表衡阳市南岳区南岳衡山导游讲解服务中心导游曾莲英提交了关于加强导游队伍建设管理推动文旅产业高质量发展的建议(以下简称建议)。建议指出,疫情过后,中国旅游业即地球已经诞生45亿年了,它的寿命究竟还有多长呢?地球已经诞生45亿年了,那么,它的寿命究竟有多长呢?目前科学界认为,地球的寿命取决于多种因素,包括太阳的寿命地球轨道稳定性地球磁场的变化行星碰撞等等。太阳的寿命是地球寿命的重要因素为什么火星上的山那么高,而地球上的山峰最高也无法超过9000米?因为地球与火星存在一定的差异。第一,因为地球上的大气圈气压较大,氧气浓度较高,水蒸气比例较高,有生物活动,有持续的板块活动与较为频繁的地震,所以风化作用比火星更强,地球岩石风化剥蚀
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网