自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(260)
  • 收藏
  • 关注

原创 IDEA中Git当前分支修改代码后不提交代码如何切换分支

在日常开发中,我们经常进行多分支开发,如当前我们正在A分支上开发 ,此时濡染要去修改另外一个分支B上代码的情况。而我们在A分支的开发的代码并未自测,并不能马上提交,如果此时我们点击切换分支按钮切换到B分支的话会出现如下界面。1、Force Checkout:不会把A分支的代码带到B分支,但是会删除当前分支修改未提交的所有代码,在切换会A分支,就找不到在A分支上开发的代码了。在当前分支上修改代码后,未提交需切换分支的时候,我们需要暂存当前修改的代码,待切换分支后还原暂存的代码。

2026-04-10 17:34:25 35

原创 把本地文件夹托管到 Gitee 仓库,实现公司和家里电脑都能编辑同步

核心流程:Gitee 建仓库 → 第一台电脑上传 → 第二台电脑clone拉取 → 编辑后同步。推荐配置 SSH 免密,减少重复输入账号密码的麻烦。每次编辑前先git pull,是避免文件冲突的关键习惯。

2026-02-26 14:06:56 763

原创 为什么switch不支持long

其次是设计层面:就算硬要支持 long,也会大幅增加 JVM 实现复杂度,而实际开发中用 long 做 switch 判断的场景极少,性价比太低。

2026-02-05 14:34:57 72

原创 Nacos 是 AP 还是 CP?一文讲透!

Nacos 是一个“双面派”:对于服务注册 → 用 AP(Distro),高可用优先;对于配置管理 → 用 CP(Raft),一致性优先;并且支持运行时动态切换,灵活应对不同业务需求。

2026-02-05 13:15:35 705

原创 MyBatis动态代理执行原理:为啥Mapper接口不用写实现类?

后来才反应过来,MyBatis就是靠动态代理给接口造实现类的,你自己写一个,相当于抢了它的活,不冲突才怪。尤其是参数多的时候,很容易搞混,后来我养成习惯,要么参数名和XML里保持一致,要么直接用。注入UserMapper时,Spring给我们的就是MyBatis生成的动态代理对象——和原生MyBatis的逻辑完全一致,只是多了一层Spring的容器管理。用过MyBatis的朋友都知道,这框架最爽的一点就是——写个Mapper接口,配个XML文件,不用写实现类,直接注入就能调用,SQL说执行就执行。

2026-02-05 09:49:52 655

原创 SpringBoot内置Tomcat启动原理:一行run()背后的猫腻

原来SpringBoot就是帮我们手动new了一个Tomcat实例,然后配置了端口、连接器这些东西,和我们自己下载Tomcat、配置server.xml本质上一模一样,只是它帮我们做了自动化。其实SpringBoot内置Tomcat的原理一点都不复杂,说白了就是帮我们把手动配置Tomcat的步骤自动化了:依赖自动引入、工厂类自动配置、容器自动启动。说白了,你引入web-starter,就相当于自动引入了Tomcat的依赖,这是基础。这个类的作用,就是帮我们自动创建Tomcat的工厂类,不用自己写一行配置。

2026-02-05 09:35:32 609

原创 SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案

在金融、电商等涉及金额的项目中,我们经常需要对BigDecimal类型的金额字段统一保留指定小数位数。如果在每个业务方法中手动调用setScale方法,会造成大量代码冗余,且难以统一维护。本文将介绍一种基于SpringBoot 拦截器 + 自定义注解的方案,实现金额字段的自动格式化,让代码更简洁、更易维护。该注解用于标记需要格式化的金额字段,支持通过scale属性指定小数位数,默认保留2位小数。/*** 金额格式化注解,用于标记需要统一处理小数位数的字段*/

2026-02-05 09:11:49 815

原创 达梦数据库与MySQL的核心差异解析:从特性到实践

场景推荐MySQL推荐达梦应用类型互联网应用、中小型企业系统政务/金融/央企等国产化项目技术栈开源生态、云原生、微服务信创体系、国产化软硬件适配核心需求轻量、灵活、低成本高可用、高安全、合规性运维成本社区支持,运维人员易招聘商用服务,需专业培训达梦与MySQL的差异本质是“商用企业级数据库”与“开源轻量数据库”的定位差异:MySQL胜在生态和灵活性,达梦胜在国产化适配、安全性和企业级特性。在迁移过程中,需重点关注语法适配、性能调优、权限安全三个维度,结合业务场景选择最优方案。

2026-02-04 11:52:12 870

原创 线程池竟能把CPU干到100%?两个JDK BUG踩坑实录

核心线程数不要乱设,的建议至少设为1;JDK 8及以下版本使用时,手动指定合理的;避免使用极端数值作为定时任务的延迟时间,防止数值溢出;条件允许的话,升级到JDK 9及以上版本,从根源上规避这些已修复的BUG。线程池是Java并发的核心工具,看似简单的API背后可能藏着复杂的底层逻辑。遇到问题时多扒扒源码,不仅能解决当下的坑,还能加深对并发机制的理解,何乐而不为?

2026-02-03 13:11:55 625

原创 再谈 Java 内部类与线程池:一个被忽视的内存泄漏陷阱

线程池不是“用完即弃”的一次性用品,而是操作系统级资源。每一次,都应当伴随一个清晰的生命周期管理策略。记住三条铁律局部变量 ≠ 可回收(只要存在 GC Root 引用);非静态内部类 = 潜在内存泄漏源;线程池必须全局化、容器化、受控化。当你下次想写“这个线程池,谁来负责它的生与死?附:安全线程池使用 checklist是否由 Spring / DI 容器管理?是否设置了合理的线程名(便于排查)?是否配置了拒绝策略和队列容量?应用关闭时是否会优雅 shutdown?

2026-02-02 16:34:27 899

原创 吃透 `@EventListener`:从实战到源码,彻底搞懂 Spring 事件监听机制

💡注意:Spring 4.2+ 支持直接监听任意 POJO,无需继承!场景推荐做法简单解耦+ POJO 事件需要事务控制耗时操作@Async复杂条件过滤condition属性 + SpEL避免异常中断自定义 Multicaster 或内部 try-catch事件链监听器返回新事件对象跨模块通知(如用户服务 → 积分服务)审计日志、监控埋点异步非核心流程(发邮件、推消息)状态变更触发(订单支付成功 → 库存扣减)掌握,你就能在保持代码简洁的同时,构建出高内聚、低耦合的系统架构。

2026-02-02 13:13:49 1092

原创 踩坑!Lombok @Builder和@NoArgsConstructor一起用,默认值居然失效了

当我们用builder创建对象,又没有给field1赋值的时候,builder里的field1就是null,然后通过全参构造器传给DTO的field1,直接覆盖了我们在DTO里设置的默认值true。当@Builder和@NoArgsConstructor、@AllArgsConstructor一起使用时,@Builder生成的builder类,其内部字段默认是null,build方法会调用全参构造器,用builder里的null覆盖DTO字段的默认值,导致默认值失效。

2026-02-02 09:04:29 735

原创 被volatile玄学问题折磨两年,大模型一句话给我整明白了

虽然这两种微调都能让程序结束,但千万不要在实际开发中这么写!这两个方法都是依赖JVM实现细节的“旁门左道”,完全不可靠。想要保证程序正确结束,唯一正确的做法就是给flag加上volatile关键字。这就像考试的时候,你知道正确答案是A,但偏要写个C,结果老师批卷的时候眼花给你打了对勾。这不是你厉害,只是运气好而已。

2026-01-30 08:49:04 641

原创 多线程下用 ConcurrentHashMap,到底要不要加 volatile?

单独拎出来 ConcurrentHashMap 和 volatile,每个知识点我都能说上几句,可把它们放在一起提问,瞬间就有种熟悉又陌生的感觉,琢磨了好一会儿才理清楚里面的逻辑,今天就把自己的思考过程整理出来,都是很实在的理解,没有什么官方套话。,也就是对象的引用,而不是对象内部的数据。而加上 volatile 之后,就能保证引用修改的可见性,所有线程都能立即获取到最新的实例引用,再结合 ConcurrentHashMap 自身的方法安全,整个流程才是完整的线程安全。

2026-01-29 08:59:10 564

原创 常用DOS命令全解析:从基础操作到实用技巧

作为Java后端程序员,日常开发中难免要和DOS命令打交道——不管是切换目录、查看文件,还是部署项目时的环境配置,掌握常用DOS命令都能大幅提升效率。这篇文章就按知识树结构,整理最实用的DOS命令,每个命令都配实操示例,新手也能直接上手。这类命令是DOS操作的基石,用于定位文件、切换目录,相当于“电脑文件管理器的键盘版”。用于创建、删除、复制、移动文件/文件夹,覆盖日常文件管理需求,避免频繁切换图形界面。删除指定文件,支持通配符批量删除,同样慎用(无回收站,直接永久删除)。

2026-01-26 17:07:02 606

原创 SpringBoot自定义启动banner:给项目加个专属“开机画面”

刚学SpringBoot的时候,每次启动项目,控制台都会跳出默认的SpringBoot logo和版本信息,看久了总觉得少点意思。后来发现原来这个启动画面(也就是banner)是可以自定义的,花几分钟改一改,既能加项目名称、版本,甚至还能加些有趣的字符画,瞬间让自己的项目有了专属感。今天就聊聊怎么自定义SpringBoot的启动banner,步骤超简单,新手也能跟着做。这个就是默认banner,我们要做的就是替换掉它,换成自己想要的内容。SpringBoot默认会读取resources目录下的。

2026-01-26 09:12:43 1090

原创 Docker run 命令详解(-a、-d、-e、-h、-i、-m、-p、-t、-v、--cpuset、--dns、--env-file、--expose、--link、--name、--net)

用来声明容器开放的端口,但不会做端口映射,只是告诉 Docker 这个容器会使用这些端口,通常用于容器间通信,或者让外部知道容器的端口用途。就算不小心删了容器,重新启动时再挂载同一个目录,数据就能恢复。之后,容器会在后台默默运行,还会返回一个唯一的容器 ID,后续管理容器(比如停止、重启)都能用这个 ID 或者容器名操作。即可,不过要注意,这种方式启动的容器,退出后会自动停止,如果想让容器继续后台运行,可以加。选项能把容器里的目录挂载到主机的目录,数据会直接存在主机上,就算容器删了,数据也能保留。

2026-01-23 13:04:15 1366

原创 为什么游戏公司的server不愿意微服务化?

但游戏服不行,玩家在线的每一秒,都要维护他的实时状态,要是把状态拆到多个服务,比如位置存在场景服、血量存在战斗服,玩家掉血的时候,场景服没及时拿到血量更新,就会出现“玩家血条空了还在跑”的BUG。但游戏服务器的负载是“脉冲式”的,开服瞬间几万玩家同时登录,团战的时候几百人在一个场景里交互,这种高并发是集中在某几个核心模块的,拆成微服务也没法把压力分散,反而会因为服务间依赖,导致一个模块崩了,整个链路都出问题。微服务里,状态分散在不同服务,要保证强一致,就得用分布式锁、事务,复杂度直接翻倍。

2026-01-23 08:50:52 714

原创 SpringData JPA 都能写 SQL,为啥还要用 MyBatis?

要是关联的表多,比如用户关联订单、订单关联商品、商品关联分类,JPA会生成一堆JOIN语句,甚至出现N+1查询问题(查1个用户带出N个订单,会执行1次查用户+N次查订单的SQL),性能直接拉胯。MyBatis就不一样了,写的SQL就是最终执行的SQL(除了动态拼接的部分),要是查询有问题,直接把XML里的SQL复制到数据库客户端,替换掉#{参数},执行一下就能定位问题。MyBatis处理多表关联,是手动写JOIN SQL,虽然要自己写关联条件,但能精准控制查询的字段和关联的表,避免冗余查询。

2026-01-22 11:02:43 892

原创 Java Spring中@AllArgsConstructor注解引发的依赖注入异常解决

会覆盖无参构造函数,Spring Bean若无无参构造函数则无法实例化,需搭配使用;触发的构造函数装配默认使用@Autowired逻辑,无法兼容等特殊注解,需改用字段注解装配;Lombok注解简化开发的同时,需兼顾Spring依赖注入的规则,避免注解冲突。

2026-01-22 09:46:36 690

原创 Java DateTimeException:Unable to obtain LocalTime from TemporalAccessor问题解决

如果不想引入,可以通过自定义解析规则,只提取时间字段,忽略日期字段。这种方案更灵活,适合复杂的解析场景。try {// 关键:自定义TemporalQuery,仅提取LocalTime字段});System.out.println("订单支付时间:" + payTime);// 输出:15:30:45System.err.println("时间解析失败:" + e.getMessage());包含了LocalTime不需要的日期字段,导致无法构建纯时间对象;

2026-01-21 13:14:14 927 1

原创 Java java.lang.ArithmeticException: Rounding necessary问题解决

异常的核心是BigDecimal的setScale无参方法默认不允许舍入,仅当需要舍入时抛出;解决该异常的核心思路是显式指定舍入模式,要么在setScale中指定,要么在除法/乘法等运算时直接指定;不同舍入模式对应不同的业务规则,需根据实际场景选择(如金额计算优先用HALF_UP。

2026-01-21 09:32:39 978

原创 VARCHAR 存日期的灾难

比如存2024年1月19日,有人写“2024-01-19”,有人写“2024/01/19”,还有人图省事写“20240119”,甚至还有“24-01-19”“2024年1月19日”这种写法。排序就更坑了,字符串排序是按字符一个个比的,比如“2024-10-01”和“2024-02-01”,按 VARCHAR 排序,“2024-02-01”会排在“2024-10-01”后面,因为字符“0”比“1”小,但实际时间上2月明明在10月前面。后来改成 DATE 类型,加个索引,同样的查询1秒不到就出来了。

2026-01-19 14:13:06 794

原创 openfeign vs nginx 负载均衡对比

我认为 openfeign 和 nginx 不是竞争关系,而是互补关系。不用纠结哪个更好,关键看使用场景。如果是做对外的入口层负载,选 nginx 准没错,简单、稳定、性能强。如果是微服务内部调用,优先用 openfeign,和 Spring Cloud 生态契合,开发效率高,还能轻松实现熔断、重试等功能。在我看来,理解两者的定位差异,就能在项目中合理搭配使用,既保证外层请求的高效分发,又能让内部服务调用更灵活可靠。

2026-01-16 13:18:49 1151

原创 SpringBoot 在一次 http 请求中耗费了多少内存?

其实问“一次请求耗多少内存”,没有固定答案,我认为核心不是纠结具体的数字,而是要有“内存意识”——知道哪些代码会耗内存,高并发下该怎么优化。普通的业务接口,单次消耗几十 KB 其实很正常,只要不是几百 KB 甚至几 MB,一般都没问题。但如果是每秒几千、几万的高并发接口,哪怕单次只耗 10 KB,一秒钟也会耗掉几十 MB 内存,这时候就得精打细算了。总的来说,SpringBoot 本身的基础开销是固定的,我们能优化的主要是业务代码里的对象创建和数据传输量。

2026-01-16 08:54:43 1123

原创 聊聊负载均衡:分布式架构的“流量调度员”

负载均衡看着知识点多,但实际用的时候,核心就是“选对类型+选对算法+选对产品”。我认为,中小项目优先用Nginx+云厂商SLB,成本低、配置简单、稳定性够;中大型集群可以用HAProxy+LVS,四层七层配合;微服务项目直接上Ingress-Nginx。另外,不要盲目追求“最好的产品”,适合自己业务的才是最好的。比如简单的Web服务,Nginx完全够用,没必要上F5;对会话要求高的场景,用IP哈希+动态兜底算法,既保证会话又能均衡负载。

2026-01-15 09:37:19 698

原创 JDK8和JDK17的GC对比:用着顺手才是王道

不管是默认的G1 GC,还是低延迟的ZGC、Shenandoah,都比JDK8的GC表现更好,而且不用复杂的参数调优,用起来更省心。除了回收器本身,GC的日志和监控方面,JDK17也比JDK8好用很多。我之前查JDK8的GC日志,最头疼的就是不同回收器的日志格式不一样,Parallel GC和CMS的日志看得我眼花缭乱,还要找专门的工具解析。如果你的项目是老项目,一直用JDK8,而且是后台批处理、数据计算这类对延迟不敏感的场景,那继续用JDK8的Parallel GC也没问题,毕竟稳定最重要。

2026-01-15 08:30:00 725

原创 idea中为啥双 Shift 叫 “全局搜索” 却搜不到文本内容?

双Shift的“全局搜索”是实体类型的全局覆盖,不是文本内容的全局扫描它的强项是找“东西”(类、文件、功能),不是找“文字”(代码片段、字符串)。Ctrl+Shift+F才是专门用来找“文字”的工具,它的强项是扫描所有文件的文本内容。我们的经验是,别被“全局搜索”这个名字骗了。找实体用双Shift,找文本用Ctrl+Shift+F,这样效率才最高。

2026-01-14 08:45:28 1339

原创 【Java报错已解决】java.lang.UnsatisfiedLinkError:踩坑后才懂的排查与解决

看似复杂,其实核心就三类问题:库找不到、方法名不对、架构/依赖不兼容。先确认库文件在里,这是最常见的问题方法名一定要用工具自动生成,别手动写,避免拼写错误库的架构必须和JVM一致,依赖库要装全我们的经验是,遇到这个报错别慌,按“路径→方法名→架构→依赖”的顺序排查,90%的问题都能在10分钟内解决。如果是用第三方库(比如OpenCV、TensorFlow的Java包)碰到这个错,优先看官方文档的库配置说明,大部分开源库都会标注需要的依赖和配置方式。

2026-01-13 10:29:58 726

原创 RabbitMQ 中无法路由的消息:原来它们都去这了

RabbitMQ 中无法路由的消息,命运完全由我们的配置决定:默认丢弃、退回生产者、转发到 AE 交换机。别依赖默认配置,除非明确允许消息丢失对可靠性要求高的场景,用mandatory=true + 退回回调需保存无法路由消息的场景,配置 AE 交换机定期监听 AE 队列,排查路由配置问题,避免大量消息堆积其实这个问题不难,关键是搞懂 mandatory 和 AE 交换机的作用,再根据业务场景选择合适的配置。如果大家有其他处理无法路由消息的技巧,也欢迎一起交流~

2026-01-13 09:28:20 1292

原创 我的笔记:怎么用 MySQL 的 EXPLAIN 来分析 SQL

我常常用EXPLAIN来调优慢查询;索引不见得越多越好,但没有关键索引,查询肯定会慢;同一个WHERE条件写法不同,执行计划也可能变化,所以写 SQL 的时候注意表达方式;多表关联的时候,EXPLAIN能帮我判断哪个表应该做先驱表(这个在复杂联查里特别重要)。总的来说,我认为EXPLAIN就像是数据库对你说:我打算怎么执行这条 SQL。理解它,不是为了背输出字段,而是为了能根据结果判断这条 SQL 有没有优化的空间。

2026-01-09 10:57:54 1054

原创 MySQL 索引真不是越多越好!聊聊索引的 “隐形代价”

索引就像调料,放对了能提味,放多了反而毁菜。它不是越多越好,而是要在查询性能和写入成本之间找平衡。每个索引都是“负债”,要承担维护成本,不是必需的就别建优先建联合索引,一个设计好的联合索引能顶好几个单列索引定期清理无用、冗余的索引,就像定期大扫除写入频繁的表,索引一定要精简;查询频繁的表,可适当多建,但也要控制数量其实建索引没有绝对的标准,关键是结合自己的业务场景,按需创建、定期优化。如果盲目建一堆索引,最后只会导致整个数据库性能下滑,得不偿失。

2026-01-06 08:57:21 1017

原创 秒懂 MySQL 索引下推:从查询原理看清有无下推的核心差异

索引下推的核心差异:无下推时存储引擎只筛索引前缀列,服务层全量回表后筛剩余条件;有下推时存储引擎利用索引内的非前缀列提前过滤,大幅减少回表IO。性能提升的关键:减少无效回表次数——回表是磁盘IO操作,每少一次,查询效率就高一分。EXPLAIN看Extra列,即生效,则未生效。其实索引下推的本质很简单:让离数据最近的存储引擎多做筛选,少让服务层做“无用功”。理解了存储引擎和服务层的交互逻辑,有无下推的区别就一目了然,不用靠生活例子也能精准掌握。

2026-01-05 09:06:50 931

原创 MySQL B + 树索引高度:原来这么多数据才需要 3 次 IO

B+树索引高度的计算看着复杂,其实核心就是“算每个节点能存多少,再算整棵树的容量”。理解了这个逻辑,就知道为啥千万级数据查询还能很快——因为索引高度没上去,IO次数少。主键尽量用INT或BIGINT,别用太长的VARCHAR,减少索引项大小控制单行数据大小,别搞太多大字段,让叶子节点能存更多行数据量超千万后,提前规划分库分表,别等性能下降了再补救每个节点=一个InnoDB页,读一个页=一次IO,查数据要从根节点走到叶子节点,经过的节点数=树的高度,所以IO次数=树的高度。

2026-01-04 09:10:23 932

原创 消除Intellij IDEA的Not annotated parameter overrides @NonNullApi parameter警告

只需要在方法的参数上添加@NonNull注解即可(注意:是org.,尤其是纯 Java 且不用 Kotlin 的项目。.lang.NonNull,不要导入错了)

2025-12-30 11:22:25 555 1

原创 MySQL 行锁:别让数据打架了

简单说,行锁就是 MySQL 在执行某些操作时,只锁住某一行数据,而不是整张表。这样别人还能改别的行,不会被你一个人占着茅坑不拉屎。假设 A 用户和 B 用户同时要转账,如果用表锁,那 A 转账的时候 B 就得干等着;但用了行锁,A 改自己的那行,B 改自己的那行,互不干扰。行锁是 InnoDB 的“精细控制”手段,只锁需要的行。必须走索引,否则可能锁太多。“读-判断-写”场景记得用FOR UPDATE。死锁不可避免,但可以通过规范操作顺序减少。行锁锁的是整行,不是某个字段。

2025-12-29 11:39:46 694

原创 Spring Retry 实战:优雅搞定重试需求

catch 加 while 循环写,代码又丑又难维护,后来发现了 Spring Retry,用起来是真方便,分享下我的使用经验。有状态重试就特殊了,比如数据库事务场景,失败后需要回滚事务再重新开始,这时候上下文得存在堆里,避免丢失。用 Spring Retry 第一步肯定要引依赖,我这边是 Spring Boot 项目,除了核心的 spring-retry,还得加 aop 依赖,不然注解不好使。这个点容易被忽略,我简单说下。无状态重试就是普通场景,重试上下文存在线程栈里,不用额外存储,大部分情况都能用。

2025-12-29 09:43:06 1032

原创 静态资源映射相关问题解答

文件保存到本地 / 服务器磁盘只是「物理存储」,但浏览器地址栏输入 URL 访问文件是「网络请求」—— 必须有一个「中间层」(Web 服务器 / 接口)把「磁盘文件路径」映射成「HTTP 可访问路径」,否则浏览器根本不知道如何访问本地文件。后来排查才知道,服务器上肯定配置了静态资源映射,把磁盘路径和 HTTP 路径关联起来了,而我本地只做了文件保存,没加这个配置。不过这个方法只适合测试,我们的经验是,项目重新编译或者重启后,static 目录里的上传文件会丢失,生产环境绝对不能用。,但访问就是 404。

2025-12-26 09:23:43 841

原创 MyBatis-Plus 的 updateById 会把没查的字段清成 null 吗?

这个问题我前阵子被同事问过,自己也一度有点犯嘀咕。场景很简单:有个订单表order,20个字段。我只用id=1查了 A、B、C 三列,然后改了 C 的值,调我当时第一反应是:“好像不会吧?”但又不敢拍胸脯。于是翻源码、打日志、写测试,折腾了一下午,总算搞明白了。今天就用大白话讲讲我的理解,顺便给还在担心的朋友吃颗定心丸。

2025-12-25 08:58:10 976

原创 踩坑:Gateway 请求体只能被消费一次?

当时想在 Spring Cloud Gateway 里加个全局过滤器,把所有进来的请求参数(尤其是 POST 的 JSON)打个日志,方便排查问题。我认为,这个“只能读一次”的设计虽然反直觉,但其实是合理的。跑起来你会发现:日志是打出来了,但下游服务收到的 POST 请求是空的,直接报错“缺少参数”。这样,后续的过滤器和下游服务拿到的还是完整的 body。它是一个字节流,像水管一样,数据流过去就没了。读完了,下游路由到微服务的时候,body 就空了。今天就聊聊这个“坑”,以及我们是怎么绕过去的。

2025-12-24 15:29:26 996

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除