Redisson学习专栏(二):核心功能深入学习(分布式锁,分布式集合,原子操作与计数器,事件与监听)

news2025/6/2 21:39:15

本文是“Redisson学习专栏”第二篇,聚焦其核心分布式功能实现原理与最佳实践

文章目录

  • 前言:分布式系统核心能力实践
  • 一、分布式锁:高并发下的守卫者
    • 1.1 可重入锁 (Reentrant Lock)
    • 1.2 公平锁 (Fair Lock)
    • 1.3 联锁 (MultiLock)
    • 1.4 红锁 (RedLock)
    • 关键参数说明
  • 二、Watchdog 机制与超时释放
    • 2.1 Watchdog (看门狗) 机制
      • 2.1.1看门狗机制为何选择10秒续期间隔?
    • 2.2 超时释放
  • 三、混合缓存利器:RMapCache
  • 四、协调任务流:分布式队列与发布订阅
    • 4.1 分布式队列
    • 4.2 发布订阅 (Pub/Sub):
  • 五、全局计数:分布式原子操作
  • 六、感知数据变化:监听 Redis 键空间事件
  • 总结


前言:分布式系统核心能力实践

在分布式架构中,跨进程的协调与数据一致性是关键技术挑战。作为基于Redis的Java客户端,Redisson通过原生分布式数据结构,为开发者提供了高效的分布式解决方案。
在上篇专栏完成基础架构解析后,本文将深入核心分布式功能实现:

  1. 分布式锁体系: 可重入锁、公平锁的Redis实现,以及MultiLock、RedLock的适用场景分析
  2. 缓存优化实践: RMapCache本地+分布式缓存混合模式
  3. 协调机制: 分布式队列与发布订阅的应用实现
  4. 原子操作: 分布式计数器的底层原理
  5. 事件驱动: 键空间监听机制与可靠性解析

技术栈要求:熟悉Redis基础及Java并发编程,示例基于Redisson 3.17+


一、分布式锁:高并发下的守卫者

1.1 可重入锁 (Reentrant Lock)

  • 原理: 基于 Redis Hash 结构存储锁信息。Key 为锁名称,Field 为客户端 ID(通常为 UUID + 线程 ID),Value 为持有计数(重入次数)。
  • 加锁: HINCRBY lock_name client_id 1(首次获取时设置过期时间)。
  • 解锁: HINCRBY lock_name client_id -1,当计数为 0 时删除 Key。通过 Lua 脚本保证原子性。
  • 核心价值: 同一线程可多次获取锁,避免死锁。
  • 适用场景: 标准分布式锁需求,支持同一线程重复加锁。
// 获取锁实例
RLock lock = redissonClient.getLock("orderLock");

try {
    // 尝试加锁(默认启用Watchdog自动续期)
    lock.lock();
    // 支持重入
    lock.lock();
    
    // 执行业务逻辑
    processOrder();
    
} finally {
    // 释放锁(需与加锁次数匹配)
    lock.unlock();
    lock.unlock();
}

1.2 公平锁 (Fair Lock)

  • 原理: 在可重入锁基础上增加排队机制。使用 Redis List 结构维护等待队列。
  • 加锁: 客户端尝试获取锁失败时,在队列尾部(RPUSH)添加自己的 ID,并订阅其前一个节点的释放消息(Pub/Sub),进入阻塞等待。
  • 解锁: 释放锁时,通过 Pub/Sub 通知队列中的下一个等待者。保证先到先得。
  • 适用场景: 需严格按申请顺序获取锁的场景。
RLock fairLock = redissonClient.getFairLock("taskQueueLock");

try {
    // 加锁(默认30秒租期,Watchdog自动续期)
    fairLock.lock();
    
    // 获取队列首任务
    String task = taskQueue.poll();
    executeTask(task);
    
} finally {
    fairLock.unlock();
}

// 指定锁超时时间(不启用Watchdog)
fairLock.lock(10, TimeUnit.SECONDS);  // 10秒后自动释放

1.3 联锁 (MultiLock)

  • 原理: 将多个独立的锁(可属于不同的 Redis 节点)组合成一个逻辑锁。
  • 加锁: 按顺序尝试获取所有底层锁。若任意一个失败,则释放所有已获得的锁。
  • 解锁:按顺序释放所有底层锁。
  • 适用场景: 需同时锁定多个独立资源时(如:跨多个系统的操作)。
// 创建多个锁实例
RLock lock1 = redissonClient.getLock("resource1");
RLock lock2 = redissonClient.getLock("resource2");
RLock lock3 = redissonClient.getLock("resource3");

// 构建联锁
RLock multiLock = redissonClient.getMultiLock(lock1, lock2, lock3);

try {
    // 尝试获取所有锁(整体作为原子操作)
    boolean success = multiLock.tryLock(100, 10, TimeUnit.SECONDS);
    
    if (success) {
        // 所有资源锁定成功
        updateMultipleResources();
    }
} finally {
    multiLock.unlock();
}

1.4 红锁 (RedLock)

  • 目标: 在 Redis 主从架构下提供更强的一致性保证(防止主节点宕机未同步锁信息)。
  • 原理 (N 个独立 Master 节点):
    • 客户端获取当前时间 T1。
    • 依次向 N 个节点发送加锁命令(包含相同的随机值和锁过期时间)。
    • 计算获取锁耗时:锁有效时间 = 锁过期时间 - (T2 - T1)(T2 为最后响应时间)。
    • 当且仅当客户端在多数节点 (N/2 + 1) 上成功获取锁,且总耗时小于锁过期时间时,认为加锁成功。
  • 争议与注意事项:
    - 时钟漂移问题: 节点间时钟不一致可能影响锁有效性判断。
    - 性能与成本: 需要部署多个独立 Redis Master 节点,操作延迟较高。
    - Martin Kleppmann 的质疑: 详细讨论了网络分区、GC 暂停等场景下的潜在问题。
    - 实践建议: 仅在极高一致性要求且能容忍复杂性和性能损耗的场景下使用。需充分理解其局限性。Redisson 实现了完善的 RedLock 算法。
// 为每个独立Redis实例创建锁
Config config1 = new Config();
config1.useSingleServer().setAddress("redis://node1:6379");
RedissonClient client1 = Redisson.create(config1);
RLock lock1 = client1.getLock("criticalLock");

Config config2 = // ... node2配置
RLock lock2 = // ... 

Config config3 = // ... node3配置
RLock lock3 = // ...

// 构建红锁
RLock redLock = redissonClient.getRedLock(lock1, lock2, lock3);

try {
    // 尝试加锁(超过半数节点成功即视为成功)
    if (redLock.tryLock()) {
        // 执行关键操作(如金融交易)
        executeCriticalOperation();
    }
} finally {
    redLock.unlock();
}

// 关闭独立客户端(重要!)
client1.shutdown();
// ... 关闭其他客户端

关键参数说明

方法参数说明默认值
lock()阻塞直到获取锁,启用Watchdog-
lock(leaseTime, unit)指定锁持有时间,不启用Watchdog-
tryLock()立即返回获取结果(成功/失败)false
tryLock(waitTime, leaseTime, unit)等待指定时间,获取后持有指定时长waitTime=0

重要提示:

  1. 红锁需要至少3个独立Redis主节点(非集群分片)
  2. 调用unlock()次数需与lock()次数匹配
  3. 使用tryLock时务必检查返回值
  4. 红锁客户端需单独创建和关闭

二、Watchdog 机制与超时释放

2.1 Watchdog (看门狗) 机制

看门狗机制解决了这样的一个问题:业务执行时间可能超过锁的初始过期时间。
看门狗时序图

原理:

  • 客户端成功获取锁(未显式指定 leaseTime)时,Redisson 会启动一个后台守护线程。
  • 该线程定期(默认在锁过期时间的 1/3 时间点,如 30s 过期则每 10s)向 Redis 发送命令重置锁的过期时间(续期)。
  • 只要客户端 JVM 进程存活且持有锁,看门狗会持续续期。
  • 客户端主动释放锁或进程崩溃时,续期停止。

关键点: lock.lock() 默认启用 Watchdog(默认 30s 过期,每 10s 续期)。lock.lock(10, TimeUnit.SECONDS) 指定 leaseTime 则不启用 Watchdog。

2.1.1看门狗机制为何选择10秒续期间隔?

设计原理分析:
Redisson的看门狗机制选择10秒作为默认续期间隔,是经过多重技术考量后的平衡设计,核心因素如下:

  1. 过期时间的三分之一原则:首先默认过期时间为30秒,该比例确保在锁过期前至少进行3次续期尝试(0s, 10s, 20s)。
    网络容错设计
  2. 性能与可靠性的平衡点:
续期间隔优点缺点
5秒容错性更高Redis压力倍增
15秒减少Redis负载容错窗口不足
10秒最佳平衡-

关键设计:

  • 时钟漂移容错: 假设各节点时钟存在1-2秒误差,10秒间隔确保时钟漂移不会导致续期失败。计算公式:续期间隔 > 最大时钟漂移 × 3
  • GC暂停容忍: 考虑JVM的Stop-The-World GC暂停(通常<1秒),10秒间隔可承受多次GC暂停影响。
  • 网络延迟补偿:
// Redisson续期操作核心逻辑
void scheduleExpirationRenewal() {
    // 计算下次续期时间 = 当前时间 + 1/3锁有效期
    Timeout task = timer.newTimeout(new TimerTask() {
        public void run(Timeout timeout) {
            // 异步续期操作(含网络请求)
            renewExpirationAsync(); 
        }
    }, lockWatchdogTimeout / 3, TimeUnit.MILLISECONDS);
}
  • 故障转移窗口:Redis集群故障转移时间通常5-10秒,10秒间隔为集群切换留出缓冲时间。

关键结论:10秒间隔是分布式系统设计中的经典时间窗口,平衡了网络不确定性(Network Uncertainty)和系统负载。它确保即使连续2次续期失败(20秒),锁仍有10秒的有效期缓冲,为故障排查留出黄金时间。

2.2 超时释放

  • 如果使用了 lock.lock(leaseTime, unit) 指定租约时间,Redis 会在 leaseTime 后自动删除 Key 释放锁。
  • 风险: 业务执行时间超过 leaseTime 会导致锁提前释放,其他客户端可能获取锁操作共享资源,造成数据不一致。谨慎使用,需确保业务最大执行时间远小于 leaseTime。

三、混合缓存利器:RMapCache

RMapCache 在分布式 Map (RMap) 基础上增加了本地缓存 (Local Cache) 和条目过期淘汰功能。
原理:

  1. 本地缓存: 客户端在内存中维护一份热点数据的副本。
  2. 数据同步: 通过 Redis 的 Pub/Sub 通道监听 Map 的更新/删除事件。当其他节点修改了 Map 中的数据,本地缓存会收到通知并失效对应的条目。
  3. 本地缓存淘汰策略: 支持 LRU (最近最少使用)、LFU (最不经常使用)、SOFT (软引用)、WEAK (弱引用) 等策略限制本地内存占用。
  4. Redis 缓存过期: 支持为 Map 中的单个条目设置 TTL (生存时间) 或 Max Idle Time (最大空闲时间)。

优势:

  • 显著降低延迟: 读取本地缓存速度极快。
  • 减轻 Redis 压力: 大量读请求被本地缓存吸收。
  • 保留分布式特性: 写操作和缓存失效通知保证不同节点间数据的最终一致性。

使用示例与配置:

RMapCache<String, SomeObject> mapCache = redisson.getMapCache("myMapCache");
// 配置本地缓存:最大容量500,淘汰策略LFU,10分钟后未访问则失效
LocalCachedMapOptions<String, SomeObject> options = LocalCachedMapOptions.<String, SomeObject>defaults()
        .cacheSize(500)
        .evictionPolicy(EvictionPolicy.LFU)
        .timeToLive(10, TimeUnit.MINUTES);
RMapCache<String, SomeObject> mapCacheWithLocalCache = redisson.getMapCache("myMapCache", options);

// 写入 (会广播失效其他节点的本地缓存)
mapCacheWithLocalCache.put("key1", new SomeObject(), 5, TimeUnit.MINUTES); // 设置该条目在Redis中5分钟后过期

// 读取 (优先读本地缓存,不存在则从Redis加载并缓存)
SomeObject obj = mapCacheWithLocalCache.get("key1");

注意事项: 本地缓存带来性能提升的同时,也引入了弱一致性。在极端网络分区情况下,不同节点的本地缓存可能短暂不一致。适用于对一致性要求不苛刻的高频读场景。

四、协调任务流:分布式队列与发布订阅

4.1 分布式队列

  • RQueue: 基于 Redis List (LPUSH/RPOP, RPUSH/LPOP) 实现的普通 FIFO 队列。
  • RBlockingQueue: RQueue 的阻塞版本。核心方法是阻塞式的 take() 和 poll(timeout)。
    • take() 原理: 客户端使用 BLPOP/BRPOP 命令阻塞等待队列中出现元素。Redis 会在元素入队时唤醒等待的客户端。
    • 应用场景: 简单的任务队列、解耦生产者消费者。
RBlockingQueue<String> queue = redisson.getBlockingQueue("myTaskQueue");
// 生产者
queue.offer("task1");
// 消费者 (阻塞等待)
String task = queue.take();
process(task);

4.2 发布订阅 (Pub/Sub):

  • RTopic: 实现基于 Redis Pub/Sub 机制的消息发布/订阅模型。
  • 原理: 发布者 (publish) 向指定频道发送消息。所有订阅了该频道的客户端都会收到消息。
  • 集群支持: Redisson 的 RTopic 能自动处理 Redis 集群环境下的消息路由。
  • 应用场景: 广播通知、事件驱动架构、实时数据推送。
RTopic topic = redisson.getTopic("myTopic");
// 订阅者 (监听消息)
int listenerId = topic.addListener(MessageType.class, (channel, msg) -> {
    System.out.println("Received: " + msg);
});
// 发布者
topic.publish(new MessageType("Hello Redisson Pub/Sub!"));
// 取消订阅
topic.removeListener(listenerId);

五、全局计数:分布式原子操作

  • RAtomicLong / RAtomicDouble:
    • 原理: 基于 Redis 的原子命令 INCRBY, DECRBY, INCRBYFLOAT 等实现。这些命令在 Redis 单线程模型下天然具有原子性。
    • 核心方法:
      • get(), set(newValue)
      • incrementAndGet(), decrementAndGet()
      • addAndGet(delta), getAndAdd(delta)
      • (RAtomicDouble特有) addAndGet(deltaDouble), getAndAdd(deltaDouble)
    • 应用场景: 全局唯一 ID 生成器(如 INCR)、库存计数、投票计数、秒杀活动计数、分布式指标统计。
RAtomicLong counter = redisson.getAtomicLong("globalCounter");
long currentId = counter.incrementAndGet(); // 原子递增并获取新值

六、感知数据变化:监听 Redis 键空间事件

Redisson 允许监听 Redis 的键空间通知 ,如键的过期、删除、更新等。

  1. 配置 Redis:需在 redis.conf 中启用键空间通知(生产环境应谨慎选择需要的事件类型):
notify-keyspace-events Exgx  # K:键空间事件,E:键事件事件,x:过期事件,g:一般事件(如 del),e:驱逐事件(maxmemory)
  1. Redisson 监听器:
RPatternTopic keyEventTopic = redisson.getPatternTopic("__keyevent@*");
// 监听所有键事件
int listenerId = keyEventTopic.addListener(PatternStatusListener, new PatternMessageListener<String>() {
    @Override
    public void onMessage(CharSequence pattern, CharSequence channel, String message) {
        // pattern: "__keyevent@*", channel: e.g. "__keyevent@0__:expired", message: the key name
        System.out.println("Event: " + channel + ", Key: " + message);
        if (channel.toString().endsWith(":expired")) {
            handleKeyExpiration(message);
        } else if (channel.toString().endsWith(":del")) {
            handleKeyDeletion(message);
        }
    }
});
  • 常用事件通道:keyevent@:expired (过期), keyevent@:del (删除), keyevent@:set (设置) 等。
  • keyspace@: 通道监听特定键的事件(需额外配置)。

应用场景:

  • 缓存失效监听: 监听 expired 事件,触发缓存重建逻辑。
  • 数据变更通知: 监听特定键的 set/del 事件,执行关联操作(如更新索引、清理关联资源)。
  • 分布式锁超时监控: 监听锁 Key 的 expired 事件,感知锁异常释放(需结合业务逻辑谨慎处理)。

注意事项:

  • 可靠性: 键空间通知是 Fire-and-Forget 的,不保证可靠传递(网络问题、客户端断开时可能丢失通知)。
  • 性能影响: 大量事件通知会对 Redis 和网络造成额外开销。
  • 事件延迟: 过期事件存在一定延迟(Redis 定期检查 + 事件传递时间)。

总结

通过本文的深度探索,我们揭示了 Redisson 如何将 Redis 从单纯的数据存储转变为分布式系统的神经中枢。这些核心功能不仅是技术组件的堆砌,更是解决分布式系统痛点的范式升级:

  • 分布式锁体系 超越了简单的互斥控制,通过 Watchdog 机制和红锁算法,在可用性和一致性之间建立了动态平衡
  • RMapCache 混合缓存 打破了本地与分布式缓存的对立,用分层设计实现亚毫秒级响应与TB级容量的统一
  • 原子操作与队列 将并发编程模型扩展到分布式维度,使跨服务的状态同步如同单机编程般自然
  • 键空间监听 开启了真正的数据驱动架构,让业务逻辑能实时响应全局状态变化

技术选型黄金法则

场景推荐组件避坑指南
高频短期锁可重入锁+Watchdog避免设置过短leaseTime
跨资源事务MultiLock严格按顺序获取锁
超高一致性要求RedLock部署3+独立节点,监控时钟同步
读密集型热点数据RMapCache+LFU策略控制本地缓存大小防OOM
实时事件响应键空间监听+本地缓存配置notify-keyspace-events参数

警示:没有完美的分布式解决方案。红锁的时钟争议提醒我们:任何分布式协调都需在CAP三角中取舍。Redisson的价值在于,它让这种取舍变得可量化、可配置、可观测

学习建议:

# 立即验证本文知识
git clone https://github.com/redisson/redisson-examples

讨论题:在您当前的项目中,Redisson 的哪个功能能带来最大价值?您遇到过哪些分布式协调的"诡异"问题?

下期预告:Redission高级特性与实战(Spring/Spring Boot 集成,响应式编程,分布式服务,性能优化)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2394655.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

医疗多模态共情推理与学习一体化网络构成初探

1 引言:多模态共情推理的概念内涵与技术背景 在当今医疗人工智能领域,多模态共情推理正逐步成为突破临床决策支持系统瓶颈的关键范式。这一技术通过融合认知共情与情感共情的双重机制,模拟人类医生的综合诊断思维过程,实现对患者全方位健康状态的深度理解。医疗环境中的共…

MySQL : MySQL的安装【CentOS 7】

MySQL : MySQL的安装【CentOS 7】 (一) MySQL的卸载和安装1.卸载查看是否存在MySQL删掉原有的MySQL 2.安装 &#xff08;二&#xff09;登录和环境配置登录方法一: 存在临时密码登录方法二:通过修改配置文件环境配置 (一) MySQL的卸载和安装 安装与卸载中&#xff0c;用户全部…

EasyRTC嵌入式音视频实时通话SDK助力AI与IoT智能硬件打造音视频交互多场景应用

一、引言​ 在数字化浪潮下&#xff0c;AI与IoT深度融合重塑智能硬件产业。实时音视频通信是智能硬件交互的核心&#xff0c;其性能关乎用户体验与场景拓展。EasyRTC嵌入式音视频实时通话SDK基于WebRTC技术&#xff0c;以轻量、易扩展的特性&#xff0c;为AI与IoT智能硬件融合…

Unity数字人开发笔记——讯飞超拟人语音

基于上一篇&#xff1a; https://blog.csdn.net/qq_17523181/article/details/148255809?spm1001.2014.3001.5501 https://blog.csdn.net/qq_17523181/article/details/148264127?spm1011.2415.3001.5331 讯飞默认的语音非常机械&#xff0c;更换为讯飞的超拟人语音 一、讯飞…

C# 文件 I/O 操作详解:从基础到高级应用

在软件开发中&#xff0c;文件操作&#xff08;I/O&#xff09;是一项基本且重要的功能。无论是读取配置文件、存储用户数据&#xff0c;还是处理日志文件&#xff0c;C# 都提供了丰富的 API 来高效地进行文件读写操作。本文将全面介绍 C# 中的文件 I/O 操作&#xff0c;涵盖基…

Visual Studio笔记:MSVC工具集、MSBuild

1. MSVC工具集 1.1 什么叫MSVC工具集 也可以说Visual Studio平台工具集&#xff08;Platform toolset&#xff09;. 这些工具包括 C/C 编译器、链接器、汇编程序和其他生成工具以及匹配的库和头文件。 Visual Studio 2015、Visual Studio 2017 和 Visual Studio 2019 是二进制…

高端制造行业 VMware 替代案例合集:10+ 头部新能源、汽车、半导体制造商以国产虚拟化支持 MES、PLM 等核心应用系统

在“中国制造 2025”政策的推动下&#xff0c;国内的新能源、汽车制造、半导体、高端装备等高端制造产业迎来了蓬勃发展&#xff0c;成为全球制造业版图中举足轻重的力量。订单数量的激增与国产化转型的趋势&#xff0c;也为高端制造企业的 IT 基础设施带来了新的挑战&#xff…

【b站计算机拓荒者】【2025】微信小程序开发教程 - chapter3 项目实践 - 3人脸识别采集统计人脸检测语音识别

https://www.bilibili.com/video/BV1WgQdYNERe/?p87&spm_id_from333.788.top_right_bar_window_history.content.click&vd_sourcec919d6976fd77ac77f9860cf2e7e0e11 1 人脸识别 # 1 采集完-人脸图片好上传到百度人脸识别-后期使用百度进行人脸识别-保存、删除等-后期…

杆塔倾斜在线监测装置:电力设施安全运行的“数字守卫”

在输电线路、通信基站及风电设施等场景中&#xff0c;杆塔作为支撑核心设备的基础结构&#xff0c;其稳定性直接关系到能源传输与信息通信的安全。传统人工巡检方式存在效率低、响应滞后等局限&#xff0c;而杆塔倾斜在线监测装置通过技术赋能&#xff0c;实现了对杆塔状态的实…

C++23 新成员函数与字符串类型的改动

文章目录 引言std::basic_string::contains 与 std::basic_string_view::contains (P1679R3)功能介绍示例代码优势 禁止从 nullptr 构造 std::basic_string 和 std::basic_string_view (P2166R1)背景改动影响 std::basic_string_view 的显式范围构造函数 (P1989R2)功能介绍示例…

threejs渲染器和前端UI界面

1. three.js Canvas画布布局 学习本节课之前&#xff0c;可以先回顾下第一章节入门部分的6和12两小节关于threejs Canvas画布布局的讲解。 网页上局部特定尺寸&#xff1a;1.6 第一个3D案例—渲染器(opens new window) 全屏&#xff0c;随窗口变化:1.12 Canvas画布布局和全屏…

AI笔记 - 网络模型 - mobileNet

网络模型 mobileNet mobileNet V1网络结构深度可分离卷积空间可分![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/aff06377feac40b787cfc882be7c6e5d.png) 参考 mobileNet V1 网络结构 MobileNetV1可以理解为VGG中的标准卷积层换成深度可分离卷积 可分离卷积主要有…

day12 leetcode-hot100-20(矩阵3)

48. 旋转图像 - 力扣&#xff08;LeetCode&#xff09; 1.辅助数组法&#xff08;题目不让&#xff09; 思路&#xff1a;很简单&#xff0c;新建一个二维数组&#xff0c;直接找新数组与旧数组的规律即可。比如这个旋转90。那就是相当于 new[col][n-row-1]old[row][col],然后…

【Java开发日记】基于 Spring Cloud 的微服务架构分析

目录 1、Spring Cloud 2、Spring Cloud 的核心组件 1. Eureka&#xff08;注册中心&#xff09; 2. Zuul&#xff08;服务网关&#xff09; 3. Ribbon&#xff08;负载均衡&#xff09; 4. Hystrix&#xff08;熔断保护器&#xff09; 5. Feign&#xff08;REST转换器&a…

AWTK 嵌入式Linux平台实现多点触控缩放旋转以及触点丢点问题解决

前言 最近涉及海图的功能交互&#xff0c;多点触摸又开始找麻烦。 在PC/Web平台awtk是通过底层的sdl2库来实现多点触摸&#xff0c;但是在嵌入式Linux平台&#xff0c;可能是考虑到性能原因&#xff0c;awtk并没有采用sdl库来做事件处理&#xff0c;而是自己实现一个awtk-lin…

尚硅谷redis7 93-97 springboot整合reids之总体概述

93 springboot整合reids之总体概述 总体概述 jedis-lettuce-RedisTemplate三者的联系 名称类型作用描述和其它的关系JedisRedis 客户端早期主流的 Java Redis 客户端&#xff0c;基于阻塞 I/O&#xff0c;同步操作可作为 RedisTemplate 的底层连接实现LettuceRedis 客户端基…

声纹技术体系:从理论基础到工程实践的完整技术架构

文章目录 一、声纹技术的理论基础与概念内核1.1 声纹的生物学本质与数学表征1.2 特征提取的理论基础与实现机制 二、声纹识别技术的演进逻辑与方法体系2.1 传统统计学方法的理论架构2.2 深度学习方法的技术革新2.3 损失函数的设计原理与优化策略 三、声纹识别系统的架构设计与模…

行为型:命令模式

目录 1、核心思想 2、实现方式 2.1 模式结构 2.2 实现案例 3、优缺点分析 4、适用场景 5、实际应用 1、核心思想 目的&#xff1a;将指令信息封装成一个对象&#xff0c;并将此对象作为参数发送给接收方去执行&#xff0c;以使命令的请求方与执行方解耦 概念&#xff…

vue3 + WebSocket + Node 搭建前后端分离项目 开箱即用

[TOC](vue3 WebSocket Node 搭建前后端分离项目) 开箱即用 前言 top1&#xff1a;vue3.5搭建前端H5 top2&#xff1a;Node.js koa搭建后端服务接口 top3&#xff1a;WebSocket 长连接实现用户在线聊天 top4&#xff1a;接口实现模块化 Mysql 自定义 top5&#xff1a;文件上…

Win10秘笈:两种方式修改网卡物理地址(MAC)

Win10秘笈&#xff1a;两种方式修改网卡物理地址&#xff08;MAC&#xff09; 在修改之前&#xff0c;可以先确定一下要修改的网卡MAC地址&#xff0c;查询方法有很多种&#xff0c;比如&#xff1a; 1、在设置→网络和Internet→WLAN/以太网&#xff0c;如下图所示。 2、在控…