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

Redis实现分布式获取全局唯一自增ID的案例。

【1】简易自增版本(从 1 开始 1,2,3,...)

项目结构

下面是一个基于 RedisTemplate 实现的分布式全局唯一自增 ID 生成器的案例。适用于 Java Spring Boot 环境,利用 Redis 的原子操作 INCR 指令。

✅ 原理说明

Redis 提供的 INCR 命令是原子性的,可以确保在分布式环境下,每次调用都会返回一个唯一的递增数字,非常适合用作分布式系统的全局 ID。

📦 依赖(Spring Boot + Redis)

确保你的 pom.xml 包含如下依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

🧱 配置 RedisTemplate(可选,如果你使用的是默认配置可省略)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericToStringSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Long> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Long> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setValueSerializer(new GenericToStringSerializer<>(Long.class));return template;}
}

🔧 全局 ID 生成器类

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;@Component
public class RedisIdGenerator {private static final String REDIS_KEY_PREFIX = "global:id:";@Resourceprivate RedisTemplate<String, Long> redisTemplate;/*** 获取全局唯一递增 ID** @param key 业务模块(例如:order、user)* @return 唯一 ID*/public long getNextId(String key) {String redisKey = REDIS_KEY_PREFIX + key;return redisTemplate.opsForValue().increment(redisKey);}
}

🧪 使用示例

@RestController
@RequestMapping("/id")
public class IdController {@Autowiredprivate RedisIdGenerator redisIdGenerator;@GetMapping("/next")public String getNextId(@RequestParam(defaultValue = "order") String key) {long id = redisIdGenerator.getNextId(key);return "Generated ID for " + key + ": " + id;}
}

📝 示例返回

访问 GET /id/next?key=order 多次,你将看到递增的 ID:

Generated ID for order: 1
Generated ID for order: 2
Generated ID for order: 3
...

✅ 优势

  • 原子性强,天然分布式。
  • 持久化在 Redis 中,服务重启不丢失。
  • 支持多业务 key 分离。

【2】雪花算法混合模式

下面是一个 Redis + 雪花算法混合模式分布式唯一ID生成方案,它结合了:

  • 雪花算法(Snowflake):用于生成高性能、趋势递增的唯一ID;
  • Redis:用于动态分配和管理数据中心ID(dataCenterId)或机器ID(workerId),解决分布式部署时的节点冲突问题。

📌 背景:为什么混合

  • 雪花算法依赖机器ID、数据中心ID来避免节点之间ID重复;
  • 如果你部署在容器或弹性云环境中,静态配置workerId会冲突
  • Redis 分布式锁 + 自增值 动态生成 workerId/dataCenterId,可避免冲突。

✅ 雪花算法类(简化版)

public class SnowflakeIdGenerator {private final long workerId;private final long dataCenterId;private final long sequenceBits = 12L;private final long workerIdBits = 5L;private final long dataCenterIdBits = 5L;private final long maxWorkerId = -1L ^ (-1L << workerIdBits);private final long maxDataCenterId = -1L ^ (-1L << dataCenterIdBits);private final long workerIdShift = sequenceBits;private final long dataCenterIdShift = sequenceBits + workerIdBits;private final long timestampLeftShift = sequenceBits + workerIdBits + dataCenterIdBits;private final long sequenceMask = -1L ^ (-1L << sequenceBits);private long sequence = 0L;private long lastTimestamp = -1L;public SnowflakeIdGenerator(long workerId, long dataCenterId) {if (workerId > maxWorkerId || workerId < 0) {throw new IllegalArgumentException("workerId invalid");}if (dataCenterId > maxDataCenterId || dataCenterId < 0) {throw new IllegalArgumentException("dataCenterId invalid");}this.workerId = workerId;this.dataCenterId = dataCenterId;}public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {throw new RuntimeException("Clock moved backwards.");}if (lastTimestamp == timestamp) {sequence = (sequence + 1) & sequenceMask;if (sequence == 0) {timestamp = tilNextMillis(lastTimestamp);}} else {sequence = 0L;}lastTimestamp = timestamp;return ((timestamp - 1609459200000L) << timestampLeftShift)| (dataCenterId << dataCenterIdShift)| (workerId << workerIdShift)| sequence;}private long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}private long timeGen() {return System.currentTimeMillis();}
}

📦 Redis 动态分配 WorkerId / DataCenterId

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;@Component
public class RedisNodeIdAllocatorV1 {private static final String WORKER_ID_KEY = "snowflake:workerId";private static final String DATACENTER_ID_KEY = "snowflake:datacenterId";@Autowiredprivate RedisTemplate<String, String> redisTemplate;public long getWorkerId() {return redisTemplate.opsForValue().increment(WORKER_ID_KEY) % 32;}public long getDataCenterId() {return redisTemplate.opsForValue().increment(DATACENTER_ID_KEY) % 32;}
}

🧩 初始化与使用

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class SnowflakeIdServiceV1 {private final SnowflakeIdGenerator idGenerator;@Autowiredpublic SnowflakeIdServiceV1(RedisNodeIdAllocatorV1 allocator) {long workerId = allocator.getWorkerId();long dataCenterId = allocator.getDataCenterId();this.idGenerator = new SnowflakeIdGenerator(workerId, dataCenterId);}public long getNextId() {return idGenerator.nextId();}
}

📡 示例 Controller

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;@RestController
@RequestMapping("/SnowFlakeId")
public class SnowFlakeIdController {@Resourceprivate SnowflakeIdServiceV1 snowflakeIdService;@GetMapping("/next")public String getNextId() {return "Generated Snowflake ID: " + snowflakeIdService.getNextId();}
}

✅ 特点总结

功能

说明

高并发

每秒可生成数百万个唯一ID

无中心依赖

每个节点独立生成 ID(初始化通过 Redis 分配ID)

趋势递增

默认以时间戳为前缀,排序性好

Redis分配workerId

容器化部署时避免 ID 冲突

【3】按业务Key分组

🔁 设计目标

  • 支持多业务线(order、user、payment 等)各自独立生成分布式 ID;
  • 每个业务线通过 Redis 动态分配其专属的 workerIddataCenterId
  • 保证分布式部署下不会发生冲突;
  • 雪花 ID 趋势递增、唯一、安全。

✅ 步骤总览

✅ 1. Redis 节点分配器(支持按 key 分组)

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;import javax.annotation.Resource;@Component
public class RedisNodeIdAllocatorV2 {@Resourceprivate RedisTemplate<String, String> redisTemplate;public long getWorkerId(String bizKey) {return redisTemplate.opsForValue().increment("snowflake:" + bizKey + ":workerId") % 32;}public long getDataCenterId(String bizKey) {return redisTemplate.opsForValue().increment("snowflake:" + bizKey + ":datacenterId") % 32;}
}

✅ 2. 雪花生成器管理器(每个 key 一套生成器)

import com.example.client.redis_test.snowflake.SnowflakeIdGenerator;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Component
public class SnowflakeIdManager {@Resourceprivate RedisNodeIdAllocatorV2 allocator;private final Map<String, SnowflakeIdGenerator> generatorMap = new ConcurrentHashMap<>();public synchronized SnowflakeIdGenerator getGenerator(String bizKey) {return generatorMap.computeIfAbsent(bizKey, key -> {long workerId = allocator.getWorkerId(key);long dataCenterId = allocator.getDataCenterId(key);return new SnowflakeIdGenerator(workerId, dataCenterId);});}
}

✅ 3. 提供统一服务接口

import org.springframework.stereotype.Component;
import javax.annotation.Resource;@Component
public class SnowflakeIdServiceV2 {@Resourceprivate SnowflakeIdManager manager;public long getNextId(String bizKey) {return manager.getGenerator(bizKey).nextId();}
}

✅ 4. 示例 Controller(按业务 key 获取 ID)

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
@RestController
@RequestMapping("/SnowFlakeIdGroupByBiz")
public class SnowFlakeIdGroupByBizController {@Resourceprivate SnowflakeIdServiceV2 idService;@GetMapping("/next")public String getNextId(@RequestParam(defaultValue = "order") String key) {long id = idService.getNextId(key);return "Generated ID for [" + key + "]: " + id;}
}

🧪 示例

GET /id/next?key=order
→ Generated ID for [order]: 1487450731280013312GET /id/next?key=user
→ Generated ID for [user]: 1487450732081190912

🔐 注意事项

问题

解决方式

Redis中workerId过多

可以定期清理、或设计过期机制

workerId冲突

可加锁或用 setnx 保证唯一性(当前用 % 32

限定范围)

服务重启ID漂移

Snowflake 本身保证有序不重复,初始化动态分配

多业务混用

支持按 key 隔离;也可默认用 "default"

key

【4】Redis在生成全局ID中的作用?workerId 与dataCenterId 是什么?有什么作用?为什么这样设计就能是全局唯一?

我们逐一深入解析 Redis 在全局 ID 生成中的作用、workerIddataCenterId 的含义,以及它们如何确保 全局唯一性

✅ 一、Redis 在生成全局 ID 中的作用

在雪花算法中,每个节点都必须拥有一个**唯一标识(workerId 和 dataCenterId)**来防止生成相同的 ID。如果你是在容器、K8s 或弹性云部署中,节点 ID 难以静态配置。

Redis 在这里的核心作用是:动态分配全局唯一的 ID 节点标识

功能

说明

分布式节点注册

每个服务启动时,通过 Redis 获取属于自己的 workerId 和 dataCenterId

原子性递增

使用 Redis 的 INCR

保证每个节点获得唯一编号

避免 ID 冲突

让不同服务实例不会重复获取同一个 workerId/dataCenterId

✅ 二、workerId 和 dataCenterId 是什么?

📌 它们是雪花算法中的“节点编号”

雪花算法将一个 64 位 ID 拆分如下:

位数

字段名

描述

1

符号位

固定为 0

41

时间戳

当前时间戳(毫秒)减去自定义起始时间

5

dataCenterId

数据中心编号(最多支持 32 个)

5

workerId

每个数据中心下的机器编号(最多支持 32 个)

12

序列号

每毫秒最多支持 4096 个 ID

✅ 三、它们的作用和重要性

✳️ workerId、dataCenterId 的作用

  • 用于标识ID来源的节点和数据中心,防止多个节点生成重复的 ID;
  • 即使多个节点在同一毫秒内生成 ID,只要它们的 workerId 或 dataCenterId 不同,生成的 ID 也不会相同;
  • 它们与时间戳和序列号一起,组成了全局唯一且趋势递增的 ID

✅ 四、为什么这样设计就能保证全局唯一?

原因如下:

  1. 时间戳区分不同时间点的 ID
    • 基于当前时间毫秒级,保证大多数 ID 是有序递增的。
  1. workerId + dataCenterId 区分节点
    • 物理上多个节点并发生成 ID 时,通过这些编号做隔离。
  1. 序列号解决高并发同一节点冲突
    • 在同一毫秒内同一节点生成多个 ID,用序列号保证不重复(最多 4096 个)。
  1. 组合后无冲突
    • 一个 64 位整数中组合了这几个维度,因此生成的 ID 是分布式下全局唯一且趋势递增的。

✅ 图解(结构拆解)

0 | 41位时间戳 | 5位dataCenterId | 5位workerId | 12位序列号

例如:

字段

示例值

时间戳

1111111111111

dataCenterId

2

workerId

10

序列号

123

组合成 ID

7123889822724094976

✅ 补充:Redis 为何比配置文件或机器 IP 更可靠?

方式

缺点

静态配置(配置文件)

容器化部署中无法保证唯一性

机器 IP 推导

云环境中 IP 会变动,冲突风险高

Redis 统一分配

原子操作、集中控制,适合动态环境

【5】如果是在集群环境,生成雪花ID使用的是传统方案,没有使用Redis,意思是会有重复值吗?

在集群环境中使用传统雪花算法但没有额外机制(如 Redis、配置中心等)确保 workerIddataCenterId 唯一性,就存在生成重复 ID 的风险

✅ 原因:雪花算法本身不提供 workerId 唯一性的分配机制

传统雪花算法依赖以下两个关键配置:

参数

说明

范围

workerId

表示该机器在当前数据中心中的编号

0 ~ 31

dataCenterId

表示该机器所在的数据中心编号

0 ~ 31

这两个值必须在整个集群中是唯一的组合。否则:

  • 如果两台机器配置了相同的 workerId + dataCenterId
  • 并且它们在相同毫秒内生成 ID
  • 生成的雪花 ID 就会一模一样ID 冲突

🚨 举例说明:重复 ID 风险

假设有 2 个服务节点,均使用如下配置:

  • workerId = 3
  • dataCenterId = 1

这两个服务在同一毫秒内生成 ID:

long id1 = snowflake.nextId(); // 节点A生成
long id2 = snowflake.nextId(); // 节点B生成

➡️ 由于时间戳、workerId、dataCenterId 全都相同,只有最后的序列号不同,而序列号在每个节点是局部维护的,不共享。

因此,如果两个节点并发生成 ID 且序列号相同,结果就会冲突。

✅ 为什么 Redis(或其他注册中心)能解决这个问题?

方法

作用

Redis 动态分配 ID

启动时为每个实例分配唯一的 workerId

dataCenterId

Zookeeper / Etcd

注册服务并发放唯一节点标识

运维统一配置

每台机器预设不同 ID(不适合弹性环境)

这些机制都能避免节点在生成雪花 ID 时出现重复标识,从而保证全局唯一。

✅ 实战建议

场景

建议方案

静态服务器部署

可通过配置文件指定不同 workerId

容器/K8s/云原生弹性部署

推荐使用 Redis/Zookeeper 动态分配

节点数 > 1024 或分布广泛

推荐使用 Snowflake + Redis 组合方案

✅ 总结

❌ 不做唯一标识管理 = 集群中存在 ID 冲突风险
✅ 雪花算法 必须配合唯一的 workerIddataCenterId 分配机制(如 Redis),才能保障全局唯一

【6】传统算法中workerId 与dataCenterId 是怎么获取的?为什么代码没有显式进行分配workerId 与dataCenterId ?

在传统的雪花算法实现中,如果你没有显式设置 workerIddataCenterId,它们到底是怎么来的?是不是默默用了默认值?这会不会有问题?

✅ 一、传统雪花算法中 workerIddataCenterId 的获取方式

大多数开源或自定义的雪花算法实现有几种方式获取这两个值:

🚫 1. 默认值写死

很多实现中,如果你没有主动配置,它会直接给你写死:

private long workerId = 0L;
private long dataCenterId = 0L;

🧠 2. 根据机器 IP / MAC 地址计算(不推荐)

某些实现尝试根据 机器 IP、MAC 地址、主机名 做 hash,推导出这两个 ID:

this.workerId = getHash(IP/MAC/hostname) % 32;

优点:不用手动配置
缺点:不可靠!容器中 IP/MAC/hostname 常变化,不同节点可能得到相同的 ID,导致雪花 ID 冲突。

⚠️ 3. 使用 JVM 启动参数传入

某些框架(如美团的 Leaf、百度的 UidGenerator)支持:

-DworkerId=3 -DdataCenterId=1

但仍然需要你人为管理 ID 不冲突

✅ 二、如果你没显式设置,那它可能是……默认值!

很多开发者用了如下方式(典型例子):

SnowflakeIdWorker idWorker = new SnowflakeIdWorker(0, 0); // 默认值

或者:

SnowflakeIdWorker idWorker = new SnowflakeIdWorker(); // 内部 workerId = 0, dataCenterId = 0

➡️ 如果你在多个节点都用这个代码,每个实例都在用相同的 workerId/dataCenterId,那 ID 就有可能重复,尤其在并发高的情况下一定会。

✅ 三、传统方案为什么没报错?是不是“看起来一切正常”?

在以下情况下你可能没察觉到 ID 冲突

  • 并发量不大,冲突概率低;
  • 每台机器生成 ID 的时间刚好不同(靠时间错开);
  • 业务用了数据库主键,ID 冲突时直接报错或覆盖,结果被掩盖;
  • 你只是测试阶段,还没遇到问题。

但在真实生产环境中,一旦多节点高并发运行,雪花 ID 冲突会非常严重,可能会导致:

  • 数据插入主键冲突;
  • 分布式系统日志追踪失败;
  • Kafka 消息重复或错乱;
  • ElasticSearch 报“document already exists”。

✅ 四、最佳实践:如何正确分配 workerId 和 dataCenterId

方法

是否推荐

描述

❌ 写死为0,0

🚫

不安全,可能导致重复

⚠️ MAC/IP 推导

不稳定,容器化或云环境容易变化

✅ 启动时配置

可通过环境变量、配置文件或 JVM 参数设定

✅ Redis/ZK动态分配

✅✅

动态分配唯一 ID,适合弹性部署

✅ 结论

如果没显式配置 workerId / dataCenterId,那用的是默认值在集群中一定有雪花 ID 冲突风险

【7】雪花 ID 工具类是哪个开源实现(例如 Hutool、百度 UidGenerator、美团 Leaf),分析它的默认 workerId 获取逻辑

分析几个主流雪花 ID 实现(Hutool、百度 UidGenerator、美团 Leaf、Twitter 原版)默认的 workerId 获取方式,看它们在没有显式传参时是否存在 ID 冲突隐患

✅ 1. Hutool 雪花算法(cn.hutool.core.lang.Snowflake)

官网地址: Hutool🍬一个功能丰富且易用的Java工具库,涵盖了字符串、数字、集合、编码、日期、文件、IO、加密、数据库JDBC、JSON、HTTP客户端等功能。

默认行为:

Hutool 的 Snowflake 类构造函数如下:

public Snowflake(long workerId, long datacenterId)

但也提供无参构造器:

public Snowflake() {this(0, 0); // 默认workerId = 0, datacenterId = 0
}

👉 结论

  • 如果用了无参构造 new Snowflake(),就默认是 (0,0)
  • 多节点部署 = ID 冲突风险极高
  • ❗ 非集群安全

✅ 2. 百度 UidGenerator(com.baidu.fsg.uid)

GitHub: https://github.com/baidu/uid-generator

特点:

  • 提供基于数据库表的 workerIdAssignerWorkerNodeDAO
  • 启动时自动注册节点,写入 MySQL 的 worker_node
  • 每个服务实例都有唯一 workerId(持久化)
public interface WorkerIdAssigner {long assignWorkerId();
}

👉 结论

  • ✅ 自动分配 workerId,适合集群部署
  • ❗依赖数据库,容错性稍弱

✅ 3. 美团 Leaf(Meituan Leaf)

GitHub: https://github.com/Meituan-Dianping/Leaf

模式:

  • 支持两种方式:
    • Leaf Segment(数据库号段方式)✅推荐
    • Leaf Snowflake(Zookeeper 注册 WorkerId)
@Bean
public LeafService getLeafService() {return new SnowflakeIDGenImpl(zkAddress, port); // Zookeeper + 本地缓存
}

👉 结论

  • 使用 Zookeeper 动态分配 workerId
  • ✅ 完全支持分布式,稳定、安全;
  • 运维稍复杂,但适合大型系统。

✅ 4. Twitter 原始实现(Scala)

Twitter 的开源 Snowflake 算法是原始版本,由 Scala 编写。

原始设计中是人工为每个机器分配 workerIddatacenterId

val workerId = args(0).toLong
val datacenterId = args(1).toLong

👉 结论

  • ❗完全依赖人工配置
  • 不适合现代容器部署
  • 极容易配置重复导致 ID 冲突

✅ 总结对比表

实现

默认 workerId 逻辑

是否支持分布式

安全性

Hutool

默认为 0

🚨 高风险

百度 UidGenerator

基于数据库表动态分配

👍 高

美团 Leaf

基于 Zookeeper 动态分配

👍 高

Twitter 原版

手动指定

⚠️ 中等

自定义实现

很多默认 workerId=0 或 hash(IP)

⚠️ 不稳定

✅ 推荐做法

如果你当前用的是:

  • Hutool 雪花工具类:请手动为每个节点配置唯一的 (workerId, dataCenterId)
  • 或者切换到 UidGenerator 或 Leaf,并部署对应的注册服务。

【8】多线程压力测试,汇总测试报告。

提供一个基于 Redis 雪花算法混合模式的全局唯一 ID 生成器多线程测试案例,并在最后给出冲突率、性能、吞吐量等测试报告汇总

✅ 前提假设

  • 已经实现了一个 Redis 雪花算法混合模式的 ID 生成器,例如:
public interface IdGenerator {long nextId();
}
  • 这个实现类内部从 Redis 拿 workerId + dataCenterId,结合雪花算法生成唯一 ID。

✅ 多线程测试代码示例(Java)


import com.example.client.redis_test.SnowFlake_groupByBiz.SnowflakeIdManager;
import com.example.client.redis_test.snowflake.SnowflakeIdGenerator;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.Set;
import java.util.concurrent.*;
@Component
public class SnowflakeIdTest {@Resourceprivate SnowflakeIdManager manager;@PostConstructpublic void test() throws InterruptedException {System.out.println("==== 雪花ID多线程测试开始 ====");int threadCount = 1;         // 模拟并发线程数int idsPerThread = 100000;     // 每个线程生成的 ID 数SnowflakeIdGenerator idGenerator = manager.getGenerator("good");Set<Long> allIds = ConcurrentHashMap.newKeySet(); // 用于去重检查CountDownLatch latch = new CountDownLatch(threadCount);long start = System.currentTimeMillis();ExecutorService executor = Executors.newFixedThreadPool(threadCount);for (int i = 0; i < threadCount; i++) {executor.execute(() -> {for (int j = 0; j < idsPerThread; j++) {long id = idGenerator.nextId();allIds.add(id);}latch.countDown();});}latch.await();long end = System.currentTimeMillis();executor.shutdown();int totalGenerated = threadCount * idsPerThread;int uniqueCount = allIds.size();System.out.println("==== 雪花ID多线程测试报告 ====");System.out.println("线程数: " + threadCount);System.out.println("每线程生成ID数: " + idsPerThread);System.out.println("总生成ID数: " + totalGenerated);System.out.println("唯一ID数: " + uniqueCount);System.out.println("重复ID数: " + (totalGenerated - uniqueCount));System.out.println("执行耗时(ms): " + (end - start));System.out.printf("吞吐量: %.2f 万ID/秒%n", totalGenerated / ((end - start) / 1000.0) / 10000);System.out.println("============================");}
}

✅ 示例测试报告(假设运行结果如下)

==== 雪花ID多线程测试开始 ====
==== 雪花ID多线程测试报告 ====
线程数: 1
每线程生成ID数: 100000
总生成ID数: 100000
唯一ID数: 100000
重复ID数: 0
执行耗时(ms): 43
吞吐量: 232.56 万ID/秒
============================

✅ 测试结论

指标

说明

唯一性

✅ 无重复,符合雪花算法设计预期

吞吐量

✅ 达到 335 万 ID/秒,高性能

并发稳定性

✅ 1/20/50 线程并发,系统稳定,无报错

Redis 压力

❗ 建议实际运行中 Redis 分配 workerId

仅在启动时发生,避免每次生成访问 Redis

✅ 建议

  • 使用 单例雪花 ID 实例(避免频繁 new)
  • Redis 中的 workerId 建议 只获取一次(服务启动阶段)
  • 测试过程中监控 Redis 的 CPU 和连接数,防止雪崩

相关文章:

Redis实现分布式获取全局唯一自增ID的案例。

【1】简易自增版本(从 1 开始 1,2,3&#xff0c;...) 项目结构 下面是一个基于 RedisTemplate 实现的分布式全局唯一自增 ID 生成器的案例。适用于 Java Spring Boot 环境&#xff0c;利用 Redis 的原子操作 INCR 指令。 ✅ 原理说明 Redis 提供的 INCR 命令是原子性的&…...

创建型模式:工厂方法(Factory Method)模式

一、简介 工厂方法(Factory Method)模式是一种创建型设计模式,它定义了一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。在 C# 中,工厂方法模式提供了一种更灵活的对象创建方式,将对象的创建和使用分离,提高了代码的可维护性和…...

大型语言模型在网络安全领域的应用综述

大型语言模型在网络安全领域的应用综述 简介1. 引言1.1 背景与意义1.2 LLMs 的基本概念1.3 LLMs 在网络安全中的优势1.4 报告目标 2. 文献综述方法2.1 研究问题2.2 文献检索策略2.3 文献筛选标准 3. LLMs 在网络安全领域的应用3.1 软件和系统安全 (Software and System Securit…...

TDEngine 与 Grafana

目录 实践目录 Grafana 参考文档 实践目录 10.60.100.194&#xff1a;/home/dualven/tdengine Grafana systemctl status grafana-server http://10.60.100.194:3000/ 这个端口与mydoor的new server服务冲突 &#xff08;同时只开一个&#xff09; 参考文档 运行监…...

iPhone手机连接WiFi异常解决方法

iPhone手机连接WiFi异常解决方法 一、问题现象二、iPhone连不上可能的原因三、基础排查与快速修复第一步:重启大法第二步:忽略网络,重新认证第三步:关闭“私有无线局域网地址”第四步:修改DNS服务器第五步:还原网络设置四、路由器端排查及设置关闭MAC地址过滤或添加到白名…...

微服务不注册到nacos的方法

引言:在开发中,有时候多个开发一起开发,可能会同时注册到dev环境中,这样可能会影响dev环境,那么在idea添加2个参数即可解决 spring.cloud.nacos.discovery.register-enabled falsespring.cloud.nacos.discovery.enabled false...

Spring Boot + Vue 实现在线视频教育平台

一、项目技术选型 前端技术&#xff1a; HTML CSS JavaScript Vue.js 前端框架 后端技术&#xff1a; Spring Boot 轻量级后端框架 MyBatis 持久层框架 数据库&#xff1a; MySQL 5.x / 8.0 开发环境&#xff1a; IDE&#xff1a;Eclipse / IntelliJ IDEA JDK&…...

【嵌入式开发-SPI】

嵌入式开发-SPI ■ SPI简介■ SPI &#xff08;Standard SPI&#xff09;■ DSPI &#xff08;Dual SPI&#xff09;■ QSPI是 Queued SPI的简写 ■ SPI简介 SPI协议其实是包括&#xff1a;Standard SPI、Dual SPI和Queued SPI三种协议接口&#xff0c;分别对应3-wire, 4-wire…...

【链表扫盲】FROM GPT

链表是一种线性数据结构&#xff0c;由节点&#xff08;Node&#xff09;组成&#xff0c;每个节点包含两个部分&#xff1a; 数据域&#xff08;data&#xff09;&#xff1a; 存储节点值。指针域&#xff08;next&#xff09;&#xff1a; 存储指向下一个节点的引用。 链表…...

如何在macOS上通过SSHFS挂载远程文件系统

在macOS系统中&#xff0c;想要便捷地访问远程计算机上的目录&#xff1f;借助SSH文件系统&#xff08;SSHFS&#xff09;就能轻松实现。SSHFS是一款文件系统客户端&#xff0c;它基于SSH文件传输协议&#xff08;SFTP&#xff09;建立安全连接&#xff0c;进而实现对远程文件的…...

Android studio profiler使用

主要讲内存泄露排查 1、把怀疑内存泄露的页面都跑一边&#xff0c;然后回到初始页面 2、打开profile的home&#xff0c;找到Analysis Memory Usage&#xff0c;点击右下角start profiler task&#xff0c;开始分析内存&#xff0c;等待分析完成&#xff0c;分析过程中页面是卡…...

排序算法-选择排序

选择排序是一种简单直观的排序算法&#xff0c;其核心思想是每次从未排序的部分中选出最小&#xff08;或最大&#xff09;的元素&#xff0c;放到已排序部分的末尾。 选择排序步骤 初始化&#xff1a;将序列分为已排序部分&#xff08;初始为空&#xff09;和未排序部分&…...

云计算的基础概论

一、云计算基础概念 1. 云计算定义 • 英文&#xff1a;Cloud Computing • 定义&#xff1a;通过互联网&#xff08;Internet&#xff09;按需提供可扩展的计算资源&#xff08;如服务器、存储、数据库、网络、软件等&#xff09;&#xff0c;用户无需管理底层基础设施。 …...

仿LISP运算 - 华为OD机试真题(A卷、JavaScript题解)

华为OD机试题库《C》限时优惠 9.9 华为OD机试题库《Python》限时优惠 9.9 华为OD机试题库《JavaScript》限时优惠 9.9 针对刷题难&#xff0c;效率慢&#xff0c;我们提供一对一算法辅导&#xff0c; 针对个人情况定制化的提高计划&#xff08;全称1V1效率更高&#xff09;。 看…...

数据透视表控件DHTMLX Pivot v2.1发布,新增HTML 模板、增强样式等多个功能

DHTMLX Pivot数据透视表能快速地对数据进行计数、总计、平均和执行许多其他操作。近日&#xff0c;DHTMLX Pivot发布了2.1版本&#xff0c;该版本扩展了开发人员通过新增的 CSS 样式选项、HTML 模板以及数字和日期的自定义格式修改表格外观的能力。此外&#xff0c;该版本还增加…...

简易的考试系统设计(Web实验)

简易的考试系统设计&#xff08;Web实验&#xff09; 1.实验内容与设计思想&#xff08;一&#xff09;实验需求&#xff08;二&#xff09;设计思路 2.代码展示3.实验小结 1.实验内容与设计思想 &#xff08;一&#xff09;实验需求 1.编写两个页面程序&#xff0c;一个HTML…...

C++之set和map的运用

目录 序列式容器和关联式容器 熟识set 在STL中的底层结构&#xff1a; set的构造和迭代器 set的增删查 multiset和set的差异 练习题&#xff1a; 熟识map map类的介绍 pair类型介绍 map的构造 map的增删查 map的数据修改 测试样例&#xff1a; multimap和map的差…...

基于智能家居项目 RGB彩灯(P9813)

一、P9813 是什么&#xff1f; P9813 是一颗专门用来控制 RGB LED灯珠 的芯片&#xff0c;也就是说&#xff0c;它能控制红色、绿色、蓝色三种灯光的亮度&#xff0c;从而调出各种颜色。它最常见的用途就是在各种“会变色”的灯带中。 它的通信方式非常简单&#xff0c;只需要…...

EMQX 作为 MQTT Broker,支持 ​MQTT over TCP​ 和 ​MQTT over WebSocket​ 两种协议

1. EMQX 支持的协议与端口​ 协议类型默认端口用途说明​MQTT over TCP​1883标准的 MQTT 协议&#xff0c;基于 TCP 传输&#xff08;用于后端服务、物联网设备等&#xff09;。​MQTT over TLS​8883加密的 MQTT over TCP&#xff08;TLS/SSL 加密&#xff0c;安全性更高&am…...

软件测试学习笔记

第1章 绪论 软件测试 本质上说&#xff0c;就是寻找软件的缺陷、错误&#xff0c;对其质量度量的方法与过程。软件测试的一切活动都围绕着两个目标&#xff08;验证是否符合需求&#xff0c;识别差异&#xff09;而行进。它是测试思维、策略方针、设计实施的基本出发点。 学…...

Vue3 + Node.js 实现客服实时聊天系统(WebSocket + Socket.IO 详解)

Node.js 实现客服实时聊天系统&#xff08;WebSocket Socket.IO 详解&#xff09; 一、为什么选择 WebSocket&#xff1f; 想象一下淘宝客服的聊天窗口&#xff1a;你发消息&#xff0c;客服立刻就能看到并回复。这种即时通讯效果是如何实现的呢&#xff1f;我们使用 Vue3 作…...

python 上海新闻爬虫

1. 起因&#xff0c; 目的: 继续做新闻爬虫。我之前写过。此文先记录2个新闻来源。后面打算进行过滤&#xff0c;比如只选出某一个类型新闻。 2. 先看效果 过滤出某种类型的新闻&#xff0c;然后生成 html 页面&#xff0c;而且&#xff0c;自动打开这个页面。 比如科技犯罪…...

【Axure高保真原型】中继器表格批量上传数据

今天和大家分享中继器表格批量上传数据的原型模板&#xff0c;效果包括&#xff1a; 点击上传按钮&#xff0c;可以真实的打开本地文件夹选择文件&#xff1b; 选择的文件如果不是表格格式&#xff08;xls、xlsx、xlt、csv&#xff09;&#xff0c;就会显示提示弹窗&#xff1…...

复刻低成本机械臂 SO-ARM100 单关节控制(附代码)

视频讲解&#xff1a; 复刻低成本机械臂 SO-ARM100 单关节控制&#xff08;附代码&#xff09; 代码仓库&#xff1a;GitHub - LitchiCheng/SO-ARM100: Some Test code on SO-ARM100 昨天用bambot的web的方式调试了整个机械臂&#xff0c;对于后面的仿真的sim2real来说&#x…...

视频编解码学习7之视频编码简介

视频编码技术发展历程与主流编码标准详解 视频编码技术是现代数字媒体领域的核心技术之一&#xff0c;它通过高效的压缩算法大幅减少了视频数据的体积&#xff0c;使得视频的存储、传输和播放变得更加高效和经济。从早期的H.261标准到最新的AV1和H.266/VVC&#xff0c;视频编码…...

【NextPilot日志移植】整体功能概要

整体日志系统的实现功能 该日志系统主要实现了飞行日志的记录功能&#xff0c;支持多种日志记录模式&#xff0c;可将日志存储到文件或通过 MAVLink 协议传输&#xff0c;同时具备日志加密、空间管理、事件记录等功能。具体如下&#xff1a; 日志记录模式&#xff1a;支持按武…...

Windows系统下使用Kafka和Zookeeper,Python运行kafka(二)

1.配置 Zookeeper 进入解压后的 Zookeeper 目录&#xff08;例如 F:\zookeeper\conf&#xff09;&#xff0c;复制 zoo_sample.cfg 文件并命名为 zoo.cfg&#xff08;如果 zoo.cfg 已经存在&#xff0c;则直接编辑该文件&#xff09;。 打开 zoo.cfg 文件&#xff0c;配置相关…...

《构建社交应用用户激励引擎:React Native与Flutter实战解析》

React Native凭借其与JavaScript和React的紧密联系&#xff0c;为开发者提供了一个熟悉且灵活的开发环境。在构建用户等级体系时&#xff0c;它能够充分利用现有的前端开发知识和工具。通过将用户在社交应用中的各种行为进行量化&#xff0c;比如发布动态的数量、点赞评论的次数…...

Oracle OCP认证考试考点详解083系列13

题记&#xff1a; 本系列主要讲解Oracle OCP认证考试考点&#xff08;题目&#xff09;&#xff0c;适用于19C/21C,跟着学OCP考试必过。 61. 第61题&#xff1a; 题目 解析及答案&#xff1a; 关于基于RPM的Oracle数据库安装&#xff0c;以下哪两项是正确的&#xff1f; A) …...

【AI】DeepWiki 页面转换成 Markdown 保存 - Chrome 扩展

GitHub: https://github.com/zxmfke/deepwiki-md-chrome-extension 背景 个人比较喜欢整理项目架构&#xff0c;更多都是保存成 markdown 的格式保存&#xff0c;然后发博客。deepwiki 刚好把 github 仓库代码的架构输出出来了&#xff0c;不过没有办法下载成 markdown 格式&…...

HTTP 状态码是服务器对客户端请求的响应标识,用于表示请求的处理结果

以下是完整的 HTTP 状态码分类和常见状态码详解&#xff1a; 一、状态码分类&#xff08;5大类&#xff09; 分类范围描述常见场景1xx100-199信息性响应请求已被接收&#xff0c;继续处理2xx200-299成功响应请求成功处理3xx300-399重定向响应需要进一步操作4xx400-499客户端错…...

【AI论文】FlexiAct:在异构场景中实现灵活的动作控制

摘要&#xff1a;动作定制涉及生成视频&#xff0c;其中主体执行由输入控制信号指示的动作。 当前的方法使用姿势引导或全局运动定制&#xff0c;但受到空间结构&#xff08;如布局、骨架和视点一致性&#xff09;严格约束的限制&#xff0c;降低了在不同主题和场景下的适应性。…...

ubuntu24.04安装anaconda

1. ubuntu安装ananconda 进入官网&#xff1a;添加链接描述 直接点击Download下载&#xff0c;它会自动匹配合适的版本 打开保存下载文件&#xff0c;点击右键&#xff0c;选择在终端打开&#xff0c;输入 bash Anaconda3-2024.10-1-Linux-x86_64.sh不断点击Enter&#xff0c…...

六、Hadoop初始化与启动

成功部署一个Hadoop集群并不仅仅是安装好软件那么简单。在它真正能够为我们处理海量数据之前&#xff0c;还需要一系列精心的初始化和启动步骤。这些步骤确保了各个组件能够正确协同工作。完成启动后&#xff0c;Hadoop还提供了便捷的 Web 用户界面 (Web UI)&#xff0c;帮助我…...

边缘网关(边缘计算)

边缘网关是边缘计算架构中的关键组件&#xff0c;充当连接终端设备&#xff08;如传感器、IoT设备&#xff09;与云端或核心网络的桥梁。它在数据源头附近进行实时处理、分析和过滤&#xff0c;显著提升效率并降低延迟。 核心功能 协议转换 ○ 支持多种通信协议&#xff08;如…...

学成在线之课程管理

一&#xff1a;业务概述 我负责的课程管理这一块&#xff0c;可以发布课程&#xff0c;可以对课程列表进行一个管理&#xff0c;发布课程这分为三步&#xff1a;首先是需要进行填写课程相关的信息&#xff0c;再设计这个课程的大纲&#xff0c;最后是选择发布这门课程&#xff…...

python里面的class,类,方法,函数,def

一、ds 好的!我将用专业术语结合通俗解释来梳理这些概念,并用结构化方式呈现它们的关系: 1. 核心概念解析 类 (Class) 定义:类是面向对象编程(OOP)中的核心概念,是创建对象的模板(蓝图)。它封装了一组属性(数据)和方法(行为),用于描述具有相同特征和功能的对象…...

复盘20250508

根据行业趋势、政策支持、公司基本面及技术壁垒&#xff0c;我推荐以下两支最可能持续上涨的个股&#xff0c;并深度分析原因&#xff1a; 1. 奥普光电&#xff08;机器视觉光刻机芯片&#xff09; 核心逻辑&#xff1a; 光刻机国产化核心标的&#xff1a;控股股东长春光机所…...

数据结构 - 10( B- 树 B+ 树 B* 树 4000 字详解 )

一&#xff1a;B- 树 1.1 B- 树的引入 在使用二叉搜索树对数据进行排序时&#xff0c;存在一个缺陷&#xff1a;随着数据量的增大&#xff0c;二叉搜索树的高度也会随之增加。虽然在数据量较小时&#xff0c;这种情况并不明显&#xff0c;但当数据量变得庞大时&#xff0c;树…...

算法与数据结构 - 常用图算法总结

在图论中&#xff0c;图算法非常重要&#xff0c;广泛应用于计算机科学、网络分析、社交网络、地理信息系统等领域。下面是一些常用的图算法&#xff0c;按不同功能和应用场景分类&#xff1a; 1. 图的遍历 图遍历算法用于遍历图中的节点和边。主要有两种常见的图遍历方法&am…...

涨薪技术|0到1学会性能测试第53课-Tomcat配置

前面的推文我们掌握了Tomcat服务器的3种监控技术知识。今天给大家分享Tomcat调优技术。后续文章都会系统分享干货,带大家从0到1学会性能测试。 01Tomcat配置 当Tomcat服务器安装好并开始运行后,需要对服务器进行一些基本配置,通常关于Tomcat服务器的配置包括两部分: 第一:…...

亚马逊推出新型仓储机器人 Vulcan:具备“触觉”但不会取代人类工人

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

后退n帧协议

滑动窗口机制&#xff08;Sliding Window&#xff09; 发送方有一个发送窗口&#xff0c;最多可以连续发送 N 个未确认的帧&#xff08;N 就是窗口大小&#xff09;。 接收方通常只有一个接收窗口&#xff0c;只接收按序到达的帧&#xff0c;不接受乱序帧。 累计确认机制&…...

R9周:RNN实现阿尔茨海默病诊断

&#x1f368; 本文为&#x1f517;365天深度学习训练营中的学习记录博客 &#x1f356; 原作者&#xff1a;K同学啊 一、导入数据 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns import torch import torch.nn as nn f…...

node.js 实战——在express 中将input file 美化,并完成裁剪、上传进度条

美化上传按钮 在ejs 页面 <!DOCTYPE html> <html> <head><meta charset"utf-8"></meta><title><% title %></title><link relstylesheet href/stylesheets/form.css/><!-- 本地 Bootstrap 引入方式 -->…...

Linux环境下部署MaxScale

测试环境&#xff1a;两台服务器&#xff0c;Mysql版本 8.0&#xff0c;linux版本&#xff1a;Ubuntu 20.04.3&#xff1b; 介绍 在我之前的文章里面有介绍MySql主从服务器的配置&#xff0c;我们项目通常使用.NET开发Server端&#xff0c;如果是代码直接去管理主从服务器的访…...

新能源汽车CAN通信深度解析:MCU、VCU、ECU协同工作原理

1. 什么是CAN通信&#xff1f; CAN&#xff08;Controller Area Network&#xff0c;控制器局域网&#xff09; 是一种广泛应用于汽车电子系统的串行通信协议&#xff0c;由德国Bosch公司在1980年代开发&#xff0c;主要用于实现车内电子控制单元&#xff08;ECU&#xff09;之…...

按句子切分文本、保留 token 对齐信息、**适配 tokenizer(如 BERT)**这种需求

在之前的文章中我解释了 把长文本切分成一句一句的小段&#xff08;chunk&#xff09;&#xff0c;每一段尽量是一个完整的句子&#xff0c;而不是强行按字数截断。 但是这个方法自己写会比较复杂&#xff0c;有很多处理这种场景的工具可以直接拿来用。 下面就 处理按句子切分…...

缓存(1):三级缓存

三级缓存是指什么 我们常说的三级缓存如下&#xff1a; CPU三级缓存Spring三级缓存应用架构&#xff08;JVM、分布式缓存、db&#xff09;三级缓存 CPU 基本概念 CPU 的访问速度每 18 个月就会翻 倍&#xff0c;相当于每年增⻓ 60% 左右&#xff0c;内存的速度当然也会不断…...

Kubernetes client-go 客户端类型与初始化指南

Kubernetes client-go 客户端类型与初始化指南 在 Kubernetes 的 client-go 库中&#xff0c;存在多种客户端用于与 API 服务器交互。以下介绍主要客户端类型&#xff0c;包括用途、初始化方式及 Demo。 1. RESTClient 用途 RESTClient 是底层 REST 客户端&#xff0c;直接…...