文章 557
评论 5
浏览 215530
SpringBoot + 冷热数据分离 + 自动归档:历史订单自动迁移至归档库,主库轻量化

SpringBoot + 冷热数据分离 + 自动归档:历史订单自动迁移至归档库,主库轻量化

前言 上个月,公司电商平台的订单查询接口突然变慢,用户投诉不断。排查后发现,订单表已经有几百万条数据,单表查询性能急剧下降。DBA建议我们尽快进行数据归档,但手动操作风险大、效率低。 我们花了一周时间,基于SpringBoot开发了一套冷热数据分离和自动归档系统,实现了历史订单自动迁移至归档库,主库瞬间轻量化。现在查询性能提升了80%,运维效率也大大提高。 今天就把这套方案分享给大家。 问题背景 在高并发电商系统中,数据量快速增长是一个常见问题,经常会遇到以下挑战: 单表数据量过大:订单表达到百万甚至千万级 查询性能下降:热点查询响应时间变长 存储成本增加:数据库存储压力不断增大 维护难度加大:备份、恢复、扩容变得困难 业务影响严重:数据库性能问题直接影响用户体验 这些问题会导致: 用户体验下降 运维成本上升 系统扩展困难 业务发展受限 技术债务累积 传统方案 vs 优化方案 传统方案:手动归档 // 传统手动归档流程 public void manualArchive() { // 1. 查询需要归档的数据 List<Order> oldOrders = orde....

SpringBoot + 全文检索 + ngram 分词 示例工程

SpringBoot + 全文检索 + ngram 分词 示例工程

项目简介 本项目是一个基于Spring Boot的中文模糊搜索示例工程,演示了如何使用MySQL的全文检索和ngram分词器来实现高性能、支持中文分词和错别字容错的搜索功能。 核心功能 全文检索 :使用MySQL的全文检索功能,提高搜索性能 ngram分词 :使用MySQL的ngram分词器,支持中文分词 错别字容错 :结合编辑距离算法,支持错别字搜索 缓存优化 :使用Redis缓存搜索结果,提高响应速度 异步事件 :使用Spring事件机制,处理商品更新时的缓存清除 测试数据 :提供测试数据生成功能,方便测试搜索性能 技术栈 Spring Boot 2.7.5 Spring Web Spring Data JPA Spring Data Redis MySQL 8.0 Lombok 工程结构 chinese-search-demo/ ├── src/ │ ├── main/ │ │ ├── java/com/example/demo/ │ │ │ ├── config/ # 配置类 │ │ │ ├── controller/ # 控制器 │ │ │ ├── dto/ # 数据....

SpringBoot + MySQL 唯一索引 + ON DUPLICATE KEY:高并发注册防重,性能提升 5 倍

SpringBoot + MySQL 唯一索引 + ON DUPLICATE KEY:高并发注册防重,性能提升 5 倍

一、高并发注册的噩梦 公司APP正在做推广活动,用户注册量激增,每秒有上千个注册请求。问题也随之而来: 重复注册:同一个用户账号被注册了多次 数据不一致:用户表中有大量重复的邮箱和手机号 性能下降:注册接口的响应时间从100ms飙升到了500ms以上 数据库压力:MySQL的CPU使用率居高不下 已经在代码里做了查重逻辑,但高并发下还是会出现重复注册。"这样的场景,作为后端开发的你,是不是也遇到过? 二、传统方案的局限性 为了防止重复注册,我们通常会使用以下方案: 1. 查询后插入 // 1. 先查询用户是否存在User existUser = userRepository.findByUsername(username);if (existUser != null) { throw new RuntimeException("用户名已存在");}// 2. 如果不存在,则插入新用户User newUser = new User();newUser.setUsername(username);userRepository.save(newUser); 这种方案的问题: 并发问题....

SpringBoot + 全文检索 + ngram 分词:中文模糊搜索响应毫秒级,支持错别字容错

SpringBoot + 全文检索 + ngram 分词:中文模糊搜索响应毫秒级,支持错别字容错

一、中文搜索的痛点 上周,一位做电商的朋友找我抱怨:他们的商品搜索功能太烂了。"用户搜索 'iPhone 13',结果只出来几个完全匹配的,"他说,"如果用户输入 'iphone13'、'苹果13'、'IPHONE 13',甚至打错字成 'ihpone 13',要么找不到结果,要么响应很慢。" 我打开他们的APP试了一下,确实如此: 搜索 "iPhone 13":找到10个结果,响应时间300ms 搜索 "iphone13":找到0个结果 搜索 "苹果13":找到0个结果 搜索 "ihpone 13":找到0个结果,响应时间800ms "我们用的是MySQL的LIKE查询,"朋友无奈地说,"'%关键词%'这种写法,数据量一大就很慢,而且不支持中文分词和错别字容错。"这样的搜索体验,用户怎么可能满意? 二、传统搜索方案的局限性 为了实现中文搜索,我们通常会使用以下方案: 1. MySQL LIKE查询 SELECT * FROM product WHERE name LIKE '%关键词%' OR description LIKE '%关键词%'; 这种方案的问题: 性能差:使用....

SpringBoot + MySQL 唯一索引 + ON DUPLICATE KEY 示例工程

SpringBoot + MySQL 唯一索引 + ON DUPLICATE KEY 示例工程

项目简介 本项目是基于Spring Boot的高并发注册示例工程,演示如何使用MySQL的唯一索引和ON DUPLICATE KEY UPDATE语法来防止重复注册,同时大幅提升系统性能。 核心功能 唯一索引:在用户名、邮箱、手机号等字段上创建唯一索引,保证数据的唯一性 ON DUPLICATE KEY:使用MySQL的INSERT ... ON DUPLICATE KEY UPDATE语法,实现原子性的插入或更新操作 性能优化:减少数据库操作次数,提高并发性能 注册日志:记录所有注册操作,便于问题排查和分析 技术栈 Spring Boot 2.7.5 Spring Web Spring Data JPA Spring Security MySQL 8.0 Lombok 工程结构 high-concurrency-register-demo/ ├── src/ │ ├── main/ │ │ ├── java/com/example/demo/ │ │ │ ├── config/ # 配置类 │ │ │ ├── entity/ # 实体类 │ │ │ ├── repositor....

SpringBoot + Redis 多级缓存 + L1/L2 自动同步:本地缓存与 Redis 一致性保障

SpringBoot + Redis 多级缓存 + L1/L2 自动同步:本地缓存与 Redis 一致性保障

一、缓存一致性的噩梦 之前参与过一个电商平台,使用了SpringBoot + Redis缓存架构。为了提高性能,在应用层也加入了本地缓存(Caffeine),形成了二级缓存架构: L1缓存:本地缓存(Caffeine),响应速度快 L2缓存:Redis缓存,支持分布式 原本以为这样可以兼顾性能和一致性,但实际运行中却出现了严重的缓存不一致问题。 用户在APP上看到的商品价格和库存信息经常与实际不符,有时候明明已经缺货的商品,页面上还显示有库存,导致用户下单后无法发货,投诉不断。 "我们的缓存更新策略是:修改数据时,先更新数据库,然后删除本地缓存,再删除Redis缓存。但还是会出现不一致的情况。" 这样的场景,作为后端开发的你,是不是也遇到过? 二、多级缓存一致性的挑战 在多级缓存架构中,一致性问题主要来自以下几个方面: 1. 更新顺序问题 如果先更新数据库,再删除缓存,可能会出现: 线程A:读取数据,发现缓存不存在 线程A:从数据库读取数据 线程B:更新数据库 线程B:删除缓存 线程A:将读取到的旧数据写入缓存 结果:缓存中存储的是旧数据 如果先删除缓存,再更新数据库,....

SpringBoot + 分布式 ID + 幂等令牌:跨服务调用防重复提交的终极方案

SpringBoot + 分布式 ID + 幂等令牌:跨服务调用防重复提交的终极方案

一、跨服务调用的重复提交噩梦 上周,一位朋友找我吐槽:他们公司的订单系统又出问题了。 用户在APP上下单,点击"提交"按钮后,因为网络延迟,页面没有立即响应,用户以为没提交成功,就又点击了一次。结果系统创建了两个相同的订单,用户收到了两条订单确认短信,商家也收到了两条订单通知。 更糟糕的是,这个问题不是第一次出现了。之前在支付、退款、发货等环节都发生过类似的重复操作问题。 "我们的系统是微服务架构,订单服务、支付服务、库存服务都是独立部署的,"朋友无奈地说,"跨服务调用的时候,很难保证操作不被重复执行。" 这样的场景,作为后端开发的你,是不是也遇到过? 二、为什么重复提交这么难解决? 在微服务架构下,重复提交问题变得更加复杂: 1. 网络不稳定 网络延迟、抖动、丢包等问题,可能导致客户端以为请求失败,从而重复发送请求。 2. 服务端处理延迟 服务端处理请求的时间过长,客户端超时后可能会重新发送请求。 3. 重试机制 为了提高系统的可靠性,很多系统都实现了自动重试机制,这也可能导致重复请求。 4. 跨服务调用 在微服务架构下,一个业务流程可能涉及多个服务的调用,任何一个环节的失败都可能导....

失败事务总是漏处理?教你用SpringBoot实现事务补偿+人工干预后台

失败事务总是漏处理?教你用SpringBoot实现事务补偿+人工干预后台

前言 上周生产环境出了个事故,订单系统在处理一笔重要订单时,支付服务调用失败了,虽然我们有异常处理,但后续的库存回滚、积分扣除等操作没有执行,导致数据不一致。 当时只能手动修复数据,费了很大劲才把数据恢复过来。这让我意识到,仅仅捕获异常还不够,我们需要一个完整的事务补偿机制,让失败的事务可查、可重试、可跳过。 今天就分享一下我们的解决方案。 问题背景 在分布式系统中,事务失败是不可避免的,经常会遇到以下问题: 事务失败后处理遗漏:异常处理后,某些操作没有执行 补偿逻辑复杂:需要编写大量补偿代码 缺乏监控手段:不知道哪些事务失败了需要补偿 人工干预困难:出现问题只能手动修复数据 补偿状态不透明:无法知道补偿是否成功 这些问题会导致: 数据不一致 业务流程中断 运维成本高 用户体验差 系统可靠性降低 传统方案 vs 优化方案 传统方案:手动补偿 // 订单创建流程 @Transactional public Order createOrder(OrderRequest request) { try { // 1. 创建订单 Order order = orderService.cr....

SpringBoot + 消息顺序性保障 + 分区键:订单状态变更严格按序处理,避免乱序

SpringBoot + 消息顺序性保障 + 分区键:订单状态变更严格按序处理,避免乱序

引言 在电商系统中,订单状态的变更是一个核心业务流程。从订单创建到支付、处理、发货、送达,每个状态变更都必须严格按照业务逻辑顺序执行。如果出现状态乱序,比如"已送达"的消息比"已发货"先到达,就会导致严重的业务逻辑错误。 传统的消息处理方式往往无法保证这种严格的顺序性要求,这就是我们今天要解决的核心问题:如何在SpringBoot应用中通过消息队列实现订单状态变更的严格按序处理。 问题场景分析 让我们先看一个典型的订单状态变更流程: 订单创建(CREATED) → 已支付(PAID) → 处理中(PROCESSING) → 已发货(SHIPPED) → 已送达(DELIVERED) 在高并发场景下,如果不做特殊处理,可能会出现这样的问题: - 消息1:订单ID=12345,状态:CREATED → PAID - 消息2:订单ID=12345,状态:PAID → PROCESSING - 消息3:订单ID=12345,状态:PROCESSING → SHIPPED 由于网络延迟、消息队列负载等因素,消费者可能以这样的顺序接收到消息: **消息3 → 消息1 → 消息2** 这就会导致....

SpringBoot + 多租户规则隔离:一套引擎服务千家企业,规则互不干扰

SpringBoot + 多租户规则隔离:一套引擎服务千家企业,规则互不干扰

大家好,今天我们来聊聊一个SaaS产品中的核心挑战:如何用一套规则引擎服务上千家企业客户,同时保证每家企业的规则完全独立、互不干扰。 多租户系统的现实痛点 在企业级应用开发中,我们经常面临这样的场景: 场景一:电商平台SaaS化 "老板,我们要把电商系统做成SaaS产品,服务1000家商户,每家商户的促销规则都不一样,怎么设计?" 场景二:风控系统多租户 "不同银行的风控策略差异很大,但底层逻辑相似,能不能用一套系统?" 场景三:业务规则定制化 "每个客户都要定制自己的业务规则,难道要为每个客户部署一套系统?" 这些问题的核心痛点是:如何在一套系统中实现数据和逻辑的完全隔离。 解决方案:多租户规则隔离架构 有没有一种方式,让一套规则引擎能够: ✅ 服务上千家企业 ✅ 每家企业规则完全独立 ✅ 规则互不干扰 ✅ 性能不受影响 答案是:多租户规则隔离架构! 核心实现思路 1. 架构设计总览 ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 企业A客户端 │ │ 企业B客户端 │ │ 企业N客户端 │ ....

SpringBoot + 规则热更新 + Nacos配置监听:业务策略修改无需重启,秒级生效

SpringBoot + 规则热更新 + Nacos配置监听:业务策略修改无需重启,秒级生效

大家好,今天咱们聊聊一个在业务快速迭代中非常关键的话题:如何实现业务规则的热更新。 业务规则管理的痛点 在传统的业务系统开发中,我们经常遇到这样的困扰: 场景一:紧急促销活动 "老板,双11活动马上开始了,但是折扣规则需要调整,能不能现在就改?" "这个...需要改代码,然后测试,再部署上线,最快也要1个小时..." 场景二:风控策略调整 "发现有个新的风险点,需要立即更新风控规则!" "规则写在代码里,要重启服务才能生效..." 场景三:个性化配置 "不同用户群体需要不同的优惠策略,每次调整都要发版?" 这些问题的核心痛点是:业务规则与代码耦合太紧,变更成本高,响应速度慢。 解决方案:规则热更新 有没有一种方式,让业务规则像配置一样可以动态调整,修改后立即生效,而无需重启应用? 答案是:规则热更新 + Nacos配置监听! 核心实现思路 1. 架构设计 我们的解决方案采用以下架构: ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ 业务应用 │ │ Nacos配置中心 │ │ 规则管理平台 │ │ ....

SpringBoot + 规则执行日志 + 调试回放:线上规则为何不生效?一键复现执行过程

SpringBoot + 规则执行日志 + 调试回放:线上规则为何不生效?一键复现执行过程

引言 在复杂的业务系统中,规则引擎已经成为处理业务逻辑的重要工具。但你是否遇到过这样的困扰:线上规则突然不生效了,排查起来却无从下手?规则执行结果不符合预期,但又不知道问题出在哪里? 今天我们就来聊聊如何通过规则执行日志追踪和调试回放技术,让规则执行过程变得透明可控,真正做到"一键复现"线上问题。 问题背景 在实际开发中,规则引擎的使用场景越来越广泛: 电商系统的促销规则 金融风控的评估规则 用户权限的控制规则 订单处理的业务规则 但随之而来的挑战是: 黑盒问题:规则执行过程不透明,难以追踪 调试困难:线上问题无法重现,只能靠猜 性能监控:规则执行耗时无法统计 版本管理:规则变更历史无法追溯 核心解决方案 我们采用的技术栈: SpringBoot 2.7 + Easy Rules 作为规则引擎基础 Redis 作为执行轨迹存储 自定义监听器 捕获执行过程 traceId机制 实现执行链路追踪 1. 规则执行日志记录 核心思路是通过监听器机制,捕获规则执行的每个关键环节: // 规则执行监听器 public class ExecutionLoggingRuleListener....

SpringBoot规则编排可视化:非技术人员也能配置复杂业务逻辑

SpringBoot规则编排可视化:非技术人员也能配置复杂业务逻辑

引言:为什么业务逻辑配置需要可视化? 在日常开发中,我们经常遇到这样的场景: 电商促销活动:满减、折扣、优惠券、会员等级、时间段、商品分类等各种规则组合在一起,每次产品经理提新促销规则,开发人员就要改代码、测试、上线,整个流程下来可能需要好几天。 审批流程:部门经理审批 → 财务审批 → 总经理审批,看似简单,但不同金额、不同类型的申请可能需要不同的审批路径。 数据处理:数据验证 → 数据转换 → 数据存储,每个环节都可能有不同的处理逻辑。 传统的硬编码方式在这些场景下显得力不从心: 代码复杂度高:if-else嵌套越来越深 维护成本大:规则变更需要重新发布代码 业务响应慢:新规则上线周期长 沟通成本高:业务人员无法直接参与规则配置 这时候,规则编排可视化就派上用场了!今天我们就来聊聊如何用SpringBoot打造一个让非技术人员也能配置复杂业务逻辑的可视化平台。 核心设计理念 1. 流程即代码,代码即流程 我们的核心思想是:把业务逻辑抽象成可视化的流程图,让业务人员通过拖拽节点的方式来配置规则。 传统方式:代码编写 → 编译测试 → 部署上线 可视化方式:拖拽配置 → 实时生效 ....

SpringBoot自适应限流:CPU高时自动降级非核心接口,保主链路

SpringBoot自适应限流:CPU高时自动降级非核心接口,保主链路

引言 在高并发的互联网应用中,系统保护是一个永恒的话题。传统的限流策略往往是静态的,一旦设定就很难根据系统实时状况进行调整。但现实中,系统负载是动态变化的,我们需要一种更智能的限流方案。 今天,我要分享一套SpringBoot自适应限流与系统负载联动的完整解决方案,当CPU使用率升高时,系统会自动降低非核心接口的流量限制,确保核心接口的可用性,真正实现"保主链路"的目标。 问题背景 传统限流的痛点 想象这样一个电商系统: 用户访问商品详情页(核心接口) 同时也在浏览推荐商品(非核心接口) 突然出现流量高峰,CPU使用率飙升至90%以上 所有接口都按同样的限流规则处理 结果:核心业务受到影响,用户体验下降 业务场景分析 在实际业务中,接口通常有不同的重要性: 核心接口:订单查询、支付接口、用户登录等 非核心接口:推荐服务、统计接口、日志上报等 当系统压力过大时,我们应该优先保障核心接口的可用性,而非核心接口可以适当降级。 解决方案设计 核心架构思路 我设计了一套三层防护体系: ┌─────────────────┐ ┌─────────────────┐ ┌───────────....

SpringBoot + 自定义 Health Indicator:数据库、缓存、第三方服务健康状态一目了然

SpringBoot + 自定义 Health Indicator:数据库、缓存、第三方服务健康状态一目了然

今天咱们来聊聊一个让运维小哥睡不好觉的问题——系统各个组件的健康状态如何实时监控?别等数据库挂了、缓存雪崩了、第三方API超时了才后知后觉,通过SpringBoot Actuator自定义Health Indicator,我们可以实现所有服务状态的一目了然! 痛点分析:为什么需要自定义健康检查? 相信每个踩过坑的后端都遇到过这些场景: 场景一:数据库连接池耗尽 用户反馈系统响应慢如蜗牛 查看日志发现大量数据库连接超时 运维紧急扩容,业务已经受损 场景二:Redis缓存雪崩 突然大量请求打到数据库 CPU使用率飙升到90%+ 系统濒临崩溃边缘 场景三:第三方服务不稳定 支付接口偶尔超时 短信服务时好时坏 用户体验直线下降 这些问题的根本原因是什么?就是我们缺乏对系统各组件健康状态的实时监控! 解决方案:三位一体的健康监控神器 我们的解决方案采用"数据库+缓存+第三方服务"的三位一体监控策略: 1. 数据库健康检查 实时监控数据库连接状态和查询性能,第一时间发现连接池问题。 2. Redis缓存监控 检查缓存连接状态和操作性能,预防缓存雪崩和击穿。 3. 第三方服务监控 监控外....

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