文章 557
评论 5
浏览 215530
Spring Boot + QQ 邮箱实现邮件推送

Spring Boot + QQ 邮箱实现邮件推送

导语 在现代应用中,邮件推送是一种常见的功能,用于用户注册验证、密码重置、业务通知等场景。QQ邮箱作为国内常用的邮箱服务,提供了稳定的SMTP服务,方便开发者集成到应用中。本文将介绍如何在Spring Boot应用中集成QQ邮箱的SMTP服务,实现邮件推送功能。通过本文的技术方案,您将能够快速实现邮件发送功能,为应用添加通知能力。 一、QQ邮箱SMTP服务配置 1.1 开启SMTP服务 登录QQ邮箱 访问 https://mail.qq.com/ 并登录您的QQ邮箱 进入设置页面 点击顶部导航栏的「设置」按钮 选择「账户」选项卡 开启SMTP服务 找到「POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务」部分 开启「SMTP服务」 生成授权码 点击「生成授权码」 按照提示完成验证(通常需要短信验证) 复制生成的授权码,这将作为邮件发送的密码 1.2 重要注意事项 授权码而非QQ密码:使用SMTP服务时,需要使用生成的授权码作为密码,而不是QQ登录密码 安全保存:授权码具有与密码相同的权限,需要安全保存 定期更新:如果担....

SpringBoot + 分页深度优化 + 游标+时间戳:千万级数据翻到第 10 万页依然毫秒响应

SpringBoot + 分页深度优化 + 游标+时间戳:千万级数据翻到第 10 万页依然毫秒响应

导语 在大数据量的系统中,分页查询是一个常见的需求。传统的基于 OFFSET 和 LIMIT 的分页方式在处理大数据量时会遇到性能瓶颈,特别是当翻到较深的页面时,查询速度会变得非常慢。本文将介绍一种基于游标和时间戳的分页优化方案,通过避免使用 OFFSET,实现千万级数据的高效分页,即使翻到第 10 万页依然能保持毫秒级响应。 一、传统分页的性能问题 1.1 传统分页的实现 基于 OFFSET 和 LIMIT 的分页 -- 第 1 页,每页 10 条 SELECT * FROM users ORDER BY id DESC LIMIT 10 OFFSET 0; -- 第 10 万页,每页 10 条 SELECT * FROM users ORDER BY id DESC LIMIT 10 OFFSET 999990; 1.2 性能问题分析 1. 数据扫描 当 OFFSET 很大时,数据库需要扫描大量数据 例如,OFFSET 999990 时,数据库需要扫描 100 万条数据才能返回 10 条结果 随着页码的增加,扫描的数据量线性增长 2. 索引使用 虽然使用了索引,但 OFFS....

SpringBoot + MySQL JSON 字段 + 虚拟列索引:灵活存储配置,查询性能不妥协

SpringBoot + MySQL JSON 字段 + 虚拟列索引:灵活存储配置,查询性能不妥协

导语 在现代应用开发中,灵活的数据存储需求越来越常见。传统的关系型数据库表结构难以应对频繁变化的业务需求,而 NoSQL 数据库虽然灵活但缺乏事务支持。MySQL 5.7+ 引入的 JSON 字段类型为我们提供了一种折中的解决方案,既保持了关系型数据库的可靠性,又获得了 NoSQL 的灵活性。 然而,JSON 字段的查询性能一直是一个挑战。MySQL 8.0 引入的虚拟列索引技术为解决这个问题提供了可能,使得我们可以在 JSON 字段上创建索引,获得接近传统列的查询性能。 本文将介绍如何在 SpringBoot 应用中使用 MySQL JSON 字段和虚拟列索引,实现灵活存储配置的同时,不妥协查询性能。 一、MySQL JSON 字段的特性与优势 1.1 JSON 字段的基本特性 1. 数据类型 MySQL 5.7+ 支持原生 JSON 数据类型 自动验证 JSON 格式的有效性 提供丰富的 JSON 函数进行操作 2. 存储方式 采用二进制格式存储,更紧凑高效 支持快速访问 JSON 对象的特定元素 避免了传统文本存储的解析开销 3. 操作函数 JSON_EXTRACT()....

SpringBoot + Redis 缓存击穿防护 + 互斥重建:热点 Key 过期时,仅一个线程回源 DB

SpringBoot + Redis 缓存击穿防护 + 互斥重建:热点 Key 过期时,仅一个线程回源 DB

导语 在高并发系统中,缓存是提升性能的关键手段。然而,当热点 Key 过期时,大量并发请求同时穿透缓存直接访问数据库,可能导致数据库压力骤增甚至宕机。这种现象被称为"缓存击穿"。 本文将介绍如何在 SpringBoot 应用中实现 Redis 缓存击穿防护和互斥重建机制,确保热点 Key 过期时,只有一个线程回源数据库,其他线程等待或使用旧数据,从而保护数据库免受高并发冲击。 一、缓存击穿的概念与危害 1.1 什么是缓存击穿 缓存击穿是指某个热点 Key 在高并发访问时突然过期,导致大量并发请求同时穿透缓存直接访问数据库的现象。 场景描述: 某个商品信息被大量用户频繁访问 该商品的缓存 Key 设置了过期时间 缓存过期瞬间,大量请求同时到达 所有请求都发现缓存不存在,同时访问数据库 数据库瞬间承受巨大压力,可能导致宕机 1.2 缓存击穿与相关概念的区别 概念描述解决方案 缓存击穿热点 Key 过期,大量请求同时访问数据库互斥锁、永不过期 缓存穿透查询不存在的数据,请求直接访问数据库布隆过滤器、缓存空值 缓存雪崩大量 Key 同时过期,导致数据库压力骤增过期时间随机化、预热 ....

SpringBoot + 分布式锁 + 事务超时回滚:跨服务操作超时自动释放资源,防死锁

SpringBoot + 分布式锁 + 事务超时回滚:跨服务操作超时自动释放资源,防死锁

导语 在分布式系统中,跨服务操作是常见的场景。然而,当多个服务同时操作共享资源时,可能会出现竞态条件和死锁问题。分布式锁是解决这类问题的有效手段,但如何处理锁的超时释放和事务的回滚,是一个需要仔细考虑的问题。 一、分布式锁的原理与实现 1.1 分布式锁的概念 分布式锁是一种在分布式系统中用于协调多个服务对共享资源访问的机制。它确保在同一时间只有一个服务能够访问特定的资源,从而避免竞态条件和数据不一致的问题。 1.2 分布式锁的实现方式 1. 基于 Redis 的分布式锁 使用 Redis 的 SETNX 命令 支持过期时间设置 实现简单,性能高 2. 基于 ZooKeeper 的分布式锁 使用 ZooKeeper 的临时节点 支持顺序锁和公平锁 可靠性高,但性能相对较低 3. 基于数据库的分布式锁 使用数据库的唯一约束 实现简单,但性能较低 1.3 分布式锁的特性 特性描述 互斥性同一时间只有一个服务能够获取锁 可重入性同一服务可以多次获取同一把锁 超时释放锁在一定时间后自动释放,防止死锁 高可用性锁服务高可用,避免单点故障 公平性按照请求顺序获取锁 二、事务超....

SpringBoot + 最终一致性 + 补偿任务看板:失败事务可视化,支持人工介入重试

SpringBoot + 最终一致性 + 补偿任务看板:失败事务可视化,支持人工介入重试

背景:分布式事务的挑战 在微服务架构中,分布式事务是一个常见的挑战。传统的2PC(两阶段提交)方案虽然能保证强一致性,但性能开销大,不适合高并发场景。而最终一致性方案虽然性能更好,但如何确保事务最终达成一致,以及如何处理失败的事务,成为了新的挑战。 想象一下这些场景: 订单创建成功,但库存扣减失败 支付成功,但订单状态更新失败 消息发送成功,但消费者处理失败 跨服务调用时网络中断,部分操作成功部分失败 这些问题如果不及时处理,会导致系统数据不一致,影响业务正常运行。 核心概念:最终一致性 + 补偿任务看板 本文将介绍一种基于 SpringBoot 的最终一致性解决方案,通过以下核心机制确保分布式事务的最终一致性: 事务日志:记录每笔分布式事务的执行状态 补偿机制:自动或手动处理失败的事务 任务看板:可视化展示失败事务,支持人工介入 重试策略:智能的重试机制,避免无效重试 架构设计 系统架构 ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 微服务 A │ │ 微服务 B │ │ 微服务 C │ └────....

SpringBoot + 事务日志快照 + 定时对账:每日自动比对订单与支付状态,差异自动修复

SpringBoot + 事务日志快照 + 定时对账:每日自动比对订单与支付状态,差异自动修复

背景:订单与支付状态不一致的困扰 在电商、金融等系统中,订单状态与支付状态不一致是一个常见且棘手的问题。想象一下这些场景: 用户支付成功,但订单状态仍显示"待支付" 订单显示"已支付",但支付平台显示"支付失败" 系统崩溃导致部分交易数据丢失 网络延迟造成状态更新不同步 这些问题不仅影响用户体验,还可能导致财务风险和审计难题。传统的解决方案往往依赖人工对账,效率低下且容易出错。 核心概念:事务日志快照 + 定时对账 本文将介绍一种基于 SpringBoot 的自动化解决方案,通过以下核心机制实现订单与支付状态的一致性保障: 事务日志快照:记录每笔交易的状态变更历史 定时对账:定期比对订单系统与支付系统的状态 自动修复:发现差异后自动进行状态修正 异常处理:对无法自动修复的情况进行告警 架构设计 系统架构 ┌───────────────┐ ┌────────────────┐ ┌─────────────────┐ │ 订单系统 │ │ 支付系统 │ │ 对账系统 │ └───────────────┘ └────────────────┘ └─────────────────....

SpringBoot + Redis 实现登录校验:分布式会话管理,安全又高效

SpringBoot + Redis 实现登录校验:分布式会话管理,安全又高效

一、问题背景:为什么需要 Redis 实现登录校验? 在传统的单体应用中,我们通常使用 Session 来管理用户登录状态。但在微服务架构和分布式系统中,Session 面临着诸多挑战: 传统 Session 的痛点 单点故障:Session 存储在单个服务器上,服务器宕机会导致所有用户登录状态丢失 无法水平扩展:多台服务器之间无法共享 Session,用户请求可能被路由到不同服务器导致登录失效 内存压力:大量用户 Session 占用服务器内存,影响性能 跨域问题:前后端分离架构下,Session 跨域处理复杂 Redis 方案的优势 特性传统 SessionRedis + Token 分布式支持❌ 不支持✅ 天然支持 水平扩展❌ 困难✅ 容易 性能⚠️ 内存受限✅ 独立缓存服务 跨域❌ 复杂✅ 天然支持 安全性⚠️ 一般✅ 可设置过期时间 持久化❌ 易丢失✅ 可持久化 二、核心概念:Token + Redis 认证机制 1. 认证流程 ┌─────────────┐ 1. 登录请求 ┌─────────────┐ │ 客户端 │ ─────────────────&....

SpringBoot + 网关动态降级开关 + 配置中心联动:突发故障时,一键关闭非核心路由

SpringBoot + 网关动态降级开关 + 配置中心联动:突发故障时,一键关闭非核心路由

一、问题背景:为什么需要动态降级? 在生产环境中,我们经常面临各种突发情况: 真实案例 去年双11大促期间,某电商平台遇到了一个棘手的问题: 场景:大促开始后 10 分钟,订单系统突然出现大量超时,导致用户无法下单。 原因:推荐服务(非核心功能)调用了第三方 AI 接口,由于第三方服务响应变慢,大量线程被阻塞,最终拖垮了整个网关。 后果:核心的下单、支付功能也受到了影响,造成了巨大的经济损失。 反思:如果当时能够快速关闭非核心路由(如推荐、广告、评论等),保留核心路由(如下单、支付),就能将损失降到最低。 传统降级方式的不足 方式优点缺点 代码硬编码简单直接需要重新部署,响应慢 配置文件修改相对灵活需要重启服务,影响用户体验 数据库开关可以动态修改需要额外的数据库查询,性能损耗 Redis 缓存响应快需要额外的缓存维护成本 动态降级开关的优势 动态降级开关是一种基于配置中心的降级方案,具有以下优势: 秒级响应:无需重启,配置修改立即生效 精细控制:可以针对单个路由或一组路由进行降级 可视化操作:通过配置中心界面进行操作,降低出错概率 历史追溯:记录降级操作历史,便于事后分....

SpringBoot + 网关请求聚合 + 并行调用优化:多个微服务接口合并为一次响应,减少 RTT

SpringBoot + 网关请求聚合 + 并行调用优化:多个微服务接口合并为一次响应,减少 RTT

引言:一次性能优化的启示 我们的移动端 App 首页加载速度一直被用户吐槽。经过排查发现,首页需要调用 7 个微服务接口,每个接口平均耗时 100ms,串行调用导致总耗时高达 700ms。 用户体验极差,用户等待时间过长,转化率大幅下降。 通过引入网关请求聚合 + 并行调用优化,我们将首页加载时间从 700ms 降低到 150ms,性能提升 4.6 倍! 今天,我就来分享这个优化方案。 一、问题分析:为什么需要请求聚合? 1.1 传统串行调用的问题 ┌─────────────────────────────────────────────────────────────┐ │ 传统串行调用模式(问题) │ ├─────────────────────────────────────────────────────────────┤ │ │ │ 客户端 │ │ │ │ │ │ 1. 请求用户信息 (100ms) │ │ ├───────────────────────────────────────────────────────>│ │ │ │ │ │ 2. 请求订单信息 (....

SpringBoot + 消息回溯重放 + 时间点恢复:数据修复时,精准重放某时段消息流

SpringBoot + 消息回溯重放 + 时间点恢复:数据修复时,精准重放某时段消息流

引言:数据修复的噩梦 去年公司的订单系统因为数据库主从同步延迟导致数据不一致。部分订单状态错误,用户投诉不断,客服电话被打爆。当时我们花了整整两天时间才修复完所有数据。 数据修复是分布式系统中不可避免的问题。无论是数据库同步延迟、消息丢失、还是业务逻辑错误,都可能导致数据不一致。传统的修复方式效率低下,容易出错。 消息回溯重放是解决这个问题的利器。通过记录和重放消息流,我们可以精准地修复某个时间段的数据,就像时光倒流一样。 一、消息回溯重放:概念与重要性 1.1 什么是消息回溯重放? 消息回溯重放是指将历史消息按照时间顺序重新投递到消息队列,让消费端重新处理,从而达到修复数据的目的。 类比生活中的例子: 录像回放:就像看体育比赛的录像回放,可以回到任意时间点重新观看 游戏存档:就像游戏的存档功能,可以回到某个存档点重新开始 Git 回滚:就像 Git 的版本控制,可以回到任意提交点重新开发 1.2 为什么需要消息回溯重放? ┌─────────────────────────────────────────────────────────────┐ │ 消息回溯重放的应用场景 │....

SpringBoot + WebSocket 消息 QoS(服务质量):在线推优先,离线存库,确保不丢关键通知

SpringBoot + WebSocket 消息 QoS(服务质量):在线推优先,离线存库,确保不丢关键通知

引言:消息丢失的噩梦 公司的订单系统因为网络抖动导致大量关键通知丢失。用户下单后没有收到支付提醒,商家也没有收到新订单通知,最终导致订单超时取消,用户投诉,GMV 损失惨重。 实时消息推送是现代 Web 应用的核心功能,但面临着诸多挑战: 网络不稳定:用户网络波动导致连接断开 客户端离线:用户关闭浏览器或 APP 离线 消息堆积:高峰期消息量过大导致推送延迟 消息丢失:关键通知丢失导致业务异常 QoS(Quality of Service,服务质量) 是解决这些问题的关键。本文将带你深入理解 WebSocket 消息 QoS 机制,并使用 Spring Boot 实现一套完整的消息推送方案。 一、WebSocket 消息 QoS:概念与重要性 1.1 什么是消息 QoS? QoS(Quality of Service) 是指消息传输的服务质量等级,用于保证消息的可靠传输。 类比生活中的例子: QoS 0(最多一次):普通信件,可能丢失 QoS 1(至少一次):挂号信,保证送达但可能重复 QoS 2(恰好一次):快递签收,保证送达且不重复 1.2 MQTT 协议中的 QoS 等....

SpringBoot + 消息生产幂等 + 唯一 ID 去重:前端重复点击,后端只处理一次

SpringBoot + 消息生产幂等 + 唯一 ID 去重:前端重复点击,后端只处理一次

引言:重复提交的噩梦 去年公司的秒杀系统因为用户疯狂点击"立即购买"按钮,导致同一个订单被重复提交了10次。虽然前端做了按钮禁用,但用户可以通过刷新页面、网络重试等方式绕过限制。最终导致库存超卖,用户投诉,运营背锅。 重复提交是 Web 应用中常见的问题,特别是在以下场景: 用户快速点击提交按钮 网络超时导致用户重复提交 浏览器后退后重新提交 前端表单重复提交 **幂等性(Idempotence)**是解决这个问题的关键。一个幂等的操作,无论执行多少次,结果都是一样的。 本文将带你深入理解幂等性,并使用 Spring Boot + Redis 实现一套完整的幂等性控制方案。 一、幂等性:概念与重要性 1.1 什么是幂等性? 定义:一个操作,无论执行一次还是多次,其产生的结果都是相同的。 数学表达:f(x) = f(f(x)) 生活中的例子: 幂等操作:设置手机铃声(无论设置多少次,结果都是同一铃声) 非幂等操作:银行转账(转100元,转两次就是200元) 1.2 HTTP 方法与幂等性 HTTP 方法幂等性说明 GET✅ 幂等获取资源,多次获取结果相同 HEAD✅ 幂....

SpringBoot + 消息消费积压自动扩容:Kafka/RabbitMQ 堆积超阈值,自动触发 Pod 水平伸缩

SpringBoot + 消息消费积压自动扩容:Kafka/RabbitMQ 堆积超阈值,自动触发 Pod 水平伸缩

导语 在微服务架构中,消息队列是一种常用的解耦和异步处理机制。然而,当系统面临突发流量或消费能力不足时,消息队列可能会出现积压现象,导致系统性能下降甚至服务不可用。 传统的消息消费系统通常需要人工监控和手动扩容,这种方式不仅反应迟缓,而且容易出错。本文将介绍如何在 SpringBoot 应用中实现消息消费积压的自动扩容机制,当 Kafka 或 RabbitMQ 消息堆积超过阈值时,自动触发 Kubernetes Pod 的水平伸缩,确保系统的稳定性和可靠性。 一、消息消费积压的问题分析 1.1 消息积压的原因 1. 突发流量 促销活动、秒杀场景等导致消息量突然增加 系统故障恢复后,大量延迟消息涌入 上游服务重试机制导致消息重复发送 2. 消费能力不足 消费者处理速度慢 消费者数量不足 消费者资源限制(CPU、内存) 3. 系统瓶颈 网络延迟 数据库性能瓶颈 外部服务调用延迟 1.2 消息积压的影响 影响描述 系统延迟消息处理延迟增加,影响用户体验 资源浪费消息队列存储资源被占用 数据丢失消息队列达到存储上限可能导致消息丢失 系统不稳定积压严重时可能导致系统崩溃 业务....

SpringBoot + 规则灰度发布 + 百分比流量切分:新规则先对 1% 用户生效,验证无误再全量

SpringBoot + 规则灰度发布 + 百分比流量切分:新规则先对 1% 用户生效,验证无误再全量

导语 在企业应用中,规则变更往往涉及业务逻辑的调整,直接全量发布可能带来较大的风险。灰度发布是一种有效的风险控制策略,通过将新规则先对小部分用户生效,验证无误后再逐步扩大范围,最终实现全量发布。 一、灰度发布的概念与原理 1.1 什么是灰度发布 灰度发布(Gray Release)是一种软件发布策略,通过将新功能先对一部分用户开放,验证无误后再逐步扩大范围,最终实现全量发布。在规则系统中,灰度发布可以用于验证新规则的效果,确保规则变更不会对业务造成负面影响。 1.2 灰度发布的优势 优势描述 风险控制小范围验证,降低发布风险 快速回滚出现问题时可以快速回滚 用户反馈收集用户反馈,优化规则 性能验证验证新规则的性能影响 平滑过渡实现规则的平滑过渡 1.3 灰度发布的策略 1. 基于用户的灰度 按用户 ID 或用户属性进行灰度 适用于需要用户体验反馈的场景 2. 基于流量的灰度 按请求比例进行灰度 适用于性能验证和稳定性测试 3. 基于时间的灰度 按时间逐步扩大灰度范围 适用于计划中的发布 4. 基于地域的灰度 按地域进行灰度 适用于区域性业务 二、技术方案设计....

服务端开发博客:后端架构、高并发、性能优化与微服务实战教程