- 博客(79)
- 收藏
- 关注
原创 三个Handler一个任务-Netty事件传播的任务边界设计
Netty 通过 AbstractChannelHandlerContext 中的单次 if 判断,实现同线程下 handler 串行直调、跨线程才入队的任务边界机制。三个绑定同组的 handler 共享同一任务队列与线程,事件传播仅入队一次,全程在同调用栈执行,既避免频繁线程切换,又保证顺序性。其核心设计——“任务边界 = 线程切换点”——依托于每执行器独享队列与轮询分配结构,实现高性能与有序性统一,类似 Go 调度器、LMAX Disruptor 的思想,是异步通信中精妙的原语抽象。
2026-11-07 10:21:35
135
原创 Netty-Kafka-Redis保序问题源码对比与NIO框架主流解法
本文剖析NIO框架中“同一连接事件保序”难题,基于Netty、Kafka、Redis源码,对比五种解法:Netty通过线程绑定实现物理串行;Kafka broker利用请求编号与会话状态保证顺序;Kafka producer依赖序列号重试机制;Redis服务端采用单线程处理;客户端则通过排队或失败重试规避乱序。归纳出五类主流思路:线程绑定、请求编号、会话管理、单线程执行、任务队列排队。强调协议设计与线程模型协同的重要性,揭示“不用加锁”的前提依赖于架构选择,为高性能系统设计提供决策依据。
2026-11-04 07:58:15
322
原创 SpringAOP两套代理创建路线设计哲学与开源实践
Spring AOP 通过 AbstractAutoProxyCreator(代理拥有者)与 AbstractAdvisingBeanPostProcessor(增强贡献者)实现职责分离:前者统揽代理创建、记账防重,支持循环依赖兜底;后者仅在已有代理上叠加 advisor,不参与早期暴露。@Async 在循环依赖中静默失效,根源在于其不持有代理、无法利用 earlyProxyReferences 防重机制。尽管可设想为 AsyncAnnotationBeanPostProcessor 添加 getEarly
2026-10-05 10:59:33
437
原创 Seata全局锁泄漏:从上游PR-backport到生产零事故发布实战
本文记录了在 Seata 2.4.0 单副本 file 模式下,通过语义级 backport 上游修复(PR #8201)解决“已提交事务锁不释放”问题的全流程。借助 ChatGPT 分析日志,精准定位并发竞态根因;绕过 Docker 环境,使用 jib 构建并推送私有镜像;历经三连坑(jib、console 401、滚动发布)后成功发布,意外清理 3595 把陈年锁,顺带治愈另一类锁残留问题,实现零事故上线。
2026-09-18 11:16:24
101
原创 微服务本地开发零配置隔离方案演进V4
本文通过改造负载均衡器,将路由决策权从“服务集群”上移至“请求头”,引入cluster-name请求头优先级高于服务自身集群,实现本地联调仅需启动目标服务。结合白名单透传与零侵入接入方案,支持浏览器、Postman及前端拦截器三类场景,彻底解决链式拖累问题,从“起一串”变为“起一个”,显著提升开发效率与本地调试体验。
2026-09-17 18:59:18
358
原创 一次SNAPSHOT依赖污染引发Redis共享缓存投毒的生产事故复盘
一次因本地 mvn deploy 误操作导致的 SNAPSHOT 依赖污染,引发共享用户缓存“投毒”事故。由于各微服务回写缓存时使用自身 fat jar 中的旧版 User 类,导致反序列化失败,缓存数据被污染。清缓存仅暂时缓解,一旦新版服务再次回填,问题复发。通过日志排查与排除法锁定“不报错但发版”的服务为真凶,最终确认根因:依赖版本管理缺陷与读穿回填机制的隐患叠加。教训深刻:不可靠的快照依赖、严格反序列化模式及吞异常不清理缓存,共同酿成生产事故。
2026-09-16 15:58:16
222
原创 SpringAOP拦截器链缓存与动态性源码实战
本文深入剖析 Spring AOP 拦截器链的缓存与动态性机制:缓存失效由 adviceChanged() 统一触发,6 处调用点覆盖所有 advisor 变更操作,全量清空 methodCache;target 无需重建 proxy,因 proxy 仅持有 TargetSource 策略,每次调用时动态获取 target;proceed() 的“恰好一次”约束源于克隆语义而非计数器——每次调用生成新 MethodInvocation 实例,递归模型自然避免重复执行。三者共同揭示 Spring AOP 在静
2026-09-14 08:35:17
220
原创 SpringAOP拦截器链递归与事务钩子补偿源码实战
链上根本没有驱动者——框架只造了一个带着游标的调用对象,每 个拦截器自己决定要不要、以及何时调用 proceed,链是递归坍缩出来的,不是循环推着走的。顺带还清了第三篇两笔小债:`ExposeInvocationInterceptor` 补进链里干什么用,以及 `processCommit` 异常路径上那个 `beforeCompletionInvoked` 标记的补偿逻辑。
2026-09-13 17:42:21
147
原创 SpringAOP自动代理与事务同步回调源码实战
Spring AOP自动代理由AbstractAutoProxyCreator在每个Bean初始化后通过postProcessAfterInitialization触发,经四步匹配(捞advisor、切点匹配、补默认、排序)确定是否织入代理,选型依据为是否有接口决定JDK或CGLIB。事务提交后执行操作依赖TransactionSynchronization在processCommit前后插入四个钩子位,确保消息/缓存刷新在真正提交后执行,避免“脏发”。@TransactionalEventListener
2026-09-13 16:49:43
182
原创 Spring事务传播行为分派与挂起恢复源码实战
本文深入剖析Spring事务传播行为的源码实现,揭示七种传播行为本质为一个两层if-else瀑布流。核心结论:“挂起”即从ThreadLocal摘下连接并封装至SuspendedResourcesHolder;“恢复”则是将其重新绑定回线程上下文。REQUIRES_NEW与NESTED分家于开事务时刻——前者换连接新建,后者在原连接上创建保存点。所有逻辑均聚焦于getTransaction与handleExistingTransaction的分支判断,精确定位UnexpectedRollbackExcept
2026-09-13 13:35:54
136
原创 读透Spring声明式事务与Druid、HikariCP介入点
本文深入剖析Spring声明式事务源码,揭示@Transactional背后的真实运行机制。从TransactionInterceptor#invoke切入,梳理事务开启、执行、提交/回滚的完整链路,明确拦截器仅负责编排,事务管理由PlatformTransactionManager实现。重点解析两大常见误区:受检异常默认不回滚(因rollbackOn仅对RuntimeException和Error生效),以及内层事务异常被外层捕获后,因rollback-only标记导致commit时抛出Unexpecte
2026-09-13 13:01:08
181
原创 微服务本地开发零配置隔离方案演进Stage3
前两阶段的故事:V1 用 EPP + 条件注解实现"零配置本地隔离",V2 把注解推翻、换成 BeanDefinition 阶段自动识别消费者。方案在业务服务上已经闭环,但联调链路始终缺一环——网关。前后端联调只能把代码部署到云端 test 环境主干,所有人的半成品挤在一条链路上互相影响,开发速度和体验双输。这次把网关也拉进隔离体系:前端请求打到本地网关,网关按个人集群优先路由本地后端,整条联调链路不出本地,提测时再发布上云——而个人集群顺带长成了事实上的开发泳道。还处理了一个隐蔽工程问题:同一个 EPP,
2026-09-04 10:26:25
351
原创 微服务本地开发零配置隔离方案演进Stage2
上一阶段我们用"组合条件注解 + EPP 注入开关"实现了本地启动隔离:本地不消费环境消息、不接主干流量,一行配置不用写。但这个方案有个天花板——**每个消费者类都得记得加注解**,忘了加就是静默漏隔离。这次把注解方案整个推翻:排除器在 BeanDefinition 注册阶段自动识别"谁是 MQ 消费者"并移除,开发者零感知。识别算法踩过的坑不少:23 个类里有 2 个的消费者实例藏在 `@PostConstruct` 的局部变量里,字段扫描根本摸不到;而"只 import 不使用"又不能误判。本文记录完整
2026-08-27 14:11:12
376
原创 OpenFeign与线程池全链路ThreadLocal传递治理实战
这是一套典型的 Spring Cloud 微服务栈:Spring Cloud Gateway 做统一入口,服务间调用走 OpenFeign,认证上下文全程依赖 ThreadLocal。这条"网关 → Servlet 微服务 → OpenFeign → 下游服务"的传递链路,在同步调用下天然闭环;但异步任务里发起的 Feign 调用偶发 401,异步日志的 traceId 断链,甚至偶现 A 用户的任务读到 B 用户的部门数据。根因只有一个:**线程池是这条精心设计的传递链路上唯一的断层**。本文记录从 Ga
2026-08-26 18:14:49
465
原创 微服务本地开发零配置隔离方案演进Stage1
团队 40+ 人共用一套测试环境,谁本地起个服务,测试环境的流量就可能路由到他电脑上,环境消息还可能被他本地抢走消费。本文记录我们如何用"一行配置都不用写"的方式根治这个问题,以及中间踩过的 Spring Cloud 双上下文的坑。
2026-08-26 15:14:10
401
原创 ShardingSphere双层Druid僵尸连接故障复盘
本文分析了生产环境中因数据库规格调整和慢查询触发的持续性数据库连接失效问题。故障表现为connection disabled异常,根源在于双层连接池(Druid+ShardingSphere)架构下的连接管理缺陷。当MySQL物理连接断开或超时后,内层Druid将连接标记为disabled,但ShardingSphere仍缓存该连接对象,导致坏连接被反复使用。排查发现外层Druid无法有效检测内层连接状态,且配置的testOnBorrow等参数在此架构下失效。最终通过版本确认(ShardingSphere
2026-07-23 10:31:03
477
原创 泛型新认知
本文通过protostuff框架实现protobuf序列化/反序列化的案例,探讨了Java泛型的运行期擦除特性。作者首先展示了针对不同PO类的独立序列化实现,进而尝试编写通用泛型序列化工具类,但在反序列化时发现无法获取运行时泛型类型信息。通过测试验证了Java泛型仅在编译期有效,运行期无法获取具体类型参数,导致空指针异常。文章揭示了Java泛型"伪泛型"的本质,即类型信息在运行期被擦除的特性,为解决该问题提供了实践案例。
2026-01-06 14:49:24
956
原创 Kafka服务端处理producer请求原理解析
本文深入解析了Kafka服务端处理Producer请求的核心流程。首先通过RequestHandlerPool接收请求,经KafkaApis路由到ProduceRequest处理逻辑。随后ReplicaManager将数据写入本地日志,经过Partition校验后调用LogSegment执行文件写入操作。关键点包括:数据分片处理、日志分段策略(基于大小/时间)、索引文件维护等。整个流程展现了Kafka高效处理写入请求的分层设计,从请求接收、权限校验到最终数据持久化,各组件职责明确,共同保障了高吞吐的消息写入
2025-10-19 18:50:53
962
原创 Safepoint的秘密探寻
这是一篇关于Java虚拟机(JVM)安全点(safepoint)的技术文章摘要: 文章主要介绍了JVM中安全点的概念、作用机制和相关源码分析。安全点是JVM中一个重要的同步机制,主要用于垃圾回收、JIT逆优化等场景。当需要执行GC等操作时,VM线程会通知所有Java线程到达安全点,通过轮询机制检查是否需要暂停。Java线程在不同状态(解释执行、本地代码、编译代码等)下有不同的安全点处理方式。文章还分析了安全点的执行流程、触发场景以及源码实现,包括VMThread、SafepointSynchronize等关
2025-10-02 08:44:15
727
原创 Spring实现proxy的流程
Spring代理机制解析 本文深入分析了Spring框架中的代理实现机制,主要包括: 代理实现方式:Spring通过BeanPostProcessor在bean生命周期最后阶段或循环依赖时提前创建代理对象,对原始bean方法进行增强。 代理流程: 正常流程:通过postProcessAfterInitialization创建代理 循环依赖:通过getEarlyBeanReference提前创建代理 两种方式最终都调用wrapIfNecessary确保代理逻辑一致 注解差异: @Transactional可以
2025-09-20 13:02:43
651
原创 再探volatile原理
volatile关键字与JIT编译优化探究 摘要 本文通过实验探究了volatile关键字在Java中的作用机制,发现JIT编译器C2阶段的优化可能导致无volatile修饰的变量出现死循环问题。实验表明: 无volatile时,C2编译器会优化循环逻辑,直接跳转形成死循环 添加volatile后,编译代码保持对变量的每次读取检查 通过JITWatch工具可观察汇编代码变化,验证了volatile防止编译器优化的效果 该现象揭示了JIT优化与内存可见性间的微妙关系,说明volatile不仅解决CPU缓存一致
2025-09-10 14:27:14
921
原创 kafka服务端架构总览
本文分析了Kafka服务端的架构设计,重点阐述了其计算与IO分离的核心思想。文章指出Kafka通过RequestChannel和Processor的responseQueue实现IO层与计算层的解耦,类似于Producer端通过batches解耦accumulator和Sender线程。服务端架构包含网络IO处理请求/响应(详见系列前两篇)和线程池处理业务逻辑两部分,这种分离设计提升了系统性能和可维护性。文章最后预告将深入探讨Kafka计算逻辑的具体实现。
2025-08-31 10:08:34
1165
原创 Kafka服务端NIO操作原理解析(二)
本文是Kafka系列文章的第三篇,主要解析Kafka服务端的NIO操作原理。文章首先展示了Kafka服务端IO类关系图,说明Acceptor和Processor都是线程,服务端启动后会以"一个Acceptor+多个Processor"模式运行。随后重点分析了Acceptor和Processor的核心流程:Acceptor通过selector监听accept事件,采用轮询方式将新连接分配给Processor;Processor则负责处理多个socketChannel,维护连接状态和数据读写
2025-08-09 15:57:47
1013
原创 Kafka服务端NIO操作原理解析(一)
Kafka服务端NIO操作解析:Kafka利用Java NIO实现高性能网络通信,核心是通过Selector监听多个Channel事件(连接、读写)。服务端流程包括:创建ServerSocketChannel并绑定端口,设置为非阻塞模式,注册到Selector监听ACCEPT事件;当客户端连接时,创建SocketChannel并注册READ事件;通过ByteBuffer处理数据读写。相比BIO,NIO能单线程处理大量连接,显著提升吞吐量。Kafka在此基础上实现了更高效的自定义网络层,但基本原理与此类似。本
2025-08-05 07:52:42
1060
原创 利用springEvent,进行服务内部领域事件处理
本文介绍了Spring Event在B端系统开发中的最佳实践方案。作者提出通过封装领域事件(DomainEvent)实现业务解耦,并针对事务和性能问题给出解决方案。关键点包括:1)利用事务钩子函数确保事务提交后才发布事件;2)使用@Async异步处理事件并配合TTL线程池解决日志追踪问题;3)建议根据业务需求选择最终一致性方案。该方案适用于流量不大的B端系统,在保证事务的同时兼顾性能,为开发人员提供了一种轻量级的解耦实现方式。
2025-07-01 21:33:55
942
原创 基于Kafka2.1解读Consumer原理
Producer的逻辑是把消息往外发,所以Sender运行的越快,client这边为了维护batch而消耗的资源(内存和CPU越少);而如果Consumer也这么干,实际消费速度赶不上fetch速度的话,会需要额外的内存和CPU资源来维持更多的completedFetchs,更别说如果发生了rebalance的话,fetch过来的completedFetchs可能都是白fetch了。从Fetcher的数据结构里其实就可以猜到它的作用:缓存已Fetch到的records、去fetch更多的records。
2024-11-17 10:43:54
1341
原创 基于Kafka2.1解读Producer原理
相信现在的javer对于Kafka应该都很熟悉了,不管是八股文还是工作中使用。虽然Kafka server是scala写的,但是client是java写的,所以咱们理解client的代码还是比较容易的,今天先来基于源码解读下Kafka Producer的主体流程Kafka的消息发送其实就是一个RPC的过程,有自己的网络协议、消息协议、消息序列化方式、数据批量发送(增加吞吐量)、超时处理、底层网络模型。不过Producer对于batch的复用,其实还是有一定的厉害之处的,等下次有空分析下~
2024-10-09 13:05:37
1197
原创 通过JITWatch查看汇编代码,观测jdk17改动对代码的影响
我们可以使用JITWatch来观测线上代码实际运行逻辑,来进行一些问题分析和学习参考。虽然线上运行的是机器指令,但是为了方便阅读和理解,JITWatch执行的都是汇编代码,是ARM指令集的汇编代码,不过咱们可以借助chat-gpt或者豆包等大模型帮忙解读没有想到C2编译器相对于C1编译器的高级优化(激进优化)里还有「分支预测」这一步JIT的编译优化也是有可能误判(错误优化)导致实际代码运行过程中需要进行逆优化再编译的。
2024-10-06 09:21:53
1437
2
原创 Springboot结合Mockito写单元测试实践和原理
相信看我博客的都是javaer,工作中一般都是使用Springboot框架。之前介绍过,可以利用@Transactional注解实现单测方法回滚,其实大家都知道Springboot-Test里面集成了Mockito,今天我们来介绍下怎么使用,以及原理是什么。文章主要讲了Springboot中的@MockBean和@SpyBean的使用场景和简单原理。
2023-10-16 20:27:37
1783
原创 AQS源码解读
AQS是AbstractQueuedSynchronizer的缩写,也是大神Doug Lea的得意之作。今天我们来进行尽量简化的分析和理解性的代码阅读。竞争资源总体分三步1. 尝试获取资源,成功就返回2. 失败了的线程封装成Node,加入到队列3. 加入到队列的Node,不停经历(阻塞-非阻塞-tryAcquire),直到获取资源成功释放资源分两步4. 尝试释放资源,失败了就返回5. 释放成功了,需要把头结点的waitStatus置空,唤醒下一个非CANCELED的Node进行资源获取操作。
2023-08-19 12:05:12
583
原创 手写简单的spring(2):实现循环依赖
文章目录前言一、前期辅助1.1 最朴素的想法1.2 真的这么丝滑么二、使用步骤1.引入库2.读入数据总结前言相信凡是写Java的同学都知道或者背过Spring实现循环依赖的方式吧,无非是三个缓存工厂,然后每个工厂放object的什么形态,bla-bla之类的。之前我也写过一篇博客,图解过 。不过,如果我们自己来实现,该如何写呢?接着我们上一篇的博客,继续探索一下。一、前期辅助1.1 最朴素的想法既然我们需要实现一个循环依赖,那么我们首先来写个demopublic class CycleSer
2022-04-04 19:30:11
737
原创 从硬件到软件去理解一致性
看了很多操作系统和软件中间件之类的知识之后发现,软件和硬件在大的方面有时候解决的是一样的问题软件层面需要解决的问题,其实在硬件层面早就解决过,在软件层面进行技术架构时可以进行参考。不过硬件层面比软件层面又好在没有网络因素在里面,所以需要对于具体的业务或者功能有相应的取舍。
2021-12-10 14:36:43
1761
原创 mac下配置PrintAssembly
有时候难免想看下对应的Java代码JIT编译之后的汇编代码是什么样有了printAssembly方式,咱们相当于可以查看JIT下class对应的执行的汇编指令。所以我们可以看看加了volatile的变量执行方式上具体有什么差异,相关内容已更新到这篇文章,欢迎不吝赐教。
2021-11-01 15:10:52
1523
原创 添加@Async注解,导致spring启动失败
文章目录前言一、异常表现,抛出内容1.1循环依赖的两个class1.2 启动报错二、原因分析2.1 主要原因2.2 循环依赖放入二级缓存处逻辑2.3 initializeBean生成的对象2.4 再次分析原因总结前言在这篇文章里,最后总结处,我说了会讲讲循环依赖中,其中一个类添加@Async有可能会导致注入失败而抛异常的情况,今天就分析一下。一、异常表现,抛出内容1.1循环依赖的两个classCycleService1@Servicepublic class CycleService1
2021-08-29 10:22:42
4448
4
原创 spring源码解读:@Async的原理——默认配置
文章目录前言一、如何使用@Async二、源码解读1.@EnableAsync的作用2. AsyncConfigurationSelector的作用3. adviceMode:PROXY(默认值)3.1 ProxyAsyncConfiguration3.2 AsyncAnnotationBeanPostProcessor3.3 AsyncAnnotationAdvisor3.3.1 buildAdvice3.3.1.1 AnnotationAsyncExecutionInterceptor,异步执行的原理3.
2021-08-22 21:38:29
2010
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅