☰
基于Spring Cloud Alibaba与JDK 21的企业级AI应用底座架构设计与实践
2026/10/2 7:11:33 网站建设 项目流程

1. 从一堆微服务开源项目里,我为什么盯上了 QuickBlue

这两年但凡在技术社区里泡过的人,应该都有一种感觉:微服务相关的开源项目多到看不过来。若依微服务Plus、Spring Cloud Alibaba 全家桶、各种电商中台脚手架,随便一搜就是几十个 star 过千的仓库。但真到企业里要落地一个“AI 应用底座”的时候,你会发现能直接拿来用的东西其实没几个——要么是纯业务脚手架,跟 AI 能力完全不搭边;要么是套了个大模型 API 的壳,底层架构经不起推敲。

QuickBlue 就是在这个背景下进入我视野的。简单说,它是一个面向企业级场景的AI 应用底座,底层基于 Spring Cloud 微服务体系搭建,同时把 AI 能力的接入、编排、治理做成了平台化的东西。你可以把它理解成一个“中间层”:往下对接各种模型服务、向量库、工具链,往上给业务系统提供统一的 AI 调用入口和治理能力。它解决的核心问题不是“怎么调一次大模型接口”,而是“当公司有二十个业务线都想用 AI 的时候,怎么统一管、统一控、统一迭代”。

这篇文章适合两类人看。一类是正在做技术选型的架构师或者技术负责人,手里有 AI 落地需求,但不想每个业务团队各搞一套;另一类是对微服务 + AI 结合感兴趣的开发者,想看看一个真实的“AI 应用底座”到底长什么样、里面有哪些坑。我会尽量把设计思路、关键实现、实操细节和踩过的坑都摊开讲,不玩虚的。

2. 拆解“AI 应用底座”这个说法,它到底要解决什么问题

2.1 没有底座的时候,企业 AI 落地是什么状态

我先描述一个特别典型的场景。某公司有三个业务团队同时要做 AI 功能:客服团队要做智能问答,运营团队要做文案生成,数据团队要做报表解读。如果没有统一底座,会发生什么?

客服团队自己申请了一个模型账号,写了一套调用代码,做了个简单的重试逻辑。运营团队用了另一个模型,因为觉得那个写文案效果更好,又写了一套。数据团队干脆在 Python 脚本里直接调,连服务化都没做。三个月后问题全来了:模型账号散落在各个人手里,费用没法归集;每个团队都在重复实现限流、重试、日志、鉴权;想换个模型,得改三个地方;出了线上问题,排查链路长得离谱。

这就是“没有底座”的典型症状。它不是某个技术点没做好,而是能力没有收敛。每个团队都在解决同样的问题,但解决方案互不兼容,最后形成一堆孤岛。

2.2 底座要收敛的四个核心能力

一个合格的 AI 应用底座,我认为至少要收敛四类能力。

第一类是接入收敛。不管底层用的是哪家模型、哪种向量库、哪个工具平台,业务侧只面对一套统一的接口。这层收敛的价值在于,模型可以换,业务代码不用动。

第二类是治理收敛。限流、熔断、降级、重试、超时、鉴权、审计,这些在传统微服务里已经玩得很熟的东西,在 AI 场景下同样需要,而且因为大模型调用又慢又贵,治理的重要性反而更高。

第三类是编排收敛。一个真实的 AI 应用往往不是“调一次模型”就完事,而是“检索 → 组装提示词 → 调模型 → 解析结果 → 调工具 → 再调模型”这样一条链路。这条链路如果每个团队自己写,维护成本极高。

第四类是观测收敛。Token 消耗、调用延迟、成功率、缓存命中率,这些指标必须统一采集、统一展示,否则你根本不知道钱花在哪、瓶颈在哪。

QuickBlue 的设计基本就是围绕这四个“收敛”展开的。下面我逐个拆。

2.3 为什么是微服务,而不是单体或者 Serverless

有人可能会问,一个 AI 底座,为什么非要用微服务?单体不是更简单吗?

这个问题我认真想过。如果你的公司只有一两个 AI 应用,单体确实够了。但底座的定位决定了它要服务多个业务线,而不同业务线的诉求差异很大:有的要求低延迟,有的要求高并发,有的要求强审计。这种差异用单体很难同时满足,因为一个模块的改动可能影响所有人。

微服务的好处在这里就体现出来了:接入层、编排层、治理层、观测层可以独立部署、独立扩容、独立迭代。比如编排层因为要处理复杂链路,资源消耗大,可以单独多给几个实例;接入层相对轻量,可以少给一点。这种弹性是单体给不了的。

至于 Serverless,它在 AI 场景下有个硬伤:大模型调用是长耗时操作,冷启动和超时限制会让体验很糟糕。所以底座这种常驻型的基础设施,微服务是更稳妥的选择。

3. QuickBlue 的整体架构与核心技术选型

3.1 分层架构:从接入到编排到治理

QuickBlue 的架构我习惯分成四层来看。

最底下是基础设施层,包括注册中心、配置中心、网关、消息队列这些微服务的标准件。这一层用的是 Spring Cloud 生态里比较成熟的组件,注册中心选的是 Nacos,配置中心也是 Nacos,网关用的是 Spring Cloud Gateway。

往上是能力接入层,负责对接各种外部能力:大模型服务、向量数据库、工具平台、缓存。这一层的关键设计是“适配器模式”,每种外部能力都有一个对应的适配器,业务侧不直接依赖具体实现。

再往上是编排与治理层,这是整个底座的核心。编排负责把多个能力串成一条链路,治理负责在这条链路上加限流、熔断、重试、缓存。这一层用到了 Spring Cloud Sentinel 做流量治理,用 Redis 集群做分布式缓存和限流数据存储。

最上面是应用接入层,对外暴露统一的 API,业务系统通过这一层来使用底座的 AI 能力。这一层还承担了鉴权、审计、计费等职责。

3.2 JDK 21 带来的实际收益

QuickBlue 明确要求 JDK 21,这个选择不是赶时髦。JDK 21 是 LTS 版本,里面有几个特性对 AI 底座特别有用。

第一个是虚拟线程。AI 场景下大量操作是 IO 密集型的——等模型返回、等向量库查询、等工具调用。传统线程模型下,一个请求占一个线程,并发一高线程池就爆了。虚拟线程让每个请求的线程开销大幅降低,同样的硬件能扛更高的并发。我实测过,在模型调用这种长耗时场景下,虚拟线程带来的吞吐提升相当明显。

第二个是模式匹配和记录类。编排层要处理各种结构化的请求和响应,用记录类定义数据结构,配合模式匹配做解析,代码比传统的 getter/setter 清爽太多,出错概率也低。

第三个是分代 ZGC。底座是常驻服务,对 GC 停顿敏感。分代 ZGC 在 JDK 21 里已经比较成熟,停顿时间控制在毫秒级,对延迟敏感的 AI 调用链路很友好。

提示:如果你的团队还在 JDK 8 或 11,升级到 21 之前一定要做充分的兼容性测试。虚拟线程虽然好用,但和某些依赖 ThreadLocal 的老库配合时会有坑,比如一些老版本的连接池。

3.3 Spring Cloud Alibaba 的现状与选型考量

这里必须说一个很多人关心的问题:Spring Cloud Alibaba 的维护状态。网上一直有“停更了”的说法,实际情况是核心组件(Nacos、Sentinel、Seata)仍在持续更新,只是节奏和以前不太一样。对于企业级项目来说,选型时更该关注的是组件是否稳定、社区是否活跃、出问题能不能找到人。

QuickBlue 选择 Spring Cloud Alibaba 体系,主要看中三点:Nacos 同时做注册和配置,省了一套组件;Sentinel 的流量治理能力开箱即用,规则可以动态下发;整套体系在国内的文档和案例足够多,团队上手成本低。

如果你的团队更倾向原生 Spring Cloud,也完全可行,只是注册配置中心可能要换成 Eureka + Config 或者 Consul,治理组件要自己搭。选型没有绝对对错,关键是和团队的技术栈匹配。

4. 核心模块的实操细节与关键实现

4.1 统一接入层:怎么做到换模型不改业务代码

接入层的核心是定义一套稳定的内部接口,把外部模型的差异屏蔽掉。我举个具体的例子。

假设业务侧要调用一个“对话补全”能力,它面对的是这样一个接口:

public interface ChatCompletionService { ChatCompletionResponse complete(ChatCompletionRequest request); }

请求对象里包含消息列表、模型标识、温度参数这些通用字段。业务侧只管构造这个请求,不关心底层是哪个模型。

底层怎么实现呢?每个模型对应一个适配器,适配器实现同一个接口:

@Component public class ModelAAdapter implements ChatCompletionService { @Override public ChatCompletionResponse complete(ChatCompletionRequest request) { // 把内部请求转换成 ModelA 的 API 格式 // 调用 ModelA // 把响应转换回内部格式 } }

路由逻辑放在一个工厂或者策略类里,根据请求里的模型标识选择对应的适配器。这样新增一个模型,只需要加一个适配器,业务代码一行不用改。

注意:适配器里一定要做好异常转换。不同模型返回的错误码和错误结构千差万别,如果直接把原始异常抛给业务侧,业务侧就得处理各种奇怪的错误类型。统一转换成底座自己的异常体系,业务侧才好写代码。

4.2 编排引擎:把多次调用串成一条链路

编排是底座里最复杂的部分。我拿一个 RAG(检索增强生成)场景举例,一条完整的链路是这样的:

  1. 接收用户问题
  2. 把问题向量化
  3. 去向量库检索相关文档
  4. 把检索结果和问题组装成提示词
  5. 调用大模型生成回答
  6. 解析回答,判断是否需要调用工具
  7. 如果需要,调用工具并把结果再喂给模型
  8. 返回最终结果

这条链路如果让业务侧自己写,代码会非常臃肿。QuickBlue 的做法是把每个步骤抽象成一个“节点”,链路用配置或者 DSL 来描述。

chain: name: rag-qa nodes: - type: embed input: ${question} output: ${vector} - type: retrieve input: ${vector} output: ${docs} - type: prompt template: rag-template input: [${question}, ${docs}] output: ${prompt} - type: llm input: ${prompt} output: ${answer}

这种声明式编排的好处是,链路调整不用改代码,改配置就行。而且每个节点的执行情况可以被统一观测,哪个节点慢、哪个节点失败,一目了然。

4.3 治理层:Sentinel 在 AI 场景下的特殊配置

Sentinel 默认的限流熔断策略是为普通 HTTP 接口设计的,直接套到 AI 场景会有问题。最大的问题是大模型调用耗时太长,一个请求可能跑十几秒甚至几十秒,如果用默认的 RT(响应时间)阈值来熔断,几乎每次都会触发。

我的做法是调整熔断策略,把慢调用比例熔断的阈值放宽,同时把统计窗口拉长。具体配置大概是这样的:

DegradeRule rule = new DegradeRule(); rule.setResource("llm-invoke"); rule.setGrade(RuleConstant.DEGRADE_GRADE_RT); rule.setCount(30000); // 30秒才算慢调用 rule.setTimeWindow(60); // 熔断后60秒再尝试 rule.setMinRequestAmount(10); // 至少10个请求才统计 rule.setSlowRatioThreshold(0.5); // 慢调用比例超过50%才熔断

限流方面,AI 场景更该关注的是成本控制。可以按 Token 消耗来限流,而不是按请求数。这需要在调用后统计 Token 用量,然后反馈给限流器。Sentinel 本身不直接支持这种模式,需要自己扩展。

提示:Redis 集群做限流数据存储时,要注意集群模式下 Lua 脚本的 key 必须落在同一个 slot。如果限流的 key 设计得不好,跨 slot 操作会直接报错。我一般会在 key 前面加 hash tag,强制同一类限流数据落到同一个节点。

4.4 观测层:Token 消耗和延迟怎么采集

观测这块,底座需要采集的指标比普通微服务多。除了常规的 QPS、RT、错误率,还要采集 Token 消耗、缓存命中率、模型调用分布这些 AI 特有的指标。

采集方式上,我推荐用 Micrometer 做指标抽象,底层对接 Prometheus。每个模型适配器在调用完成后,把 Token 用量、耗时、是否命中缓存这些数据打到指标里。这样在 Grafana 上就能看到按模型、按业务线、按时间维度的消耗情况。

这里有个细节:Token 用量的统计要区分输入和输出,因为很多模型对输入和输出的计费标准不一样。如果只统计总量,成本核算会不准。

5. 实操过程中踩过的坑与排查经验

5.1 微服务拆分粒度:拆太细反而拖慢开发

我见过一个团队,把 AI 底座拆成了十几个微服务:模型接入一个、向量检索一个、提示词管理一个、编排一个、治理一个、观测一个……结果开发效率极低,改一个功能要动三四个服务,联调成本高得吓人。

我的经验是,底座初期拆成三到五个服务就够了:接入服务、编排服务、治理服务、观测服务。等业务量真的上来了,再把其中压力大的部分单独拆出去。过早拆分是微服务落地最常见的坑,没有之一。

5.2 配置中心的坑:动态刷新不是万能的

Nacos 的动态配置刷新很好用,但不是所有配置都能动态生效。比如数据源连接池的配置,改了之后需要重建连接池,光靠@RefreshScope是不够的。还有一些和线程池相关的配置,动态调整后需要重新初始化线程池。

我的做法是把配置分成两类:一类是真正需要动态调整的(比如限流阈值、模型权重),走 Nacos 动态刷新;另一类是启动时确定的(比如数据源、线程池核心参数),走本地配置或者启动参数。不要为了动态而动态。

5.3 常见问题速查表

问题现象可能原因排查方向
模型调用频繁超时网络抖动或模型侧限流检查底座到模型服务的网络,查看模型侧返回的错误码
限流规则不生效Sentinel 规则未推送或资源名不匹配检查 Nacos 里的规则配置,确认资源名和代码里一致
Token 统计不准流式响应未正确累计检查流式调用的回调逻辑,确认每个 chunk 都被统计
缓存命中率低缓存 key 设计不合理检查 key 是否包含随机因子,确认相似请求能命中同一 key
虚拟线程下 ThreadLocal 失效老库依赖 ThreadLocal改用 ScopedValue 或显式传参

5.4 一个真实的排查案例

有次线上反馈说某个业务线的 AI 调用成功率突然掉到 60%。我先看观测面板,发现失败集中在某个模型上,其他模型正常。再看错误日志,大量超时。

第一反应是模型侧的问题,但联系模型服务方后对方说他们那边正常。于是我抓了一次完整的调用链路,发现请求在底座内部就卡了很久,根本没到模型侧。继续往下查,发现是编排层的一个节点在做向量检索时,Redis 集群有个节点响应特别慢,导致整个链路被拖住。

最后定位到是那个 Redis 节点的内存快满了,触发了频繁的淘汰。扩容之后问题解决。这个案例的教训是:AI 链路的瓶颈不一定在模型侧,底座内部的每个环节都可能是短板。观测要覆盖全链路,不能只盯着模型调用。

6. 这套底座适合什么样的团队,以及后续怎么扩展

QuickBlue 这种 AI 应用底座,最适合的是有多个业务线、有统一治理诉求、有一定微服务基础的团队。如果你的公司只有一个 AI 应用,或者团队里没人懂微服务,那上这套东西反而是负担,不如先用单体把业务跑通。

后续扩展上,我觉得有几个方向值得做。一是多模态能力的接入,现在底座主要处理文本,图片、音频、视频的接入可以复用同样的适配器模式。二是成本优化,比如做模型路由,简单问题走便宜的小模型,复杂问题才走大模型。三是评测体系,把 AI 应用的效果量化,这样才能持续迭代。

我自己在实际操作中的体会是,底座的价值不在于技术多先进,而在于把重复的事情收敛掉。当业务团队不再需要关心限流怎么写、日志怎么打、模型怎么换的时候,他们才能真正把精力放在业务创新上。这才是底座存在的意义。

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

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

立即咨询