一、@Autowired 注入解决 每次创建新对象、内存暴涨、性能差
Spring 管理的 Bean 默认都是全局唯一一个的单例
**以前:**每次请求都 new ObjectMapper ()→ 1000 个请求 = 1000 个对象→ 内存暴涨、GC 频繁、性能差、并发不安全
现在:@Autowired 直接注入 Spring 创建好的单例→ 整个项目永远只有 1 个 ObjectMapper→ 所有请求共用这一个→ 不占额外内存、不重复创建、性能极高、并发安全
总结:@Autowired = 拿全局唯一对象new = 每次都造新对象
二、连接池解决OkHttp 并发崩溃问题
**问题原因:**无连接池,频繁创建销毁连接,高并发下直接卡死。
java
private final OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 连接最多等30秒
.readTimeout(120, TimeUnit.SECONDS) // 读数据最多等120秒
.writeTimeout(30, TimeUnit.SECONDS) // 发数据最多等30秒
.connectionPool(new ConnectionPool(10, 5, TimeUnit.MINUTES)) // 连接池
.build();
连接池
**以前:**每次请求都新建连接 → 用完关闭
**现在:**建立连接后不扔,放池子里复用→ 高并发不卡顿、不崩溃、速度飞快
超时时间 : 防止 AI 响应太慢把接口卡死**,**到时间自动断开,不卡死服务
最大空闲连接数 = 10 连接存活时间 = 5 分钟
总结:给 AI 请求加了 "高速通道 + 连接复用 + 防卡死"高并发必备
三、同步架构
bash
主线程 → 调用AI → 等待10秒 → AI返回 → 更新数据库 → 返回前端
整个 10 秒,主线程完全卡死
100 人同时访问 → 100 个线程卡死
服务器线程耗尽 → 服务崩溃
四、异步 + 后端自旋架构
bash
主线程:
1. 开启异步子线程 → 去调用AI(主线程不管它)
2. 主线程只做一件事:**每隔50ms查一下数据库**
3. 查到完成 → 返回前端
主线程虽然在等待,但它不阻塞任何系统资源
- 它不占用 AI 连接
- 它不占用数据库连接
- 它不阻塞任何外部服务
- 它只是空循环 + 极轻量查询
- 每次查询耗时 < 1ms
同步:主线程在等 IO、等网络、等 AI → 卡死资源
异步:主线程只等数据库状态,每次查询 1ms,完全不耗资源AI 任务依然在异步线程里高效执行
五、同步模式
流程:
- 用户请求进来,Tomcat 主线程(业务工作线程) 接手
- 主线程直接调用 Coze 大模型接口
- 卡死 5~15 秒 一动不动,全程占用这个 Tomcat 工作线程
- AI 返回→更新数据库→最后响应前端
关键致命点:
- Tomcat 工作线程池数量有限(默认就几十条)
- 一条 AI 请求 = 永久占用 1 条核心业务线程 10 秒 +
- 并发一高:线程全部被 AI 卡死 → 新请求排队、超时、服务雪崩
这就是并发低的根源:核心业务线程被慢 IO 锁死
六、纯异步模式@Async 子线程干活
流程:
- Tomcat 主线程 接收请求、保存初始消息
- 开启独立异步子线程去调用 AI、跑耗时逻辑
- 主线程直接释放、立刻归还线程池,去接待下一个用户
- 子线程慢慢跑 AI,跑完自己更新数据库
优势:
- 耗时、阻塞、慢 IO 全部丢给异步线程池
- Tomcat 核心业务线程秒释放,无限接新请求
- 两套线程池分工:
- Tomcat 线程:只处理极速短逻辑
- Async 异步线程:专门扛慢接口、长耗时任务
七、异步 + 主线程轻量自旋
流程:
- Tomcat 主线程:存初始消息 → 开启异步子线程跑 AI
- 主线程不销毁,每隔 50ms 查一次数据库,极轻量
- AI 跑完、状态变更,主线程立刻返回结果
重点回答你:会不会退化同步?
会轻微占用主线程,但和「同步阻塞 AI」完全不是一个量级:
- 同步:线程卡在网络 IO 等待,重量级阻塞,全程卡死
- 自旋:线程只是
sleep(50)+ 单条数据库简单查询
sleep时CPU 不占用、挂起休眠- 单次 DB 查询极快,毫秒级结束
- 真正耗时的网络请求、大模型解析、流处理 ,依然全部在异步子线程
八、主线程 VS 异步子线程 核心区别
1. 线程池不一样
主线程:Tomcat 容器核心业务线程池,容量小、不能堵
子线程:自定义 Async 线程池,专门设计用来扛长耗时任务,容量可以调大
2.阻塞的内容不一样
主线程同步:阻塞在外网 HTTP 长连接、大模型 IO(最重)
异步子线程:专门承接这类重型阻塞
自旋主线程:只阻塞在短暂休眠 + 轻量 DB 查询(最轻)
3.职责拆分
主线程:负责快速接收、快速响应、流量入口
子线程:负责耗时计算、第三方接口、慢任务
九、解答你的终极疑问
疑问 1:都有线程在干活,凭什么异步并发更高?
- 同步:稀缺的核心业务线程 被慢任务占死
- 异步:廉价扩容的异步线程 扛慢任务,核心线程自由
不是 "没人干活",是干活的人换了一批、分工合理了
疑问 2:自旋等待,主线程不还是被占用了吗?
是占用,但属于低资源占用:
- 大部分时间在
Thread.sleep,CPU 几乎 0 消耗 - 没有占用外网连接、没有阻塞 IO、没有卡死第三方请求
- 对比直接卡 10 秒 AI 网络阻塞,压力下降 90% 以上
疑问 3:资源都在消耗,高并发优势在哪?
高并发的本质:不让「有限的入口线程」被慢任务锁死
- 同步:10 个慢请求 = 10 个入口线程报废,系统直接堵死
- 异步 + 自旋:10 个慢请求 = 10 个子线程扛压,入口线程还能继续接几百个新请求
十、极简总结
-
主线程为 Tomcat 核心业务线程,数量有限,负责快速处理请求,不能被长耗时第三方接口阻塞;异步子线程由独立线程池管理,专门承载大模型调用等慢任务,实现职责拆分。
-
同步方案中,主线程全程阻塞在 AI 网络请求,会快速耗尽业务线程池,导致并发能力极低。
-
异步方案将耗时逻辑下放至子线程,核心主线程快速释放,大幅提升系统吞吐与并发承载能力。
-
后期为解决前端转圈,增加主线程轻量自旋等待:线程大部分时间休眠,仅做轻量数据库查询,没有重型 IO 阻塞,不会退化為同步性能,既保留异步高并发架构,又实现同步交互体验。
-
高并发的核心不是不用线程,而是稀缺入口线程不阻塞、慢任务隔离到独立线程池。
总结:异步子线程执行耗时严重的 AI 网络请求,Tomcat主线程负责轻量单条库表轮询任务状态,该方案不会退化为同步模式,核心耗时压力依旧隔离在异步线程池,既保留异步高并发优势,又无需改造前端,解决了页面长时间转圈的问题。