当前位置: 首页 > news >正文

民间it网站建设网站建设海南

民间it网站建设,网站建设海南,医药企业网站设计制作,免费制作企业网站一#xff0c;背景 日常开发中#xff0c;我们需要对系统中的各种数据使用 ID 唯一表示#xff0c;比如用户 ID 对应且仅对应一个人#xff0c;商品 ID 对应且仅对应一件商品#xff0c;订单 ID 对应且仅对应 一个订单。我们现实生活中也有各种 ID #xff0c;比如身…一背景 日常开发中我们需要对系统中的各种数据使用 ID 唯一表示比如用户 ID 对应且仅对应一个人商品 ID 对应且仅对应一件商品订单 ID 对应且仅对应 一个订单。我们现实生活中也有各种 ID 比如身份证 ID 对应且仅对应一个人 简单来说ID 就是数据的唯一标识。 一般情况下会使用数据库的自增主键作为数据 ID 但是在大数量的情况 下我们往往会引入分布式、分库分表等手段来应对很明显对数据分库分表后 我们依然需要有一个唯一 ID 来标识一条数据或消息数据库的自增 ID 已经无法 满足需求。此时一个能够生成全局唯一 ID 的系统是非常必要的。概括下来那 业务系统对 ID 号的要求有哪些呢 全局唯一性不能出现重复的 ID 号既然是唯一标识这是最基本的要求。 趋势递增、 单调递增 保证下一个 ID 一定大于上一个 ID 。 信息安全如果 ID 是连续的恶意用户的扒取工作就非常容易做了直接按照顺序下载指定 URL 即可如果是订单号就更危险了竞对可以直接知道我们一天的单量。所以在一些应用场景下会需要 ID 无规则、不规则。 同时除了对 ID 号码自身的要求业务还对 ID 号生成系统的可用性要求极高想象一下如果 ID 生成系统不稳定大量依赖 ID 生成系统比如订单生成等关键动作都无法执行。所以一个 ID 生成系统还需要做到平均延迟和 TP999 延迟都要尽可能低可用性 5 个 9 高 QPS 。 二常见方法介绍 2.1 UUID UUID(Universally Unique Identifier)的标准型式包含 32 个 16 进制数字以连字号分为五段形式为 8-4-4-4-12 的 36 个字符示例550e8400-e29b-41d4-a716-446655440000。 2.1.1 优点 性能非常高本地生成没有网络消耗。 2.1.2 缺点 不易于存储UUID 太长16 字节 128 位通常以 36 长度的字符串表示很多场景不适用。 信息不安全基于 MAC 地址生成 UUID 的算法可能会造成 MAC 地址泄露这个漏洞曾被用于寻找梅丽莎病毒的制作者位置。 ID 作为主键时在特定的环境会存在一些问题比如做 DB 主键的场景下UUID就非常不适用 ① MySQL 官方有明确的建议主键要尽量越短越好[4]36 个字符长度的 UUID不符合要求。 ② 对 MySQL 索引不利如果作为数据库主键在 InnoDB 引擎下UUID 的无序性可能会引起数据位置频繁变动严重影响性能。在 MySQL InnoDB 引擎中使用的是聚集索引由于多数 RDBMS 使用 B-tree 的数据结构来存储索引数据在主键的选择上面我们应该尽量使用有序的主键保证写入性能。 可以直接使用 jdk 自带的 UUID原始生成的是带中划线的如果不需要可自行去除例如下面代码 public static void main(String[] args) {for (int i 0; i 5; i) {String rawUUID UUID.randomUUID().toString();//去除“-”String uuid rawUUID.replaceAll(-, );System.out.println(uuid);}} 2.2 雪花算法及其衍生 这种方案大致来说是一种以划分命名空间UUID 也算由于比较常见所以单独分析来生成 ID 的一种算法Snowflake 是 Twitter 开源的分布式 ID 生成算法。Snowflake 把 64-bit 分别划分成多段分开来标示机器、时间等比如在 snowflake 中的 64-bit 分别表示如下图所示 第 0 位 符号位标识正负始终为 0没有用不用管。第 1~41 位 一共 41 位用来表示时间戳单位是毫秒可以支撑 2 ^41毫秒约 69 年         第 42~52 位 一共 10 位一般来说前 5 位表示机房 ID后 5 位表示机器 ID实际项目中可以根据实际情况调整这样就可以区分不同集群/机房的节点这样就可以表示 32 个 IDC每个 IDC 下可以有 32 台机器。         第 53~64 位 一共 12 位用来表示序列号。 序列号为自增值代表单台机器每毫秒能够产生的最大 ID 数(2^12 4096),也就是说单台机器每毫秒最多可以生成 4096 个 唯一 ID。 理论上 snowflake 方案的 QPS 约为 409.6w/s这种分配方式可以保证在任何一个 IDC 的任何一台机器在任意毫秒内生成的 ID 都是不同的。 三 分布式 ID 微服务 从上面的分析可以看出每种方案都各有优劣我们现在参考美团 Leaf 方案实现自己的分布式Id。 3.1 美团 Leaf 方案实现 原 MySQL 方案每次获取 ID 都得读写一次数据库造成数据库压力大。改为批量获取每次获取一个 segment(step 决定大小)号段的值。用完之后再去数据库获取新的号段可以大大的减轻数据库的压力。 3.1.1 优点 Leaf 服务可以很方便的线性扩展性能完全能够支撑大多数业务场景。ID 号码是趋势递增的 8byte 的 64 位数字满足上述数据库存储的主键要求。         容灾性高Leaf 服务内部有号段缓存即使 DB 宕机短时间内 Leaf 仍能正常对外提供服务。         可以自定义 max_id 的大小非常方便业务从原有的 ID 方式上迁移过来。 3.1.2 缺点 ID 号码不够随机能够泄露发号数量的信息不太安全。         TP999 数据波动大当号段使用完之后还是会在获取新号段时在更新数据库的 I/O 依然会存在着等待tg999 数据会出现偶尔的尖刺。         DB 宕机会造成整个系统不可用。 3.1.3 优化 Leaf 取号段的时机是在号段消耗完的时候进行的也就意味着号段临界点的 ID 下发时间取决于下一次从 DB 取回号段的时间并且在这期间进来的请求也会因为 DB 号段没有取回来导致线程阻塞。如果请求 DB 的网络和 DB 的性能稳定这种情况对系统的影响是不大的但是假如取 DB 的时候网络发生抖动或者 DB 发生慢查询就会导致整个系统的响应时间变慢。         为此希望 DB 取号段的过程能够做到无阻塞不需要在 DB 取号段的时候阻塞请求线程即当号段消费到某个点时就异步的把下一个号段加载到内存中。而不需要等到号段用尽的时候才去更新号段。这样做就可以很大程度上的降低系统的 TP999 指标。         采用双 buffer 的方式Leaf 服务内部有两个号段缓存区 segment。当前号段已下发 10%时如果下一个号段未更新则另启一个更新线程去更新下一个号段。当前号段全部下发完后如果下个号段准备好了则切换到下个号段为当前segment 接着下发循环往复。通常推荐 segment 长度设置为服务高峰期发号 QPS 的 600 倍10 分钟这样即使 DB 宕机Leaf 仍能持续发号 10-20 分钟不受影响。每次请求来临时都会判断下个号段的状态从而更新此号段所以偶尔的网络抖动不会影响下个号段的更新。 四分布式id实战 数据库配置 CREATE DATABASE qiyu_live_common CHARACTER set utf8mb3 COLLATEutf8_bin;CREATE TABLE t_id_generate_config (id int NOT NULL AUTO_INCREMENT COMMENT 主键 id,remark varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 描述,next_threshold bigint DEFAULT NULL COMMENT 当前 id 所在阶段的阈 值,init_num bigint DEFAULT NULL COMMENT 初始化值,current_start bigint DEFAULT NULL COMMENT 当前 id 所在阶段的开始 值,step int DEFAULT NULL COMMENT id 递增区间,is_seq tinyint DEFAULT NULL COMMENT 是否有序0 无序1 有序,id_prefix varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 业务前缀码如果没有则返回 时不携带,version int NOT NULL DEFAULT 0 COMMENT 乐观锁版本号,create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 创建时 间,update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间,PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT8 DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci; 插入记录 INSERT INTO t_id_generate_config (id, remark, next_threshold, init_num, current_start, step, is_seq, id_prefix, version, create_time, update_time) VALUES(1, 用户 id 生成策略, 10050, 10000, 10000, 50, 0, user_id, 0, 2023-05-23 12:38:21, 2023-05-23 23:31:45); 搭建springboot项目和配置文件 1.创建两个maven并导入maven依赖 导入maven依赖 dependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependencydependencygroupIdorg.apache.dubbo/groupIdartifactIddubbo-spring-boot-starter/artifactIdversion${dubbo.version}/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactIdexclusionsexclusionartifactIdlog4j-to-slf4j/artifactIdgroupIdorg.apache.logging.log4j/groupId/exclusion/exclusions/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion${qiyu-mysql.version}/version/dependencydependencygroupIdcom.alibaba.cloud/groupIdartifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId/dependencydependencygroupIdorg.idea/groupIdartifactIdqiyu-live-id-generate-interface/artifactIdversion1.0-SNAPSHOT/versionscopecompile/scope/dependency 配置文件 spring:application:name: qiyu-live-id-generate-providerdatasource:driver-class-name: com.mysql.cj.jdbc.Driver# 访问主库url: jdbc:mysql://192.168.1.128:8808/qiyu_live_common?useUnicodetruecharacterEncodingutf8username: rootpassword: root 在下面模块生成基本配置策略枚举和对外接口 创建id生成策略枚举类 package org.qiyu.live.id.generate.enums;/*** Author idea* Date: Created in 17:55 2023/6/13* Description*/ public enum IdTypeEnum {USER_ID(1,用户id生成策略);int code;String desc;IdTypeEnum(int code, String desc) {this.code code;this.desc desc;}public int getCode() {return code;}public String getDesc() {return desc;} }生成对外接口方法 package org.qiyu.live.id.generate.interfaces;/*** Author idea* Date: Created in 19:45 2023/5/25* Description*/ public interface IdGenerateRpc {/*** 获取有序id** param id* return*/Long getSeqId(Integer id);/*** 获取无序id** param id* return*/Long getUnSeqId(Integer id);}接下来在id生成模块实现 创建数据库po类这里就是数据库id配置策略表 package com.laoyang.id.dao.po;import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName;import java.util.Date;/*** Author idea* Date: Created in 19:59 2023/5/23* Description*/ TableName(t_id_gengrate_config) public class IdGeneratePO {TableId(type IdType.AUTO)private Integer id;/*** id备注描述*/private String remark;/*** 初始化值*/private long initNum;/*** 步长*/private int step;/*** 是否是有序的id*/private int isSeq;/*** 当前id所在阶段的开始值*/private long currentStart;/*** 当前id所在阶段的阈值*/private long nextThreshold;/*** 业务代码前缀*/private String idPrefix;/*** 乐观锁版本号*/private int version;private Date createTime;private Date updateTime;public int getId() {return id;}public void setId(int id) {this.id id;}public String getRemark() {return remark;}public void setRemark(String remark) {this.remark remark;}public long getInitNum() {return initNum;}public void setInitNum(long initNum) {this.initNum initNum;}public int getStep() {return step;}public void setStep(int step) {this.step step;}public long getCurrentStart() {return currentStart;}public void setCurrentStart(long currentStart) {this.currentStart currentStart;}public long getNextThreshold() {return nextThreshold;}public void setNextThreshold(long nextThreshold) {this.nextThreshold nextThreshold;}public String getIdPrefix() {return idPrefix;}public void setIdPrefix(String idPrefix) {this.idPrefix idPrefix;}public int getVersion() {return version;}public void setVersion(int version) {this.version version;}public Date getCreateTime() {return createTime;}public void setCreateTime(Date createTime) {this.createTime createTime;}public Date getUpdateTime() {return updateTime;}public void setUpdateTime(Date updateTime) {this.updateTime updateTime;}public int getIsSeq() {return isSeq;}public void setIsSeq(int isSeq) {this.isSeq isSeq;}Overridepublic String toString() {return IdGeneratePO{ id id , remark remark \ , initNum initNum , step step , isSeq isSeq , currentStart currentStart , nextThreshold nextThreshold , idPrefix idPrefix \ , version version , createTime createTime , updateTime updateTime };} } 生成mapper映射类注意插入加入了乐观锁注意这个sql package com.laoyang.id.dao.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import com.laoyang.id.dao.po.IdGeneratePO;import java.util.List;/*** Author idea* Date: Created in 19:47 2023/5/25* Description*/ Mapper public interface IdGenerateMapper extends BaseMapperIdGeneratePO {Update(update t_id_gengrate_config set next_thresholdnext_thresholdstep, current_startcurrent_startstep,versionversion1 where id #{id} and version#{version})int updateNewIdCountAndVersion(Param(id)int id,Param(version)int version);Select(select * from t_id_gengrate_config)ListIdGeneratePO selectAll(); }在service下创建bo类生成有序id和无序id对象 package com.laoyang.id.service.bo;import java.util.concurrent.atomic.AtomicLong;/*** Author idea* Date: Created in 20:00 2023/5/25* Description 有序id的BO对象*/ public class LocalSeqIdBO {private int id;/*** 在内存中记录的当前有序id的值*/private AtomicLong currentNum;/*** 当前id段的开始值*/private Long currentStart;/*** 当前id段的结束值*/private Long nextThreshold;public int getId() {return id;}public void setId(int id) {this.id id;}public AtomicLong getCurrentNum() {return currentNum;}public void setCurrentNum(AtomicLong currentNum) {this.currentNum currentNum;}public Long getCurrentStart() {return currentStart;}public void setCurrentStart(Long currentStart) {this.currentStart currentStart;}public Long getNextThreshold() {return nextThreshold;}public void setNextThreshold(Long nextThreshold) {this.nextThreshold nextThreshold;} }package com.laoyang.id.service.bo;import java.util.concurrent.ConcurrentLinkedQueue;/*** Author idea* Date: Created in 20:32 2023/5/26* Description 无序id的BO对象*/ public class LocalUnSeqIdBO {private int id;/*** 提前将无序的id存放在这条队列中*/private ConcurrentLinkedQueueLong idQueue;/*** 当前id段的开始值*/private Long currentStart;/*** 当前id段的结束值*/private Long nextThreshold;public int getId() {return id;}public void setId(int id) {this.id id;}public ConcurrentLinkedQueueLong getIdQueue() {return idQueue;}public void setIdQueue(ConcurrentLinkedQueueLong idQueue) {this.idQueue idQueue;}public Long getCurrentStart() {return currentStart;}public void setCurrentStart(Long currentStart) {this.currentStart currentStart;}public Long getNextThreshold() {return nextThreshold;}public void setNextThreshold(Long nextThreshold) {this.nextThreshold nextThreshold;} }生成service类生成有序id与无序id package com.laoyang.id.service;/*** Author idea* Date: Created in 19:58 2023/5/25* Description*/ public interface IdGenerateService {/*** 获取有序id** param id* return*/Long getSeqId(Integer id);/*** 获取无序id** param id* return*/Long getUnSeqId(Integer id); }实现有序id和无序id方法这里是关键主要用到了原子类一些同步类操作等等线程池 package com.laoyang.id.service.impl;import jakarta.annotation.Resource; import com.laoyang.id.dao.mapper.IdGenerateMapper; import com.laoyang.id.dao.po.IdGeneratePO; import com.laoyang.id.service.IdGenerateService; import com.laoyang.id.service.bo.LocalSeqIdBO; import com.laoyang.id.service.bo.LocalUnSeqIdBO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.stereotype.Service;import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicLong;/*** Author idea* Date: Created in 19:58 2023/5/25* Description*/ Service public class IdGenerateServiceImpl implements IdGenerateService, InitializingBean {Resourceprivate IdGenerateMapper idGenerateMapper;private static final Logger LOGGER LoggerFactory.getLogger(IdGenerateServiceImpl.class);private static MapInteger, LocalSeqIdBO localSeqIdBOMap new ConcurrentHashMap();private static MapInteger, LocalUnSeqIdBO localUnSeqIdBOMap new ConcurrentHashMap();private static ThreadPoolExecutor threadPoolExecutor new ThreadPoolExecutor(8, 16, 3, TimeUnit.SECONDS, new ArrayBlockingQueue(1000),new ThreadFactory() {Overridepublic Thread newThread(Runnable r) {Thread thread new Thread(r);thread.setName(id-generate-thread- ThreadLocalRandom.current().nextInt(1000));return thread;}});private static final float UPDATE_RATE 0.50f;private static final int SEQ_ID 1;private static MapInteger, Semaphore semaphoreMap new ConcurrentHashMap();Overridepublic Long getUnSeqId(Integer id) {if (id null) {LOGGER.error([getSeqId] id is error,id is {}, id);return null;}LocalUnSeqIdBO localUnSeqIdBO localUnSeqIdBOMap.get(id);if (localUnSeqIdBO null) {LOGGER.error([getUnSeqId] localUnSeqIdBO is null,id is {}, id);return null;}Long returnId localUnSeqIdBO.getIdQueue().poll();if (returnId null) {LOGGER.error([getUnSeqId] returnId is null,id is {}, id);return null;}this.refreshLocalUnSeqId(localUnSeqIdBO);return returnId;}/**** param id 传的是对应的业务id* return*/Overridepublic Long getSeqId(Integer id) {if (id null) {LOGGER.error([getSeqId] id is error,id is {}, id);return null;}LocalSeqIdBO localSeqIdBO localSeqIdBOMap.get(id);if (localSeqIdBO null) {LOGGER.error([getSeqId] localSeqIdBO is null,id is {}, id);return null;}this.refreshLocalSeqId(localSeqIdBO);long returnId localSeqIdBO.getCurrentNum().incrementAndGet();if (returnId localSeqIdBO.getNextThreshold()) {//同步去刷新 可能是高并发下还未更新本地数据LOGGER.error([getSeqId] id is over limit,id is {}, id);return null;}return returnId;}/*** 刷新本地有序id段** param localSeqIdBO*/private void refreshLocalSeqId(LocalSeqIdBO localSeqIdBO) {long step localSeqIdBO.getNextThreshold() - localSeqIdBO.getCurrentStart();if (localSeqIdBO.getCurrentNum().get() - localSeqIdBO.getCurrentStart() step * UPDATE_RATE) {Semaphore semaphore semaphoreMap.get(localSeqIdBO.getId());if (semaphore null) {LOGGER.error(semaphore is null,id is {}, localSeqIdBO.getId());return;}boolean acquireStatus semaphore.tryAcquire();if (acquireStatus) {LOGGER.info(开始尝试进行本地id段的同步操作);//异步进行同步id段操作threadPoolExecutor.execute(new Runnable() {Overridepublic void run() {try {IdGeneratePO idGeneratePO idGenerateMapper.selectById(localSeqIdBO.getId());tryUpdateMySQLRecord(idGeneratePO);} catch (Exception e) {LOGGER.error([refreshLocalSeqId] error is , e);} finally {semaphoreMap.get(localSeqIdBO.getId()).release();LOGGER.info(本地有序id段同步完成,id is {}, localSeqIdBO.getId());}}});}}}/*** 刷新本地无序id段** param localUnSeqIdBO*/private void refreshLocalUnSeqId(LocalUnSeqIdBO localUnSeqIdBO) {long begin localUnSeqIdBO.getCurrentStart();long end localUnSeqIdBO.getNextThreshold();long remainSize localUnSeqIdBO.getIdQueue().size();//如果使用剩余空间不足25%则进行刷新if ((end - begin) * 0.35 remainSize) {LOGGER.info(本地无序id段同步开始id is {}, localUnSeqIdBO.getId());Semaphore semaphore semaphoreMap.get(localUnSeqIdBO.getId());if (semaphore null) {LOGGER.error(semaphore is null,id is {}, localUnSeqIdBO.getId());return;}boolean acquireStatus semaphore.tryAcquire();if (acquireStatus) {threadPoolExecutor.execute(new Runnable() {Overridepublic void run() {try {IdGeneratePO idGeneratePO idGenerateMapper.selectById(localUnSeqIdBO.getId());tryUpdateMySQLRecord(idGeneratePO);} catch (Exception e) {LOGGER.error([refreshLocalUnSeqId] error is , e);} finally {semaphoreMap.get(localUnSeqIdBO.getId()).release();LOGGER.info(本地无序id段同步完成id is {}, localUnSeqIdBO.getId());}}});}}}//bean初始化的时候会回调到这里Overridepublic void afterPropertiesSet() throws Exception {ListIdGeneratePO idGeneratePOList idGenerateMapper.selectAll();for (IdGeneratePO idGeneratePO : idGeneratePOList) {LOGGER.info(服务刚启动抢占新的id段);tryUpdateMySQLRecord(idGeneratePO);semaphoreMap.put(idGeneratePO.getId(), new Semaphore(1));}}/*** 更新mysql里面的分布式id的配置信息占用相应的id段* 同步执行很多的网络IO性能较慢** param idGeneratePO*/private void tryUpdateMySQLRecord(IdGeneratePO idGeneratePO) {int updateResult idGenerateMapper.updateNewIdCountAndVersion(idGeneratePO.getId(), idGeneratePO.getVersion());if (updateResult 0) {localIdBOHandler(idGeneratePO);return;}//重试进行更新for (int i 0; i 3; i) {idGeneratePO idGenerateMapper.selectById(idGeneratePO.getId());updateResult idGenerateMapper.updateNewIdCountAndVersion(idGeneratePO.getId(), idGeneratePO.getVersion());if (updateResult 0) {localIdBOHandler(idGeneratePO);return;}}throw new RuntimeException(表id段占用失败竞争过于激烈id is idGeneratePO.getId());}/*** 专门处理如何将本地ID对象放入到Map中并且进行初始化的** param idGeneratePO*/private void localIdBOHandler(IdGeneratePO idGeneratePO) {long currentStart idGeneratePO.getCurrentStart();long nextThreshold idGeneratePO.getNextThreshold();long currentNum currentStart;if (idGeneratePO.getIsSeq() SEQ_ID) {LocalSeqIdBO localSeqIdBO new LocalSeqIdBO();AtomicLong atomicLong new AtomicLong(currentNum);localSeqIdBO.setId(idGeneratePO.getId());localSeqIdBO.setCurrentNum(atomicLong);localSeqIdBO.setCurrentStart(currentStart);localSeqIdBO.setNextThreshold(nextThreshold);localSeqIdBOMap.put(localSeqIdBO.getId(), localSeqIdBO);} else {LocalUnSeqIdBO localUnSeqIdBO new LocalUnSeqIdBO();localUnSeqIdBO.setCurrentStart(currentStart);localUnSeqIdBO.setNextThreshold(nextThreshold);localUnSeqIdBO.setId(idGeneratePO.getId());long begin localUnSeqIdBO.getCurrentStart();long end localUnSeqIdBO.getNextThreshold();ListLong idList new ArrayList();for (long i begin; i end; i) {idList.add(i);}//将本地id段提前打乱然后放入到队列中Collections.shuffle(idList);ConcurrentLinkedQueueLong idQueue new ConcurrentLinkedQueue();idQueue.addAll(idList);localUnSeqIdBO.setIdQueue(idQueue);localUnSeqIdBOMap.put(localUnSeqIdBO.getId(), localUnSeqIdBO);}} }最后创建启动类 package com.laoyang.id;import jakarta.annotation.Resource; import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import com.laoyang.id.service.IdGenerateService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import java.util.HashSet;/*** Author idea* Date: Created in 19:45 2023/5/25* Description*/ SpringBootApplication public class IdGenerateApplication implements CommandLineRunner {private static final Logger LOGGER LoggerFactory.getLogger(IdGenerateApplication.class);Resourceprivate IdGenerateService idGenerateService;public static void main(String[] args) {SpringApplication springApplication new SpringApplication(IdGenerateApplication.class);springApplication.setWebApplicationType(WebApplicationType.NONE);springApplication.run(args);}Overridepublic void run(String... args) throws Exception {HashSetLong idSet new HashSet();for (int i 0; i 1500; i) {Long id idGenerateService.getSeqId(1);System.out.println(id);idSet.add(id);}System.out.println(idSet.size());} }最终会在控制台打印输出
http://www.w-s-a.com/news/628786/

相关文章:

  • 网站建设制度制定wordpress主题哥
  • 门户网站的种类php网站开发实训心得
  • 流程图制作网页网络优化seo
  • 个人公益网站怎么制作wordpress flat theme
  • 做营销型网站的公司篇高端网站愿建设
  • 五莲网站建设维护推广凡科做网站的方法
  • 山东省住房建设厅网站首页网站文章更新怎么通知搜索引擎
  • 商务网站的可行性分析包括大流量网站 优化
  • 推广网站有效的方法网站数据统计
  • 自建视频网站WordPress数据库添加管理员
  • 新民电商网站建设价格咨询网站建设高效解决之道
  • 做网站需要哪些步骤网站设计介绍
  • 物流网站制作目的国外中文网站排行榜单
  • 苏州网站建设招标网站ftp的所有权归谁
  • 未央免费做网站河间网站建设
  • 酒庄企业网站app制作多少钱一个
  • 西安模板建网站网站如何做直播轮播
  • 网站功能需求表百度怎么投放自己的广告
  • 如何免费制作网站网站icp备案费用
  • 网站建设最新教程wordpress表白墙
  • android电影网站开发网站建设与设计实习报告
  • 公司汇报网站建设方案烟台seo网站推广
  • 文章网站哪里建设好找素材的网站
  • 怎么做自己的彩票网站公司建设网站价格
  • 国外比较好的设计网站网站后台无法上传图片
  • 帮别人做网站的公司是外包吗用户登录
  • 关于我们网站模板小莉帮忙郑州阳光男科医院
  • 上海门户网站怎么登录永州网站制作
  • 微信网站模版下载做销售的去哪个网站应聘
  • 好看的个人博客主页长安网站优化公司