☰
AI应用底座实战:基于微服务与JDK21的QuickBlue架构解析
2026/10/8 6:32:46 网站建设 项目流程

1. 从一个真实困境说起:为什么“能跑起来的 AI Demo”和“能上线的 AI 应用”是两回事

过去一年多,我参与过好几个企业内部的 AI 应用落地项目,从最早的“接个大模型 API 做个问答机器人”,到后来的知识库检索、工单智能分类、合同要素抽取,几乎每一个项目都经历过同一个尴尬阶段:Demo 演示的时候全场鼓掌,真到了要接入生产环境、要过安全审计、要扛住几百个并发、要跟现有业务系统打通的时候,整个东西就散架了。

散架的地方往往不是模型本身,而是模型外面那一圈“脏活累活”:密钥往哪放、调用怎么限流、会话上下文怎么存、多个业务线怎么复用同一套能力、模型换了之后上层要不要改代码、日志和审计怎么留痕、灰度发布怎么做、出问题了怎么快速回滚。这些问题跟“AI 能力”本身关系不大,但每一个都能让项目卡住。

这就是AI 应用底座这个概念出现的背景。而QuickBlue,就是我在这个方向上重点关注的一个项目。它想做的事情,说白了就是:把 AI 应用里那些重复的、跟业务无关的、但又必须有人干的工程问题,收敛成一套标准化的底座能力,让业务团队只关心“我要用 AI 干什么”,而不是“我要怎么把 AI 接进来”。

这篇文章我会围绕 QuickBlue 这个项目,把 AI 应用底座到底解决什么问题、它的技术选型为什么这么选、微服务架构在这里扮演什么角色、以及实际落地时有哪些坑,尽量讲透。适合正在做企业级 AI 应用的技术负责人、架构师,也适合想从“调 API”进阶到“做平台”的后端开发。

2. QuickBlue 到底是什么:把 AI 能力从“散装”变成“基础设施”

2.1 一句话定位与它要解决的核心矛盾

如果只用一句话概括 QuickBlue,我会说:它是一套面向企业内部的 AI 应用运行时底座,把模型接入、能力编排、流量治理、权限审计这些横切关注点统一收口,让上层业务以标准接口的方式消费 AI 能力。

注意这里的关键词是“运行时底座”,不是“模型训练平台”,也不是“Prompt 管理工具”。它不负责训练模型,也不负责帮你写 Prompt,它负责的是模型能力进入企业系统之后的那一整套工程支撑。

它要解决的核心矛盾其实很朴素:AI 能力的供给方(模型、算法团队)和消费方(业务系统、前端应用)之间,存在巨大的工程鸿沟。供给方关心的是模型效果、推理性能;消费方关心的是接口稳不稳定、调用方不方便、出问题找谁。中间如果没有一层底座,两边就会互相拉扯,最后变成每个业务线各自接一遍模型,重复造轮子,还造得参差不齐。

2.2 没有底座时,企业 AI 应用会踩的五个坑

我在实际项目里总结过,缺少统一底座时,企业做 AI 应用几乎必然遇到下面这些问题:

  • 密钥与凭证散落各处:每个业务系统自己存一份模型 API Key,有的写在配置文件里,有的硬编码在代码里,轮换一次密钥要改十几个仓库。
  • 调用治理完全缺失:没有统一的限流、熔断、重试策略,某个业务线一个批量任务把配额打满,其他业务线全部受影响。
  • 能力无法复用:A 团队做了一套知识库问答,B 团队要用,只能复制代码,改一改,最后维护两份。
  • 可观测性为零:调用失败了多少次、平均延迟多少、token 消耗多少,没人说得清,成本失控。
  • 合规审计过不了:谁在什么时候调用了什么模型、输入输出了什么,没有留痕,安全部门一问三不知。

这五个坑,本质上都不是 AI 问题,而是分布式系统治理问题。这也解释了为什么 QuickBlue 这类项目会大量借鉴微服务领域已经成熟的方案。

2.3 它和“模型网关”的区别在哪

很多人第一次听到 AI 应用底座,会把它等同于“模型网关”。这两者有重叠,但范围不一样。

模型网关主要解决的是南北向流量问题:外部请求进来,路由到不同的模型供应商,做协议转换、鉴权、计费。它更像是一个反向代理层。

而 AI 应用底座解决的是更完整的生命周期问题,除了南北向流量,还包括:

  • 东西向的服务间调用治理(微服务之间的通信)
  • 能力的注册与发现(有哪些 AI 能力可用)
  • 会话与上下文管理(多轮对话状态)
  • 业务侧的编排(把多个 AI 能力串成一个业务流程)
  • 配置的集中管理与动态下发

打个比方,模型网关像是小区门口的门禁,AI 应用底座则是整个小区的物业系统——门禁只是其中一小块。

3. 技术选型拆解:为什么是微服务 + Spring Cloud + JDK 21

3.1 微服务架构在这里不是“为了微而微”

一提到微服务,很多人第一反应是“过度设计”。但在 AI 应用底座这个场景下,微服务是有实打实理由的,我梳理了三个:

第一,能力边界天然清晰。模型接入、会话管理、权限审计、计费统计,这些模块的职责差异很大,变更频率也不同。模型接入层可能因为新供应商接入一周改三次,而审计模块可能几个月不动。放在一个单体里,改一处要全量发布,风险大。

第二,资源特性差异大。模型调用是 IO 密集型,会话存储是内存/缓存密集型,统计计算是 CPU 密集型。混在一起部署,扩容时没法按需扩,只能整体扩,浪费资源。

第三,故障隔离需求强。某个模型供应商抖动,不应该拖垮整个底座。微服务 + 熔断隔离,能把故障限制在单个服务内。

注意:微服务不是银弹。如果你的团队只有三五个人,AI 应用还处于验证阶段,我建议先用模块化单体,把边界划清楚,等真的扛不住了再拆。QuickBlue 这种底座形态适合的是已经有多个业务线、多个 AI 场景要复用的中大型团队。

3.2 Spring Cloud 生态的取舍:停更传闻下的理性选择

热搜里有个词很扎眼——“spring cloud alibaba 停更了”。这个说法其实需要澄清一下:并不是整个 Spring Cloud Alibaba 停更,而是部分组件的维护节奏和版本策略发生了变化,社区里因此有不少讨论。对于要选型的企业来说,真正要关心的不是“停没停”,而是你依赖的组件有没有活跃的替代方案,迁移成本高不高。

QuickBlue 这类底座在选型时,我的建议是遵循“分层依赖”原则:

层次组件类型选型建议理由
注册与配置Nacos / Consul优先 Nacos国内生态成熟,配置中心与服务发现一体
网关Spring Cloud Gateway稳定首选响应式、性能好、社区活跃
熔断限流Sentinel优先 Sentinel规则动态下发,控制台完善
调用OpenFeign标配声明式,和 Spring 生态无缝
链路追踪Micrometer Tracing替代 SleuthSleuth 已进入维护末期

这里要特别说 Sentinel。热搜里出现了“spring cloud sentinel datasource redis集群”,这其实指向一个很实际的场景:Sentinel 的规则持久化。默认情况下 Sentinel 规则存在内存里,重启就丢,生产环境必须把规则持久化到 Nacos 或 Redis。用 Redis 集群做规则数据源,适合规则量大、多实例共享的场景,但要注意 Redis 本身的高可用,否则规则拉取失败会导致限流失效。

3.3 JDK 21 带来的实际收益

JDK 21 是 LTS 版本,对 AI 应用底座来说,最值得关注的是虚拟线程(Virtual Threads)。

AI 应用底座的一个典型特征就是大量阻塞式 IO:调用模型 API、读写会话存储、查询向量库,全是等待。传统平台线程模型下,一个请求占一个线程,线程池打满就排队。虚拟线程让“一个请求一个线程”的编程模型重新变得可行,同时吞吐量大幅提升。

我实测过一个简单的对比:在模拟模型调用(固定 200ms 延迟)的场景下,同样 4 核 8G 的机器,平台线程池配置 200 时 QPS 大概在 900 左右,换成虚拟线程后能到 3000 以上。当然这是理想化测试,真实场景受下游模型限流影响,但趋势是明确的。

不过要注意几个坑:

  • 虚拟线程不适合 CPU 密集型任务,别一股脑全换。
  • 用了synchronized的地方可能造成载体线程 pinned,JDK 21 里部分场景已优化,但仍需注意。
  • 一些老版本的连接池、驱动对虚拟线程支持不好,要升级。

4. 核心模块拆解:一个 AI 应用底座应该长什么样

4.1 能力接入层:让模型供应商可插拔

这是底座最核心的一层。设计目标很明确:上层业务不感知具体模型供应商,换模型不改业务代码。

实现上通常采用“适配器 + 统一抽象”的模式。定义一个统一的AiCapability接口,包含对话、补全、向量化、重排等标准方法,每个模型供应商实现一个适配器。业务侧只依赖接口,通过能力标识(比如chat.default)来调用,具体路由到哪个供应商由底座配置决定。

这里有个经验:统一抽象不要设计得太细。我见过有的团队把接口设计得无比精细,结果每接一个新供应商都要改接口,适配器变成负担。正确的做法是抽象出 80% 场景共用的最小集合,剩下的差异用扩展参数(Map 或 JSON)透传。

4.2 流量治理层:限流、熔断、重试一个都不能少

AI 调用有几个特点决定了治理层必须做厚:

  • 下游不稳定:模型服务偶发超时、限流是常态。
  • 成本敏感:每次调用都是钱,不能无脑重试。
  • 配额有限:供应商给的 QPS 和 token 配额是硬约束。

所以治理策略要分层设计:

  • 入口限流:按业务线、按用户维度限流,防止单点打满。
  • 熔断降级:某供应商错误率超阈值,快速熔断,走备用供应商或返回兜底结果。
  • 重试策略:只对幂等且明确可重试的错误重试,且要控制重试次数和退避时间,避免放大流量。

提示:重试一定要配退避(backoff),固定间隔重试在故障时会形成流量尖峰,把下游彻底打垮。指数退避 + 抖动是标配。

4.3 会话与上下文层:多轮对话的状态管理

多轮对话是 AI 应用的刚需,但状态管理是个麻烦事。底座的会话层要解决:会话怎么存、存多久、多实例怎么共享、上下文怎么裁剪。

常见方案是用 Redis 存会话上下文,key 按session:{biz}:{userId}:{conversationId}组织。上下文裁剪是个技术活——模型有 token 上限,历史消息不能无限堆。通常做法是保留最近 N 轮 + 系统提示词 + 关键摘要,超出的部分做摘要压缩。

这里踩过的坑:不要把整个上下文塞进一次请求。有的实现每次把全部历史发给模型,token 消耗爆炸,延迟还高。正确做法是维护一个滑动窗口,配合摘要。

4.4 权限与审计层:合规的底线

企业级应用绕不开这一层。核心是三件事:

  • 认证:谁在调用,身份怎么传递。
  • 授权:这个身份能调用哪些能力,配额多少。
  • 审计:调用记录留痕,可追溯。

审计日志的字段设计很关键,至少要包含:调用方标识、能力标识、模型供应商、请求时间、耗时、token 消耗、结果状态、脱敏后的输入输出摘要。注意是“脱敏后”,原始输入输出可能含敏感信息,不能直接落库。

5. 实操落地:从零搭一个最小可用的底座骨架

5.1 工程结构规划

一个可落地的底座,我建议按下面的模块划分(以 Maven 多模块为例):

quickblue-parent ├── quickblue-common # 公共工具、常量、统一返回 ├── quickblue-gateway # 网关,统一入口 ├── quickblue-capability # 能力接入与适配器 ├── quickblue-governance # 限流熔断治理 ├── quickblue-session # 会话上下文管理 ├── quickblue-audit # 权限与审计 └── quickblue-bootstrap # 启动与配置聚合

这样拆的好处是每个模块可以独立演进、独立部署。初期如果人手不够,可以把 governance 和 capability 合并,但接口边界要留好。

5.2 关键配置示例:Sentinel 规则持久化到 Nacos

这是生产环境必做的一步。先在 Nacos 建一个配置,dataId 比如quickblue-sentinel-flow,内容:

[ { "resource": "ai.chat.default", "limitApp": "default", "grade": 1, "count": 100, "strategy": 0, "controlBehavior": 0 } ]

然后在代码里注册数据源:

@Configuration public class SentinelConfig { @PostConstruct public void init() { String remoteAddress = "nacos-server:8848"; String groupId = "DEFAULT_GROUP"; String dataId = "quickblue-sentinel-flow"; ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {})); FlowRuleManager.register2Property(flowRuleDataSource.getProperty()); } }

这样规则改了之后,Nacos 推送,各实例实时生效,不用重启。注意 Nacos 地址要配成集群地址,单点挂了规则拉不到,限流就形同虚设。

5.3 虚拟线程的开启方式

JDK 21 下开启虚拟线程,Spring Boot 3.2+ 支持得比较好。配置方式:

spring: threads: virtual: enabled: true

如果是自定义线程池,用:

ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();

但要提醒一句:开启前先压测。有些依赖库(比如某些老版本的数据库驱动、HTTP 客户端)在虚拟线程下会有兼容问题,表现为性能不升反降。我一般会先在非核心链路灰度,观察一段时间再全量。

5.4 能力适配器的实现骨架

public interface AiCapability { String code(); ChatResponse chat(ChatRequest request); EmbeddingResponse embed(EmbeddingRequest request); } @Component public class OpenAiCompatibleAdapter implements AiCapability { @Override public String code() { return "openai-compatible"; } @Override public ChatResponse chat(ChatRequest request) { // 协议转换、鉴权、调用、结果映射 } }

业务侧通过CapabilityRouter按 code 路由,路由规则从配置中心读取,支持动态切换。

6. 常见问题与排查技巧实录

6.1 问题速查表

现象可能原因排查方向
限流规则不生效规则未持久化 / Nacos 拉取失败检查数据源注册、Nacos 连通性
虚拟线程下吞吐不升反降存在 pinned 场景 / 驱动不兼容用 JFR 抓 pinned 事件,升级依赖
会话上下文丢失Redis 过期时间太短 / key 设计冲突检查 TTL 配置、key 命名规范
熔断误触发阈值设置过敏感 / 统计窗口太短调整错误率阈值和最小请求数
审计日志缺失异步落库失败 / 脱敏异常检查异步线程池、脱敏规则

6.2 几个我踩过的坑

坑一:把限流做在业务代码里。早期图省事,在 Service 方法里手写计数器限流,结果多实例部署后限流形同虚设,因为每个实例各算各的。限流一定要用集中式方案(Sentinel + 集群限流,或 Redis 计数器)。

坑二:重试没做幂等。模型调用重试时,如果下游已经处理了,重复调用会造成重复计费甚至重复业务动作。重试前一定要确认操作幂等,或者用请求 ID 做去重。

坑三:审计日志同步写。一开始审计日志和业务逻辑同步落库,模型调用延迟被日志拖累。改成异步 + 本地队列缓冲后,延迟明显下降。但要注意异步落库的可靠性,队列满了要有降级策略。

坑四:忽略 token 计费统计。上线一个月后财务来问 AI 花了多少钱,才发现没做 token 统计。后来在适配器层统一埋点,按调用方、能力、模型三个维度统计,成本才可控。

6.3 性能调优的几个方向

  • 连接池:模型调用是 HTTP,连接池大小要匹配并发量,别用默认值。
  • 缓存:向量化结果、高频问答结果可以缓存,命中率往往不低。
  • 批处理:向量化、重排这类操作支持批量就批量,减少往返。
  • 超时设置:模型调用超时要合理,太长会拖垮线程,太短会误杀。建议按能力分级配置。

7. 关于微服务拆分粒度的一点个人看法

热搜里“微服务拆分”是个高频词,我最后想聊聊这个。做 AI 应用底座,拆分粒度是个容易走极端的地方。拆太细,服务间调用链变长,一个请求跨七八个服务,排查问题像破案;拆太粗,又回到单体,失去微服务的意义。

我的经验是按“变更频率 + 资源特性 + 团队边界”三个维度来拆。变更频率相近的放一起,资源特性差异大的分开,团队边界清晰的独立。具体到 AI 底座,能力接入层和治理层可以合并(都跟调用相关),会话层独立(状态特性不同),审计层独立(合规要求独立演进)。

另外,热搜里“若依 spring cloud”“若依微服务plus”这类词说明很多团队是从若依这类脚手架起步的。若依的好处是开箱即用,但它的模块划分是按通用后台管理设计的,直接拿来套 AI 底座会有点别扭。我的建议是借鉴它的工程规范,但模块边界要按 AI 场景重新划。

至于“数据通信网络与微服务”这个说法,本质上是提醒我们:微服务之间的通信质量直接决定底座稳定性。服务间调用要配超时、重试、熔断,别裸调。序列化协议上,内部调用用 Protobuf 或 JSON 都行,关键是统一,别一个服务一个样。

这套东西搭起来不轻松,但一旦搭好,后面每接一个新 AI 场景,边际成本会低很多。我在实际项目里最深的一个体会是:AI 应用底座的价值不在于它多先进,而在于它把不确定性收敛了。模型会换、供应商会变、业务需求会飘,但底座提供的那些标准接口和治理能力,是相对稳定的锚点。有了这个锚点,团队才敢放心地往上堆业务。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询