库存扣减、创建订单,如何拆成TCC?

典型回答 这是一个比较典型的场景题,考察对TCC的理解。 我们先来回顾一下TCC。 ✅什么是TCC,和2PC有什么区别? 所谓TCC,就是把一个操作拆分成Try\Confirm\Cancel三个步骤,并且这三个动作已经不是一个事务了,而是三个不同的事务。 怎么理解上面这句话呢? Try\Confirm\Cancel分别是三个不同的方法,站在事务参与者的角度,在代码中,每一次调用Try或者Confirm或者Cancel的时候,都会单独开启一个数据库事务(如果数据库支持的话),这就是2PC比较大的区别,2PC从头到尾就一个事务。 那么TCC如何拆呢?其实再看下TCC的定义: Try阶段:执行业务检查,预留资源 Confirm阶段:若所有Try成功,提交资源 Cancel阶段:若任一Try失败,释放预留资源 那么回到问题上,针对库存扣减,如何拆解成TCC呢? Try阶段:执行业务检查,预留资源 冻结库存 <font style="color:rgb(64, 64, 64);">update inventory_table set frozen_inventory = frozen_inventory + #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">冻结库存</font> + 1,用户看到的<font style="color:rgb(64, 64, 64);">可用库存</font> = <font style="color:rgb(64, 64, 64);">剩余库存</font> - <font style="color:rgb(64, 64, 64);">冻结库存</font> ,那么,这就起到了资源预留的作用。 Confirm阶段:若所有Try成功,提交资源 解冻并扣减库存 <font style="color:rgb(64, 64, 64);">update inventory_table set frozen_inventory = frozen_inventory - #{count},saleable_inventory = saleable_inventory - #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">冻结库存</font> - 1, <font style="color:rgb(64, 64, 64);">剩余库存</font> - 1,即真正做库存扣减。 Cancel阶段:若任一Try/Confirm失败,释放预留资源 解冻库存 <font style="color:rgb(64, 64, 64);">update inventory_table set frozen_inventory = frozen_inventory - #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">冻结库存</font> - 1, 即释预留资源 Cancel阶段:若Confirm成功,但是其他参与者失败,需要回滚Confirm操作 回退库存 <font style="color:rgb(64, 64, 64);">update inventory_table set saleable_inventory = saleable_inventory + #{count} where id = xxx</font> <font style="color:rgb(64, 64, 64);">剩余库存</font> + 1,即回退库存扣减操作。 ...

March 22, 2026 · 1 min · santu

防止接口被恶意刷流量,除了限流还应在代码层面做哪些防护?

典型回答 接口恶意被刷的话,我们需要通过技术手段来识别出来哪些流量是恶意流程,区别于正常流量,恶意流量一般他的请求都是自己伪造的一些异常参数或者非法参数。还有就是恶意流量大部分都是机刷的,所以要想办法识别出非人为的流量。 第一部分,针对异常参数和非法参数的防控是很重要的,我们的接口需要有非常强的参数校验和过滤能力,主要需要从这几个方面来考虑: 1、验证码,这个大家都很好理解,对于一些流量来源是用户操作界面的接口,可以要求用户输入验证码,或者是做一些行为验证码,比如那种滑动拼图的,这样就可以提升一部分的接口安全性。 2、token,和验证码类似,就是一些关键的接口,需要用户提交合法的token,所谓token其实就是个口令,是一个我们提前发放给用户的合法的参数,只有带来token的,我们才认为他是合法用户。token也有很多种,比如用户登录后的token,或者是用户访问页面的时候请求后端拿到的token等等的。并且针对token我们可以做定期的刷新,以及限流。 3、验签,这个一般是对外提供的接口是需要的,这个不详细说了,可以看下面这个文章: ✅加密&解密、加签&验签做的事情一样吗? 4、参数合法性校验,针对一些特殊的参数,需要多做一点边界值、特殊值的校验,比如手机号要求11位,邮箱做正则匹配,list限定一下最大的数量等等的。我们之前就出现过,内部的安全扫描扫到我们一个贷款分期试算的接口,他传了一个巨大的数字,但是后端没做校验,就开始进行分期计划的试算了,因为实在是太多了,就直接把内存干爆了。所以,入参中多加点限制,@NotNull 、 @Min @Max多用用。 5、行为逻辑关联性校验。比如组合下单前, 比如是有添加购物车行为的,不能绕过加购来做组合下单、 另外,就是识别出一些机刷的流量,这部分其实是非常专业的风控领域了,一般有专门的风控来做,我们也可以了解一些。 1、集成人机识别服务,通过 TLS 指纹、IP 信誉库、鼠标轨迹分析等区分真人用户与机器人。 2、把用户的请求生成唯一设备指纹(通过 User-Agent、屏幕分辨率、Canvas 指纹等),识别并限制同一设备的异常高频请求。 3、统计用户请求的时间间隔分布,正常用户操作存在随机性,而脚本请求往往呈现固定频率。 4、检测请求IP的地理位置(如境外代理IP)、ASN(自治系统号),结合历史数据标记可疑来源。 5、….还有很多很多,借助算法能力可以挖掘出很多异常行为。

March 22, 2026 · 1 min · santu

Redis保存库存的时候,如何避免被Redis清理掉?

典型回答 用Redis做库存扣减,是非常常见的一种抗高并发的方案。但是,如何避免这个库存被Redis给清理掉呢?这其实是一个关于Redis的淘汰策略的问题。 ✅Redis的内存淘汰策略是怎么样的? 上面这篇文章介绍过,Redis的淘汰策略分几种,比如lru、lfu、random等等,不管是哪种,其实太还会有另外一个叠加条件,那就是allkeys还是volatile allkeys就是所有的key都参数LFU、LFU等等的淘汰筛选。而volatile则是只有设置了超时时间的key才会参与到淘汰筛选中。 一般来说,allkeys-lru和volatile-lru用的比较多,allkeys这种主要用于你把Redis当纯缓存的时候,就是他没了就没了,无所谓。大不了去查数据库。 而Redis来做库存处理,是一种非常典型的半缓存半持久化的场景,这种场景就比较适合volatile-lru这种策略,这也是像阿里云上的Redis的默认的淘汰策略。 当然,如果你为了保险,你可以像腾讯云的redis一样,选择noeviction作为淘汰策略,他在内存满了之后会OOM,而不是帮你淘汰数据。但是这种我不太建议,因为内存毕竟有限,还是设置个淘汰策略好一点。

March 22, 2026 · 1 min · santu

如果token被窃取了,是不是就能伪造登陆了?

典型回答 假如,我们拿到了别人在某个网站上登录后的token(通常为AccessToken) ,是不是就可以直接用这个token访问他的数据了呢?是不是就相当于可以直接登录了呢? 确实是,一般是这样的,而且很多爬虫工具也是这么做的,有些网站需要鉴权的时候,你只要把自己的登录的token配置上就行了。 因为token是很多登录框架做鉴权的主要手段,所以很多时候,我们想要模拟登陆某个网站的时候,都是通过预先获取token做的。 那么,这个问题如何避免呢?可以从以下几个方面去考虑。 首先就是如何避免token被窃取,第二是如果获取到如何减少被攻击的概率。 如何避免token被窃取 首先,**token的窃取一般在2个阶段可以做,一个是网络传输过程中,一个是存储过程中。**网络传输这个比较简单,一般来说我们只需要注意,第一不要在url中传输token,而是通过header等方式传输。第二就是尽可能使用HTTPS的方式传输即可。 那么在存储过程中,我们需要注意的一般来说,我们的token都是通过浏览器cookie存储的,那么想要避免cookie被窃取,可以通过设置HttpOnly 和 Secure属性来实现。 1 Set-Cookie: session_id=abc123; Secure; HttpOnly; Path=/ HttpOnly 标记的 Cookie 会被浏览器存储,但禁止客户端 JavaScript(如 document.cookie)读取或修改该 Cookie。这是防御 XSS(跨站脚本攻击) 的关键手段,因为即使攻击者注入了恶意脚本,也无法窃取受保护的 Cookie。 Secure 属性确保浏览器仅在 HTTPS 加密连接中发送该 Cookie,防止在 HTTP 明文传输中被中间人窃取。 另外,很多时候token也被存储在cookie以外的存储中,比如LocalStorage/SessionStorage,这些位置应该尽量避免存储token。 LocalStorage 和 SessionStorage 是浏览器提供的两种客户端存储机制。 如何降低token被窃取带来的影响 过期/刷新机制 可以通过过期机制让token的不要那么长,比如短有效期(如15分钟~1小时),减少攻击窗口。 还可以引入RefreshToken机制,用于在 Access Token 过期后获取新的令牌,减少长期暴露敏感令牌的风险。 IP绑定 为了避免被窃取,可以将Token与用户登录时的IP或设备指纹(如mac地址、umid等)绑定,异常来源直接拒绝。 速率限制 还可以做一个限制单个Token的请求频率,防止自动化攻击。 多重验证 对敏感操作(如登录、修改密码)要求第二因素验证(短信、刷脸、指纹等),即使Token泄漏,攻击者仍需突破额外屏障。

March 22, 2026 · 1 min · santu

下单支付过程,点击跳转支付,输入密码,支付完成后跳转到订单页,整个过程可能会有什么问题?架构方面做哪些设计?

典型回答 这个问题是个非常大的问题,从这个问题开始展开,几乎够聊一整场面试的了。非常考验一个人的能力。那么我们试着分析下,整个过程会涉及到哪些问题,以及该如何解决和优化。 问题1:支付跳转失败 这种情况一般出现在第三方支付系统出现异常,或者网络出现异常的情况,导致我们无法成功跳转到某个支付渠道的收银台上面去。 这里涉及到的其实是一个故障转移相关的问题,也就是当某个系统不可用了,出现故障了,那么如何降低对本系统的影响。 其实,最有效的办法就是限流、降级、熔断一把梭。 ✅限流、降级、熔断有什么区别? 首先需要实时监控各个支付渠道的成功率,当某个渠道的成功率降到一定阈值之后,比如80%以下,则在收银台上渲染支付方式的时候直接不展示这个支付渠道,或者只给一部分用户展示这个支付渠道,这样就起到了一个限流、或者熔断的作用了。 等过一会支付成功率恢复了之后,再恢复收银台的展示即可。 问题2:支付状态未同步 对于第三方支付来说,支付结果一般都有多种方式通知的,一种是渠道会做回调,再创建支付的时候注册一个回调地址,在支付成功/支付失败后,会回调指定的地址,在这个地址中处理结果就行了。 对于页面来说,前端也会不断轮询这个支付单的状态,当回调处理完之后,前端就会直接跳转到成功页面上面去了。 还有一种就是调用方也可以主动轮训这个支付状态的,支付渠道会提供一个查询接口,我们可以通过定时任务轮训查询,或者最简单的就是页面上提供一个链接:如页面未跳转,请点击跳转。 这个点击其实就是向后端发起一个查询,后端会查询一下支付渠道,如果成功了,则直接处理成功要干的事儿,以及页面进行跳转。 另外,还需要一个兜底的定时任务,防止万一用户不点击链接导致不一致的情况。 问题3:用户重复支付 这个也是比较常见的,这个就不展开说了,下面几篇都写的很清晰了。 ✅基于Token校验避免订单重复提交 ✅如何解决消息重复消费、重复下单等问题? ✅一个支付单,多个渠道同时支付成功了怎么办? 问题4:支付完成后页面未跳转 这种情况,和问题2其实处理方式一样,就是页面是增加主动查询的链接,主动去支付渠道查询结果。 问题5:支付成功后库存未扣减、或订单状态未推进 这个,其实就是涉及到分布式系统的一致性问题了。很多订单,会在支付成功后扣减库存,并且更新订单状态的。 这就涉及到订单、支付、库存三个系统之间的一致性了,其实就是个分布式事务的问题。 在这个场景下,可以考虑用TCC或者AT的分布式方案解决。不建议用MQ的方案,因为MQ的方案有延迟,是最终一致性,支付这个地方对一致性要求还是挺高的。 关于TCC,可以从下面这篇开始看: ✅什么是TCC,和2PC有什么区别? 关于AT,可以从下面这篇开始看: ✅Seata的AT模式的实现原理 在我的那个数藏项目中,支付成功后同样会处理订单、支付、藏品、链等几个模块的一致性,用到了Seata的AT模式,同时为了解决外部链平台不可用导致的额外回滚问题,引入了事务钩子机制。详细的代码和讲解可以从项目课中了解。 🧣🧣🧣项目实战课介绍&老用户福利 问题6:支付数据被篡改 这个问题一般很少会出现,因为成熟的第三方支付系统,都会需要进行加签验签、加密解密的。只要按照要求做了, 一般都没啥问题。 ✅加密&解密、加签&验签做的事情一样吗? 问题7:用户不支付,卡在支付中 如果支付一直没支付,那么我们需要有超时机制来让支付单失效。 这就需要一个超时关单的功能了,这个我也讲过很多方案: ✅订单到期关闭如何实现 建议大家优先考虑用定时任务的方案,而不是MQ的方案。 ✅为什么不建议使用MQ实现订单到期关闭? 另外,这里的关单需要和支付渠道的时间保持一致,避免出现我们自己关单了,但是渠道还没关单,导致用户自己打开支付宝或者微信找到那个支付单自己付掉的情况。 一般就是给渠道的超时时间比自己系统的短一点,让他先超时,他超时的时候也会回调我们,我们直接处理我们的关单即可。如果他一直没回调,我们的时间到了之后,主动关单的时候也掉一下渠道的关单接口即可。

March 22, 2026 · 1 min · santu

如何从 1TB 的搜索日志中找出搜索量最高的 10 个关键词?

典型回答 从1TB的日志中找到搜索量最高的10个关键词,暴力统计肯定也行,但是面试官肯定不想听这个答案。 一个比较典型的方案就是:哈希分片+大根堆+统计 所谓的哈希分片,其实是一种典型的分治思想。通过哈希的方式,将相同关键词分配到同一分片,便于统计全局次数。 一般是选择一个相对均匀的哈希函数,比如murmurhash,然后遍历日志文件,将每一个搜索的关键词通过哈希计算分散到不要固定数量的分片文件上(可以大一点,比如几百个,或者1000个都可以)。这样就能确保同一个关键词可以落到同一个分片文件中。 接下来,就可以针对每个文件,逐行读取关键词并使用哈希表统计词频。将统计结果按次数降序排序后保存为中间文件。 因为每个中间文件按次数降序排列的,那么我们就读取每个文件的第一个关键词(即当前分片的最大次数),将其加入最大堆。再使用一个最小堆维护当前前10高频词,初始为空。 然后开始循环执行: 1. 从最大堆中取出当前全局最大次数候选(记为`关键词K,次数C`)。 2. 若前10堆(最小堆)未满,直接加入;若已满且`C > 堆顶最小值`,则替换堆顶。 3. 若`C ≤ 堆顶最小值`且前10堆已满,提前终止(后续关键词次数只会更小)。 4. 从`K`所在分片文件读取下一个关键词,更新最大堆。 输出结果:最终前10堆中的关键词即为全局Top 10。 扩展知识 为啥找最大值要用最小堆 ✅海量数据查找最大的 k 个值,用什么数据结构?

March 22, 2026 · 1 min · santu

有一张上百万条数据的单表,从前端页面、Java后台、数据库三个层面做查询优化

典型回答 这是一个比较常见的典型的性能优化的场景题,并且问的并不算难,因为他限定了前端页面、Java后台、数据库,而且还说了数据库是单表。那也就意味着我们不用考虑太多的分布式系统、分库分表等带来的影响了。 那么,分别从三个方面该如何优化呢? 前端 百万级数据,肯定不能一页就查询出来,所以肯定要分页查询。另外,建议页面上增加滚动加载或者下拉加载的效果,一方面提升用户的体验,另外也能避免跳页查询,能够更好地解决深分页的问题。 ✅MySQL的深度分页如何优化 除了分页以外,还需要提供关键词搜索、过滤条件、排序选项,总之就是避免用户全量查询。另外在输入框中加防抖的功能,减少频繁请求,比如一定要点击查询按钮才发起请求。 前端排序,对于有一些数据如果需要在当前页排序的话,完全可以用前端排序代替后端排序,这样不仅能减少多次查询请求,还能更快的实现排序。 还有就是前端也是可以作缓存的,对查询频繁的下拉框、静态表单选项等做前端缓存或预加载。 Java代码 首先分页查询的问题还是要的,后端也要做些控制,比如限制最大的pageSize,避免无条件的全表查询等。 接着就是可以考虑做一些缓存,针对一些变化不频繁地热点数据,可以考虑在Redis或者本地做一层缓存,减少对数据库的查询,来提升性能。 异步处理+预读,对于查询可能会耗时的操作了 ,可以提前通过Future异步的方式查询,然后主线程继续执行其他的代码,当需要这些数据的时候,再从Future中取出数据,这样也能提升一定的效率。 ✅如何在 Java 中实现高效的异步编程?如何避免回调地狱? 数据库优化 这就是核心的了,但是其实百万级数据,还是比较好优化的,主要就是考虑索引、避免多表join、避免深分页、减少Select *等几个方面。 因为百万级数据完全没必要上读写分离、分库分表这些,只要把索引弄好,没有join,没有深分页也就够了。 索引: ✅索引失效的问题是如何排查的,有哪些种情况? ✅为什么MySQL会选错索引,如何解决? ✅设计索引的时候有哪些原则(考虑哪些因素)? ✅SQL执行计划分析的时候,要关注哪些信息? join: ✅为什么大厂不建议使用多表join? ✅什么是数据库范式,为什么要反范式? 深分页: ✅MySQL的深度分页如何优化 select * : ✅为什么要尽量避免使用select * ?

March 22, 2026 · 1 min · santu

用@Scheduled执行定时任务,如何避免集群的并发问题

典型回答 在 Spring Boot 项目中,@Scheduled 默认在每个实例上都会执行一次任务。如果你的应用部署在集群环境下,所有节点都会执行 @Scheduled 任务,可能导致并发问题。 那么如何解决呢? 他山之石,可以攻玉,先看看xxl-job是咋解决的: ✅xxl-job如何保证一任务只会触发一次? 他是基于数据库的悲观锁,多个实例执行的时候,大家一起抢锁,谁抢到了谁执行。 所以,我们也可以用**悲观锁**的思想。 不管使用xxl-job这种select for update的悲观锁,还是基于Redis、Zookeeper来实现分布式锁,都是同样的思想,就是谁抢到锁,谁执行。 几种分布式锁实现方式如下: ✅分布式锁有几种实现方式? 但是需要注意,这里最好用非阻塞锁,抢锁失败就直接返回失败,而不是要一直等。那么就可以用redis的tryLock代替lock。 除了加锁之外,还可以用另外一种方案,那就是**选主** 大家不妨想一下,其实是加分布式锁,谁抢到谁执行,这其实就是一种选主,大家一起选择一个master,谁是master谁执行。 那么,就可以用zookeeper,它能实现master选举的能力,任务执行的时候去选主,如果选举成功,则给他执行,否则就不执行。 除了以上方案外,再追问的话,就只能废弃到Scheduling Task这种用法了,用XXL-JOB、 Quartz 等框架代替。

March 22, 2026 · 1 min · santu

假设还有很多内存,有什么情况还会频繁fullgc?

典型回答 好问题。下次我也问下哈哈哈哈。 有以下几个思路供大家参考: 1、你看到的可能不是JVM内存 有可能你看到的很多内存,比如用free命令,是机器内存,而不是JVM内存。我们需要看JVM内存的情况来判断内存是不是还足够。因为大多数时候我们的JVM内存只是机器内存的1/2 -> 2/3。 这时候需要检查JVM的内存情况,可以用以下方式: 1、jstat -gc 1000 2、jmap -heap 3、使用arthas 2、有大量内存碎片 有时候,虽然有可能内存挺多的,但是都是碎片,比如老年代采用的标记清除算法的话,就会有很多碎片存在。 解决思路是可以考虑改用G1算法,可以避免老年代碎片的发生。 3、大对象进入老年代 可能内存还挺多,但是来一个大对象,比剩余的内存还大,那么老年代放不下,就会触发full gc了。 4、元空间不足 FullGC不仅是老年代不足会导致,元空间(老版本的PermGen也会)不足也会导致FullGC ✅YoungGC和FullGC的触发条件是什么? 如果你的代码中有很多动态类加载的代码,如反射,CGlib等,都会导致大量的类加载,把元空间干满。如这个case: ✅频繁FullGC问题排查 **5、 过度调用 ****System.gc()** 这个虽然出现的概率不高,但是我们要知道, 手动调用 System.gc() 会导致强制 Full GC。而有些第三方库(如 RMI、JDK Management Beans)可能会隐式调用System.gc()。 当上面的问题都排除了,可以考虑下这个方向。

March 22, 2026 · 1 min · santu

压测600没问题,上线后300就扛不住了,可能是什么原因?

典型回答 ✅什么是压测,怎么做压测? 大多数时候,压测能压倒600,实际上也是可以扛得住600的,但是也有些特殊情况,我们其实就是发生过,比如下面我要介绍的数据倾斜问题、外部系统影响等问题,都是比较常见的。 以下就是一些可能的情况。 冷启动问题(不常见) 所谓冷启动,就是机器可能刚刚启动,里面的东西都是冷的,比如缓存、热点代码等等。问题中没说什么时候扛不住的,那么有可能在应用刚启动的时候扛不住了。这时候有这么几种常见的情况了。 缓存未预热 生产环境启动时缓存为空,那么就会有大量请求穿透到数据库,导致DB负载激增,而且DB的RT也要比缓存长。而压测环境可能已预加载数据,并没有暴露这个问题。 ✅如何在Spring启动过程中做缓存预热 JIT编译延迟 Java应用冷启动时,JIT编译器尚未优化热点代码,初始阶段吞吐量低。压测持续运行后JIT优化生效,但生产环境刚上线时性能未达峰值。 ✅Load飙高问题排查过程 MQ消费延迟 生产环境可能存在历史消息堆积(如Kafka未消费消息),消费者启动后需处理积压消息,占用大量资源,导致业务接口资源不足。 这种情况并不太常见,或者说不是本身不常见,是和压测有关的不常见,一般如果做好优雅上下线了,都会可以很好地解决这个问题,还有就是如果在刚启动的时候,RT比较高、Load或者CPU比较高,可以考虑这个问题。 定时任务干扰(常见) 资源抢占 生产环境定时任务(如报表生成、数据归档)可能在高峰期运行,消耗大量CPU、IO或数据库连接,导致业务接口响应延迟。 锁竞争 定时任务涉及批量数据操作(如全表更新),可能引发数据库锁竞争,阻塞业务SQL执行。 未进行全链路压测(很常见) 压测的时候可能只覆盖了单个服务,未模拟依赖链路的真实负载(如支付、风控服务)。生产环境中,下游服务性能瓶颈(如第三方API限速)拖累整体性能。 ✅什么是全链路压测? 外部系统影响(常见) 第三方服务降级 生产环境依赖的外部服务(如短信网关、支付接口)存在限流、高延迟或故障,触发熔断机制,导致业务线程阻塞。 慢SQL与数据问题(很常见) 为啥压测的时候没有慢SQL呢。没有数据问题呢?因为压测可能是之前进行的,而线上的数据是不断地变化的。随着时间的迁移,就可能出现问题了。 数据倾斜 生产环境存在热点数据(如某大V用户被频繁访问),导致数据库单分片负载过高,或缓存频繁失效。 索引失效 生产数据量增长或查询条件分布变化,导致原本有效的索引失效,引发全表扫描。 ✅为什么MySQL会选错索引,如何解决? 数据隔离差异 压测环境使用隔离的测试数据,有的时候数据都是我们自己造的,一般造出来的数据都比较工整,而而生产环境的数据不仅规模更大、而且也要更加复杂的得多。所以有些问题并不一定能暴露的出来。 压测环境偏差(常见) 硬件/配置差异 压测环境使用更高配服务器(如CPU核数、内存)、独立数据库实例,而生产环境为共享集群或容器化部署(资源受K8s限制)。 网络拓扑差异 生产环境存在跨机房调用、公网传输(如OSS存储),而压测环境为内网低延迟链路。 其他接口QPS干扰(常见) 这个和前面那个定时任务干扰差不多的情况。压测的时候一般选择业务低峰期,只针对受压接口进行压测,而其他接口可能QPS并不高。但实际生产环境中,可能并不一定,题目说300QPS,没说是单接口还是整体。有可能虽然单接口可能才300,但是多接口加一起可能就高的多大了。 基础设施问题(常见) 压测的时候和真实的生产环境中,基础设置可能有一定的差异。比如MQ、数据库、Redis等等,都有可能,他们的线程池大小、CPU情况,内存情况,都是有影响的。 而且有些时候,这些中间件是共用的,可能你的QPS并不高,但是其他系统可能很高,占用了更多的中间件资源,那么其他系统就可能被拖垮了。 还有就是线上系统,可能有很多其他的开销,比如ELK日志采集,SkyWalking的监控,都会占用一定的资源的。

March 22, 2026 · 1 min · santu

留言给博主