- 博客(42)
- 收藏
- 关注
原创 Spring 三级缓存解决循环依赖:getBean(“a“) 完整调用流程图解
此时缓存状态:一级: {},二级: {},三级: {a: factory, b: factory}此时缓存状态:一级: {},二级: {a: earlyA},三级: {b: factory}至此,A 与 B 的循环依赖通过三级缓存成功解决,两个 Bean 均完成创建并放入一级缓存。此时缓存状态:一级: {b: B成品},二级: {a: earlyA},三级: {}此时缓存状态:一级: {},二级: {},三级: {a: factory}一级: {a: A成品, b: B成品},二级: {},三级: {}
2026-08-31 22:45:06
330
1
原创 Redis 与 MySQL 数据一致性:从原理到架构实战
如果写操作是"更新缓存",在并发场景下,可能出现:线程 A 更新 DB 为 100 → 线程 B 更新 DB 为 200 → 线程 B 更新缓存为 200 → 线程 A 更新缓存为 100。最终缓存值 100 与 DB 值 200 不一致。而"删除缓存"后,下次读请求会重新从 DB 加载最新值,天然避免了上述并发写入导致的脏数据问题。
2026-08-29 10:39:49
380
原创 线程池异常方案
线程池异常处理不能靠开发自觉,必须做框架级兜底。核心是重写线程池的 afterExecute 钩子方法,统一捕获所有未处理异常,打日志、上报告警,同时区分 execute 和 submit 两种提交方式的异常差异,避免 submit 的 Future 异常静默丢失。再配合统一提交工具类和代码规范,从机制上杜绝开发漏写异常处理导致的静默故障。线程池的拒绝策略有哪些?如何监控线程池的运行状态?线程池的核心参数有哪些?
2026-08-26 00:21:01
130
原创 生产环境线程池落地全方案
Slf4j@Override// 1. 监控告警:上报拒绝次数、队列积压、活跃线程数log.error("线程池任务拒绝,活跃线程:{},队列积压:{},总任务数:{}",// 2. 降级持久化:任务落库,后续补偿任务重试} else {// 兜底:主线程同步执行if (!r.run();生产落地线程池,首先按业务做隔离,核心与非核心、快任务与慢任务分池部署;队列默认用指定容量的 LinkedBlockingQueue,容量按业务可容忍等待时长计算,绝对禁用无界队列;
2026-08-26 00:17:29
66
原创 公共包远程调用:完整自定义异常体系与使用示例
**远程调用顶层父异常*//** 下游原始响应体,出现异常时尽量带回,方便排查,可能为null */@Bulkhead @CircuitBreaker @Retry 只加在纯 http 调用方法;本地业务逻辑一定放在上层业务,不要进被注解的方法;下游业务成功:返回 RiskRespDTO,业务 code 放在 DTO;网络、限流、熔断、解析错误:抛出异常,不返回业务码 DTO。
2026-08-24 22:49:32
187
原创 Java 服务调用下游接口注意点
异步任务会耗尽业务线程池。调用下游接口,首先必须设置连接超时、读取超时,防止下游响应慢把我方线程无限阻塞,耗尽线程池或者 Tomcat 线程,造成服务雪崩。不设置超时,线程会无限阻塞等待下游返回,线程池线程被占住不释放,最终线程池打满、队列积压,整个服务雪崩。:调用下游的请求单独隔离线程池,下游慢,只占隔离池,不会占用业务核心线程池,不会影响别的业务。:下游大量失败,打开熔断,直接本地快速失败,不去调用下游,保护自己,也保护下游。:如果不做舱壁,下游全部卡死,自己业务线程池全部占满,其他无关接口全部挂掉。
2026-08-24 22:43:33
162
原创 Spring @Async 坑点 + 改造方案
项目中使用 @Async,首先要规避默认 SimpleAsyncTaskExecutor 的坑,这个类不会复用线程,高并发会不断新建线程。我们会实现 AsyncConfigurer 把默认执行器替换为我们自定义的 ThreadPoolExecutor。针对 void 返回的异步方法,配置 AsyncUncaughtExceptionHandler 做异常兜底;同时线程池重写 afterExecute,处理返回 Future 场景的异常。
2026-08-24 21:48:41
385
原创 Java 线程池:复用、Spring 管理、监控与线上故障排查全指南
为了业务隔离,我们会创建多个独立线程池实例,避免一个业务耗尽全部线程。但是我们不会每个线程池重复拷贝 ThreadFactory、afterExecute 的代码。我们把线程工厂封装成通用类,每个线程池实例化它,传入不同线程名称前缀;把 afterExecute 里面 Future 解析、异常日志告警抽成公共工具方法;多个线程池复用同一套底层逻辑,保证所有线程池行为统一,便于维护,避免复制代码带来 bug。补充区分(很容易混淆):不是多个线程池共用同一个 ThreadFactory 对象。
2026-08-24 21:41:04
377
原创 Spring Boot 3.x 异步线程丢失 TraceId 的解决方案与最佳实践
Spring 体系内:无脑使用。JDK 原生线程池:优先使用包装器,或者手动使用。虚拟线程:必须封装自定义执行器,显式传递MDC和。
2026-08-23 00:41:47
386
原创 企业级接口设计六大核心规范:从架构到实战的完整指南
本文从资深架构师视角,系统阐述了企业级接口设计的六大核心规范。首先强调接口作为业务契约的本质,提出单一职责、开闭原则等设计准则;其次详解RESTful规范与命名标准;第三部分规范参数校验与响应封装;第四构建全局异常体系;第五重点说明安全防护机制;最后提出性能优化与高可用方案。全文贯穿阿里、腾讯等大厂实战经验,强调接口设计是贯穿需求、架构、运维全流程的系统工程,需建立标准化的数据交互层、健壮的容错机制和完善的安全防线,最终实现高可用、易维护的企业级接口体系。
2026-08-23 00:25:11
307
原创 Java CompletableFuture 异步编程实战:从入门到架构师避坑指南
是 Java 8 引入的一个极其强大的异步编程工具。如果说我们上一轮聊的 Spring 事件广播(@Async)是“发个通知让别人去干活”,那么就是“它实现了Future和接口,彻底解决了传统Future只能阻塞等待(get())、无法链式处理、异常处理繁琐等痛点。
2026-08-22 23:44:16
211
原创 CompletableFuture 生产环境踩坑详解与解决方案
在生产环境中使用 CompletableFuture 确实极易踩坑,如果配置或使用不当,很容易引发严重的线上故障。结合异常丢失、线程池混用和并行度不合理等问题,以下是具体的踩坑详解及生产级解决方案。
2026-08-22 23:38:34
313
原创 企业级 JPA 与数据库架构落地指南
🔹 主键策略与批量优化Oracle Sequence 配置与 JPA 批处理参数对齐SEQUENCE 策略在 Oracle 环境下的最佳实践allocationSize 与 batch_size 的协同配置🔹 内存管理与性能保障JPA 一级缓存机制与脏检查原理批量插入中的 OOM 风险与 flush/clear 分批机制内存占用双倍原理及解决方案🔹 核心组件深度解析EntityManager 生命周期管理方法详解实体四种状态转换路径一级缓存与二级缓存的适用场景对比。
2026-08-21 23:52:58
327
原创 HTTPS 为什么“非用不可”?从核心优势到工作原理的全面解析
防伪装(身份验证):通过 CA 证书和非对称加密(公钥/私钥)验证了服务器的真实身份。防窃听(数据保密性):通过握手生成的“对称会话密钥”,对业务数据进行了高强度的加密。防篡改(数据完整性):通过 MAC 消息认证码,确保了数据在传输过程中没有被中间人修改。这就是 HTTPS 的完整工作原理。它巧妙地结合了“非对称加密”(用于安全地交换密钥)和“对称加密”(用于高效地传输数据),在保证极高安全性的同时,兼顾了网络传输的性能。
2026-08-20 23:43:38
551
原创 企业级幂等方案
在分布式系统中,由于网络不可靠,超时重试、消息重投、网关重试是常态。接口幂等性(Idempotency)是指同一个操作无论执行一次还是多次,最终产生的业务结果与执行一次完全一致,不会产生副作用(如重复扣款、重复创建数据等)。
2026-08-20 23:04:45
382
原创 ContentCachingRequestWrapper 实战:解决请求体“只能读一次”的官方方案
只要你使用了 Spring Boot(引入了 spring-boot-starter-web),这个类就已经在你的项目依赖中了,不需要额外引入任何第三方包,直接 import 即可使用。总结:它是 Spring 官方为了解决“请求体流只能读一次”的底层缺陷而提供的官方解决方案,非常适合用来做全局的请求/响应日志记录。它在把数据传递给 Spring MVC 的同时,同步地把读到的字节拷贝一份,存到自己的内部缓存数组中。虽然它很好用,但在生产环境中使用它有一个极其容易踩的坑:它只缓存“已经被读取过”的内容。
2026-08-18 22:32:31
166
原创 Jackson 生产级配置与避坑终极指南
框架会先准备好一个 Builder,然后遍历所有开发者提供的 Customizer,把 Builder 传进去让大家“动刀”,最后再构建出最终的 ObjectMapper。:确保所有的 Java Bean 提供默认无参构造函数和标准的 getter/setter,且字段严格使用标准小驼峰命名(camelCase),避免 Lombok 生成非标准 getter 导致 Jackson 找不到属性。,Jackson 无法知道集合内部的具体元素类型,会默认使用 LinkedHashMap 兜底,导致强转时抛出。
2026-08-16 20:08:10
326
原创 深入理解Java线程中断:从核心机制到线程池实战避坑指南
Java线程中断机制核心要点 协作式中断:interrupt()仅设置标记,需线程主动检查或触发InterruptedException 关键处理原则:捕获InterruptedException后必须调用Thread.currentThread().interrupt()恢复中断状态,否则信号丢失 典型问题:不恢复中断会导致线程池关闭卡死、资源泄漏等严重后果 最佳实践: 线程池任务中必须恢复中断状态 立即终止线程时可省略(但仍不推荐) 始终通过isInterrupted()检查中断状态协调逻辑 (字数:1
2026-05-29 15:45:47
378
原创 @Transactional 最佳实践
本文深入剖析了Spring中@Transactional注解的本质与潜在问题,指出其核心在于控制数据库连接的占用时长而非仅保证原子性。文章通过真实案例展示了事务中混入外部IO操作(如慢API调用)如何导致连接池被长期占用,进而引发服务雪崩,并提供了四种解决方案:1)分离外部调用与事务操作(推荐);2)事务提交后执行外部调用;3)异步化处理;4)超时等兜底措施。最后强调@Transactional方法应严格限定为数据库操作,任何非DB操作都可能成为生产事故隐患,同时提供了问题排查方法和架构优化建议。
2026-05-29 15:44:06
201
原创 线程池的最佳实践
根据使用场景,线程池分为两类:一类是给@Async/异步请求用的全局通用线程池,另一类是自定义业务用的专用线程池。如果不需要用@Async,只是手动提交异步任务,直接定义// 配置和上面一样,根据业务场景调整参数// ... 省略配置。
2026-05-28 14:33:40
380
原创 SpringBoot Configuration Annotation Processor not configured 解决方案和详细问题分析以及作用
写在前:笔者出现这个问题的时候,大概猜到是什么问题,在网上也是很快找到了解决方案,但是很多帖子,并没有深究,只是单纯的解决了问题。
2024-05-30 18:03:06
6602
原创 Maven的下载安装(2024最新详细版~)
Maven – Download Apache Maven 4.3 验证配置Noted: 很多人会忘记配置新项目,导致一打开新项目maven还是旧的配置而出现问题 new Project Settings->Settings for New Projects
2024-05-30 17:13:14
1105
原创 接口优化的常见解决方式
1)定位问题 traceId分析调用链路的各阶段的用时,找到耗时长的地方。通过explain执行计划分析,可能存在以下问题;
2022-12-19 18:38:01
1478
原创 MySQL之二
DML语句、可回滚、可以是删除某一行或者是多行DDL语句、不可回滚、清空表中的数据DDL语句、不可回滚、删除表、索引、权限等等都会删除。
2022-08-22 22:16:05
306
原创 基于Redis实现分布式锁
各种分布式锁实现对比基于redis实现分布式锁需要实现两个功能1、获取锁 需要有互斥性 setnx lock thread12、释放锁setnx 和expire是两条命令,不具备原子性,因此需要一条命令去实现这两条命令的功能:s线程1获取锁后由于业务阻塞,导致锁被超时释放,线程2获取锁执行业务,此时线程1业务执行完毕,去释放锁,但这锁是线程2的。解决:在释放前先判断是否是自己的锁,因此存储的value是线程id。
2022-08-20 22:45:14
410
原创 Redis 之二
是一个c语言写的非关系型数据库,基于内存操作,所以读写性能非常好,一般做缓存。也有做分布式锁,甚至消息队列,支持事务、持久化、Lua脚本 、集群等。
2022-08-20 16:35:45
474
原创 接口幂等性的实现
1、select语句天生幂等2、update语句,需要做幂等处理3、delete语句,如果是精确删除,如id =1,不需要处理。如果是id>1,则需要4、insert语句,如果是插入自增的id,比如增加数据,需要处理。如果是,手动填充id,传进实体,则不需要,因为数据库主键有唯一性约束,会报异常。
2022-08-19 22:59:30
477
原创 JVM虚拟机
如:我们写的程序一般是通过程序加载器去加载的,而程序加载器不会先去加载,而去找他的上一级扩展类加载器加载,扩展类加载器也不会加载,而找到最顶层的根加载器。加载后的class文件会存放在缓存区,jvm每次读的时候会优先读取缓存区的数据,而变更后的文件要想见效,必须重新加载进缓存区。线程私有的,不存在GC,包含局部变量表、操作数栈、方法出口、动态链接,每执行一个方法会压入一个栈帧,方法执行完会弹栈。加载------》链接(验证、准备、解析)-----》初始化,将编译后的.class文件加载到JVM系统。...
2022-08-15 23:51:57
243
原创 Spring事务
Spring事务分编程式事务(setAutoCommit(false)-->commit/rollback)和注解式事务(启动类加@EnableTransactionManagement--->方法/接口加@Transactionl)@Transactional注解:1、未交给Spring管理2、方法不是public修饰3、A调B方法,而只在B方法加了@Transactional,因为事务的底层是AOP,扫描到注解,才会启动动态代理做切面4、try catch捕捉了异常/吞并异常,但未抛出。........
2022-08-10 21:35:25
513
原创 Seata的四种模式介绍
就是指不是单个服务或者单个数据库架构下产生的事务,例如: Seata有四种模式: XA、AT(默认)、TCC、SeagaXA:强一致性,基于数据库隔离,无代码侵入,在一阶段不提交事务AT:默认模式,基于全局锁隔离,无代码侵入,一阶段提交事务,在提交事务前,会记录undolog日志,性能比XA模式好,二阶段TC通知回滚,则根据undolog回滚,通知提交,则删除undolog日志。TCC:性能最好,不需要依赖关系型数据库,但代码入侵读高。Try:冻结可用数据,Confirm:确认提交数据,删除冻结数据 Ca
2022-08-10 20:49:43
11096
2
原创 MQ面试题整理
我们可以开启手动ACK模式,然后在消费者的业务执行成功后,才使用代码发送ACK确认,以实现消息可靠。默认情况下,MQ服务器的消息到达消费者后,消息者会立即发送ACK确认消息给MQ服务器,MQ服务器获取ACK后,从队列中删除消息。判断ack是否成功,如果ack为false,代表消息发送失败,可以重发几次消息,如果重试失败,在DB的消息表写入错误消息。如果执行自动ACK确认机制的话,MQ服务器可能会在消息者接受到消息但未执行成功业务的时候,主动删除MQ消息,导致消息的丢失。1、MQ如何保证消息可靠?...
2022-08-10 17:24:27
3880
原创 MySQL
MySQL在5.5之前默认用的是myISAM ,5.5以后用的是InnoDBMyISM: 不支持外键、事务、行锁,只支持表锁。文件:xxx.fri表结构 xxx.MYI 表索引 xxx.MYD表数据InnoDB: 支持外键、事务、行锁、表锁,使用的是b+树索引 文件:xxx.ibd 每张表都对应一个表空间,存储数组、索引、表结构。Memory: 默认使用Hash索引,引擎的数据存储在内存中,读写快,但是会受到硬件、断电影响,因此只能将这些表做缓存或临时用。............
2022-08-07 00:34:25
284
原创 Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module “com.fasterxml.
Java 8 date/time type `java.time.LocalDateTime` not supported by default: add Module "com.fasterxml.
2022-07-24 16:37:28
4761
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅