Caffeine 本地缓存核心与 SpringBoot 集成

Caffeine 核心与 SpringBoot 集成 📖 前置阅读:本文假设读者已了解 Redis 基本操作和 Spring Cache 注解(@Cacheable/@CachePut/@CacheEvict)。如果还不熟悉 Redis 系列,建议先阅读 SpringBoot Redis 全操作指南。 一、⚡ 问题切入:Redis 再快也是远程调用 回顾一下,一个典型的 Redis 缓存查询是: // Redis 缓存读 User user = (User) redisTemplate.opsForValue().get("user:1001"); if (user != null) return user; // 缓存未命中,查 MySQL user = userMapper.selectById(1001L); redisTemplate.opsForValue().set("user:1001", user, 30, TimeUnit.MINUTES); return user; Redis 延迟一般在 0.5ms ~ 2ms——相比 MySQL 的 3ms ~ 10ms 已经快很多了。但这个延迟不是免费的:每次 Redis 查询都是一次网络往返(RTT)。同机房内 RTT 大约 0.1ms,跨机房可能到 2ms 甚至更久。 在高 QPS 下,这 0.5ms × 10 万次查询 = 50 秒的累计时间,还不算序列化/反序列化的 CPU 开销。而且 Redis 不是永远不会挂——网络抖动、内存满了、主从切换,任何一个都可能让 Redis 临时不可用。 ...

十月 30, 2022 · 6 分钟 · 1073 字 · yaomingye

MongoDB 索引、事务与性能调优

生产落地的三件套:索引、事务与调优 📖 前置阅读:本文是 MongoDB 系列的生产调优篇,假设读者已经掌握了 MongoDB 文档模型、SpringBoot 操作和聚合管道。如果还没有,建议先阅读前三篇: MongoDB 核心概念:文档模型、BSON 与查询操作符全解析 —— 介绍篇 SpringBoot MongoDB 全操作指南 —— 实战篇 MongoDB 聚合管道深入 —— 进阶篇 一、⚡ 问题切入:查询怎么越来越慢了? 用户表单数据从 10 万增长到 500 万,“按手机号查询表单记录"从 5ms 变成了 800ms。你用 explain() 一看——stage: "COLLSCAN",全表扫描。 这场景和 MySQL 一样——数据量大了没建索引,写什么数据库都快不了。但 MongoDB 的索引有一些 MySQL 没有的类型,还有 Schema 设计的决策(嵌入还是引用?要不要用事务?)直接影响性能。 本篇要解决的问题:怎么设计索引、怎么看懂 explain、怎么选嵌入还是引用、什么时候用事务——以及遇到性能问题时从哪下手排查。 二、📊 索引类型与策略 2.1 单字段索引与复合索引 底子和 MySQL 一样——B-Tree。创建一个索引语法几乎一样: // 单字段索引 db.users.createIndex({ email: 1 }) // 1 = 升序,-1 = 降序(单字段索引中不重要) // 复合索引(多个字段组合) db.orders.createIndex({ userId: 1, createTime: -1 }) // 查看所有索引 db.orders.getIndexes() 复合索引的 ESR 规则——这是 MongoDB 复合索引最重要的设计原则: ...

十月 29, 2022 · 6 分钟 · 1237 字 · yaomingye

MongoDB 聚合管道深入

聚合管道实战:从入门到精通 📖 前置阅读:本文是 MongoDB 系列的进阶篇,假设读者已经掌握了 MongoDB 文档模型和 SpringBoot 基本操作。如果还没有,建议先阅读前两篇: MongoDB 核心概念:文档模型、BSON 与查询操作符全解析 —— 介绍篇 SpringBoot MongoDB 全操作指南 —— 实战篇 一、⚡ 问题切入:查询能查出结果,但分析不出来 先看一个业务需求。你有一个电商订单 Collection: // 一条订单文档 { _id: ObjectId("..."), userId: 1001, total: NumberDecimal("6999.00"), status: "paid", items: [ { productName: "华为Mate60 Pro", category: "手机", price: NumberDecimal("6999.00"), quantity: 1 } ], createTime: ISODate("2024-01-15T10:30:00Z") } 产品经理要你给出以下数据: 每个用户的总消费金额 每月订单量趋势 销量最高的 10 个商品分类 每个用户的平均客单价 哪些商品经常一起购买(关联分析) 用 find 可以查出原始数据,但统计计算全得拉到 Java 内存里自己算——5 万条订单光加载到内存就需要 2 秒,再算就 5 秒起步。 这就是聚合管道的用武之地——把计算下推到 MongoDB 服务器端完成,只返回结果,不传原始数据。 二、🧱 聚合管道是什么 2.1 核心概念 聚合管道(Aggregation Pipeline) 是一组按顺序执行的数据处理阶段(Stage)。每个 Stage 接收上一阶段的输出,做一次数据变换,把结果传给下一阶段。 flowchart LR classDef stage fill:#450a0a,stroke:#dc2626,stroke-width:1.5px,color:#fecaca,font-weight:bold; classDef data fill:#052e16,stroke:#16a34a,stroke-width:1.5px,color:#bbf7d0,font-weight:bold; classDef result fill:#0f172a,stroke:#3b82f6,stroke-width:2px,color:#bfdbfe,font-weight:bold; COLLECTION[(orders\n50000 文档)] COLLECTION --> S1[$match\n过滤: status=paid] S1 --> S2[$group\n分组: 按 userId] S2 --> S3[$sort\n排序: 总金额降序] S3 --> S4[$limit\n取前 10] S4 --> RESULT([10 条聚合结果]) class S1,S2,S3,S4 stage; class COLLECTION data; class RESULT result; 关键点: ...

十月 28, 2022 · 8 分钟 · 1662 字 · yaomingye

SpringBoot MongoDB 全操作指南

SpringBoot 集成 MongoDB:CRUD 到聚合全操作 📖 前置阅读:本文假设读者已了解 MongoDB 的文档模型、BSON 数据类型和 mongosh 基础操作。如果还不熟悉,建议先阅读 MongoDB 核心概念:文档模型、BSON 与查询操作符全解析。 本文按照"先搞懂操作 → 教程版完整实现 → 生产版架构模式 → 验证排错“的顺序组织。如果你只想快速上手 MongoTemplate 的 CRUD,读完 Part 1 后直接看 Part 2 即可;如果你想理解真实项目中 MongoDB 是怎么用的,需要完整读完。 Part 1:先搞懂要做什么 一、目标说明 这篇文章的目标:让读者在一篇文章内学会 SpringBoot 项目中所有常用的 MongoDB 操作,读完就能直接写到项目里。 具体来说,读完这篇文章会掌握: 用 @Document / @Id / @Field 注解定义 MongoDB 文档映射 用 MongoTemplate 执行 CRUD、复杂查询、更新操作 用 MongoRepository 做声明式查询(方法命名 + @Query) 聚合管道的 Java 写法初探 一个完整的"用户自定义表单"功能从零到一的实现 二、前置条件 前置项 具体要求 验证命令 JDK 17+(文中用 17,8+ 均兼容) java -version Maven 3.6+ mvn -v SpringBoot 3.x(文中用 3.2.0) mvn dependency:tree | grep spring-boot MongoDB 7.0(6.x 也兼容文中所有操作) mongosh --eval "db.version()" 前置知识 SpringBoot 基础、MongoDB 核心概念(第一篇) — Part 2:教程版 —— 从零掌握 MongoDB 全部操作 下面每一节都给出了完整的、可运行的代码。整个教程版使用同一个技术栈:Spring Boot 3.x + spring-boot-starter-data-mongodb,所有操作通过 MongoTemplate 和 MongoRepository 完成。 ...

十月 27, 2022 · 11 分钟 · 2206 字 · yaomingye

Elasticsearch 生产调优与索引设计

Elasticsearch 生产调优 📖 前置阅读:本文是 ES 系列的生产调优篇,假设读者已经掌握了 ES 核心概念、SpringBoot 操作和高级搜索聚合。如果还没有,建议先阅读前三篇: Elasticsearch 核心概念:倒排索引、分词器与 REST API 全解析 —— 介绍篇 SpringBoot Elasticsearch 全操作指南 —— 实战篇 ES 高级搜索与聚合分析 —— 进阶篇 一、⚡ 问题切入:搜索怎么越来越慢了? 商品从 10 万增加到 500 万,搜索响应时间从原来的 50ms 涨到了 2 秒。用户开始投诉"搜索好慢",产品经理开始质疑"ES 不是很快吗"。 你打开监控面板,发现: 搜索 P99 延迟 2.3 秒 ES 堆内存使用率 85% 磁盘 IO 等待时间飙升 GC 频率从每小时 2 次变成了每 5 分钟 1 次 问题出在哪?不一定是数据量大就一定慢。500 万数据对 ES 来说远没到上限——一个设计良好的 3 节点集群处理几亿数据都没问题。慢的往往是索引设计不合理、查询写得不高效、分页方式用错了。 本篇要解决的问题:怎么设计索引让 500 万数据搜索保持在 100ms 以内,以及遇到性能问题时从哪下手排查。 二、🗂️ 索引设计最佳实践 2.1 分片数设计 —— 不是越多越好 ES 把一个 Index 的数据切分成多个分片(Shard)分布在不同节点上。每个分片本质上是一个独立的 Lucene 实例——有自己的倒排索引、段文件、内存开销。 ...

十月 25, 2022 · 12 分钟 · 2352 字 · yaomingye

ES 高级搜索与聚合分析

ES 高级搜索 📖 前置阅读:本文是 ES 系列的进阶篇,假设读者已经掌握了 ES 核心概念(倒排索引、分词器、Mapping)和 SpringBoot 的基本操作。如果还没有,建议先阅读前两篇: Elasticsearch 核心概念:倒排索引、分词器与 REST API 全解析 —— 介绍篇 SpringBoot Elasticsearch 全操作指南 —— 实战篇 一、⚡ 问题切入:搜索结果不够准怎么办? 前面两篇学完,你已经可以搭建一个"能搜"的商品搜索功能了。但用户搜"苹果手机"时,排名第一的可能是"苹果水果礼盒"——因为倒排索引中"苹果"这个词也出现了。 问题出在几个地方: 用户搜"苹果手机"时,商品名包含"苹果手机"这四个字的应该排在最前面,但基础 match 查询没有考虑字段匹配的完整度 商品标题命中的权重应该比描述命中的权重更高,但基础查询一视同仁 用户期望按销量和评分来影响排序,而不仅仅是文本相关性 输入"苹果手鸡"应该能自动纠错成"苹果手机" 本篇要解决的问题就是:怎么让搜索结果更准、排序更合理、用户体验更接近 Google 搜索。 二、🔍 全文搜索再深入 2.1 multi_match —— 多字段搜索 第一篇的 match 查询只搜一个字段。实际产品中,搜索词可能同时匹配商品名、品牌名、描述等多个字段——用户输入"华为手机",应该既搜 name 也搜 description,甚至搜 brand。 multi_match 就是为此而生的。它有三种模式,差异在于多字段之间如何计算和合并相关性分数: flowchart LR classDef mode fill:#450a0a,stroke:#dc2626,stroke-width:1.5px,color:#fecaca,font-weight:bold; classDef field fill:#0f172a,stroke:#3b82f6,stroke-width:1.5px,color:#bfdbfe,font-weight:bold; MM[multi_match\n搜索苹果手机] MM --> BF[best_fields\n取最优字段的分数] MM --> MF[most_fields\n各字段分数累加] MM --> CF[cross_fields\n跨字段组合匹配] BF --> BF_EX["name=苹果手机 → 10分\ndescription=苹果... → 2分\n最终得分:10分"] MF --> MF_EX["name=苹果... → 5分\ndescription=手机... → 3分\n最终得分:8分"] CF --> CF_EX["name=苹果 + detail=手机\n作为一个整体匹配\n最终得分:匹配两个字段"] class BF,MF,CF mode; class BF_EX,MF_EX,CF_EX field; best_fields(默认模式):搜索词在所有字段中分别执行匹配,取分数最高的那个字段作为最终得分。适合"搜索词大概率完整出现在某一个字段中"的场景——比如用户搜完整商品名。 ...

十月 24, 2022 · 10 分钟 · 2102 字 · yaomingye

SpringBoot Elasticsearch 全操作指南

SpringBoot Elasticsearch 📖 前置阅读:本文假设读者已了解 ES 的倒排索引、分词器、Mapping 和 REST API 基础操作。如果还不熟悉,建议先阅读 Elasticsearch 核心概念:倒排索引、分词器与 REST API 全解析。 本文按照"先搞懂操作 → 教程版完整实现 → 生产版四种模式 → 验证排错“的顺序组织。如果你只想快速上手 ElasticsearchRestTemplate 的 CRUD 和搜索,读完 Part 1 后直接看 Part 2 即可;如果你想理解真实项目中 ES 是怎么承载搜索、同步、秒杀、推荐四种场景的,需要完整读完。 关于版本:Part 2 教程版使用 Spring Boot 3.x + 新版 ElasticsearchClient(spring-boot-starter-data-elasticsearch 自动配置);Part 3 生产版使用 Spring Boot 2.7.x + RestHighLevelClient(手动创建 Bean)。两个版本不能混用——读者根据自己的 Spring Boot 版本选择对应的代码。 Part 1:先搞懂要做什么 一、目标说明 这篇文章的目标很明确:让读者在一篇文章内学会 SpringBoot 项目中所有常用的 ES 操作,读完就能直接写到项目里。 具体来说,读完这篇文章会掌握: 用 @Document 和 @Field 注解定义 ES 映射 用 ElasticsearchRestTemplate 执行 CRUD、搜索、聚合、高亮 用 Spring Data ES Repository 做声明式查询 批量写入、条件删除 和 真实场景串联 一个完整的"商品搜索"功能从零到一的完整代码 二、前置条件 前置项 具体要求 验证命令 JDK 17+(文中用 17,8+ 均兼容) java -version Maven 3.6+ mvn -v SpringBoot 3.x(文中用 3.2.0) mvn dependency:tree | grep spring-boot Elasticsearch 8.x(7.x 也兼容文中大部分操作,需调整配置) curl -u elastic http://localhost:9200 前置知识 SpringBoot 基础、ES 核心概念(倒排索引、分词器、Mapping) — Part 2:教程版 —— 从零掌握 ES 全部操作 下面每一节都给出了完整的、可运行的代码。整个教程版使用同一个技术栈:Spring Boot 3.x + spring-boot-starter-data-elasticsearch,通过 ElasticsearchRestTemplate 操作 ES。 ...

十月 23, 2022 · 14 分钟 · 2948 字 · yaomingye

Redis 缓存策略进阶:六大模式全解析

🚀 Redis 缓存策略进阶:六大模式全解析 📖 前置阅读:本文是 SpringBoot Redis 系列的进阶篇,假设读者已经掌握了 Redis 的基本数据结构和 SpringBoot 环境下的 RedisTemplate 操作。如果还没有,建议先阅读前两篇: Redis 核心架构:五大数据结构与常用命令全解析 —— 介绍篇 SpringBoot Redis 全操作指南 —— 实战篇 一、⚡ 问题切入:没有缓存策略会怎样? 先看一段日常开发中常见的业务代码: // 一个典型的"查缓存 → 查 DB → 写缓存"逻辑 public User getUserById(Long userId) { String cacheKey = "user:" + userId; // 1. 先查 Redis 缓存 User user = (User) redisTemplate.opsForValue().get(cacheKey); if (user != null) { return user; } // 2. 缓存未命中,查 MySQL user = userMapper.selectById(userId); if (user != null) { // 3. 写入 Redis 缓存,设置 30 分钟过期 redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES); } return user; } public void updateUser(User user) { // 更新 DB userMapper.updateById(user); // 删除缓存(而非更新缓存) redisTemplate.delete("user:" + user.getId()); } 这段代码隐含了一个被广泛使用的模式—— Cache-Aside(旁路缓存) 。但这就是全部吗?当业务场景从"普通查询"扩展到"秒杀库存扣减"、“热点榜单刷新”、“写多读少日志落盘"时,上面这段代码会暴露出以下问题: ...

十月 21, 2022 · 16 分钟 · 3330 字 · yaomingye

SpringBoot Redis 全操作指南

🚀 SpringBoot Redis 全操作指南 📖 前置阅读:本文假设读者已了解 Redis 的五种核心数据结构(String / Hash / List / Set / ZSet)和基本命令。如果还不熟悉,建议先阅读 Redis 核心架构:五大数据结构与常用命令全解析。 🎯 第一步:目标说明 这篇文章的目标很明确:让读者在一篇文章内学会 SpringBoot 项目中所有常用的 Redis 操作,读完就能直接写到项目里。 具体来说,读完这篇文章会掌握: 用 StringRedisTemplate 和 RedisTemplate 操作 Redis 五种数据结构 用 Spring Cache 注解(@Cacheable、@CachePut、@CacheEvict)无侵入地加缓存 用 Redisson 实现分布式锁 Pipeline 批量操作和发布订阅 排行榜、计数器、消息队列等真实业务场景的完整代码 文中的所有代码都可以直接复制粘贴到项目里,只需要改包名和类名。 📋 第二步:前置条件 开始之前,确认以下知识储备和环境就绪: 前置项 具体要求 验证命令 JDK 17+(文中用 17,8+ 均兼容) java -version Maven 3.6+ mvn -v SpringBoot 3.x(文中用 3.2.0) mvn dependency:tree | grep spring-boot Redis 7.x(6.x 也兼容文中所有操作) redis-cli --version IDE IntelliJ IDEA / VS Code / Eclipse 均可 — 前置知识 SpringBoot 基础(依赖注入、application.yml)、SQL 基础、Linux 命令行基础 — 📌 前置知识:读者需要了解 SpringBoot 的 @Configuration、@Bean、@Autowired 基本用法,以及 application.yml 配置文件的写法。如果不熟悉 Maven 的 pom.xml 依赖管理,建议先补一下 SpringBoot 入门。 ...

十月 20, 2022 · 17 分钟 · 3462 字 · yaomingye

Spring Boot 面试突击

Spring Boot 面试突击:高频考点全面解析 📌 前置知识:阅读本文需要具备 Java 基础、Servlet 基础、Spring 基础(IoC / AOP / Bean 容器概念)。本文定位为面试突击速查手册,每个考点都按"面试怎么答"组织,建议配合实际项目经验一起记忆。 📊 各模块面试频率参考 在开始具体考点之前,先了解各模块的面试出现频率,有助于合理分配背诵时间: 模块 面试频率 重要程度 基础概念 ⭐⭐⭐⭐⭐ 每场必问,开场热身 核心注解 ⭐⭐⭐⭐⭐ @SpringBootApplication 必问 自动配置原理 ⭐⭐⭐⭐⭐ 灵魂考点,区分候选人水平 配置文件 ⭐⭐⭐⭐⭐ 多环境配置高频出现 事务管理 ⭐⭐⭐⭐⭐ 事务失效原因超高频 Bean 生命周期 ⭐⭐⭐⭐⭐ 面试官最爱追问 Web/MVC ⭐⭐⭐⭐ 结合项目经验考察 AOP ⭐⭐⭐⭐ 原理 + 应用场景 Starter ⭐⭐⭐⭐ 自定义 Starter 加分项 高级特性 ⭐⭐⭐⭐ 3.x 变化、热部署 Actuator ⭐⭐⭐ 生产经验加分 重点背诵:自动配置原理、事务失效原因、Bean 生命周期、@SpringBootApplication 组成、配置加载优先级。 📖 一、基础概念题 ❓ 1.1 什么是 Spring Boot?与 Spring、Spring MVC 的关系? 这是最基础的面试开场题,回答需要简洁清晰、一句话点明三者关系。 ...

十月 17, 2022 · 11 分钟 · 2166 字 · yaomingye
Cat Radio