博思AI智能体系统架构解析:打造高并发、多模型协同的AI社交应用
在AI技术日新月异的今天,如何构建一个既能承载高并发用户,又能灵活集成多种大模型的社交应用,是开发者面临的一大挑战。本文将深入解析我主导开发的“博思AI智能体”系统架构,分享在技术选型、核心流程设计与性能优化上的实践与思考。
整个系统采用前后端分离架构,后端基于Spring Boot 3.1.6 (Java 17),前端则选用了React 18,并通过Redis、RabbitMQ和WebSocket等中间件,构建了一个稳定、高效且易于扩展的技术栈。
整体架构:五层设计,职责分明
为了清晰地划分系统边界,我将整个架构划分为五层,每一层都承担着明确的责任。
1. 用户层 (User Layer):由React 18构建的单页应用(SPA)组成。我引入了KeepAliveRoute机制,确保用户在切换页面时状态得以保留,提升了体验。同时,通过全局的ErrorBoundary捕获渲染异常,保证了应用的健壮性。
2. 接入层 (Access Layer):使用Nginx作为反向代理,统一处理外部请求。它不仅负责将流量分发到后端的两个应用实例(:8081, :8082),还配置了健康检查和故障转移策略,并集成了IP限流拦截器,有效抵御恶意请求。

3. 应用层 (Application Layer):这是系统的核心,由Spring Boot驱动。我在此层实现了JWT鉴权、内容安全审核以及核心的聊天与辩论业务逻辑。通过集成WebSocket和STOMP协议,实现了服务端与客户端的实时双向通信。
4. 数据层 (Data Layer):采用MySQL 8进行数据持久化,存储用户、消息、辩论记录等核心数据。Redis则扮演了双重角色:一方面用于会话跟踪和在线人数统计,另一方面作为AI回复结果的缓存,避免重复调用,节省成本。
5. AI层 (AI Layer):这是博思AI智能体的“大脑”。我接入了千问(Qwen)、DeepSeek和豆包(Doubao)三个主流大模型。它们能力互补,共同为用户提供高质量的对话和辩论服务。

核心流程:五步打造稳健的聊天体验
用户发送一个问题到收到AI回复,背后经历了一个精心设计的五步流程,确保了系统的稳定与高效。
1. 限流检查:请求首先到达IpRateLimitInterceptor。我采用了滑动窗口算法,对同一IP的短时高频请求进行拦截,防止系统被突发流量击垮。
2. 内容安全:通过ContentSafetyService调用阿里云内容安全API,对用户的提问进行敏感词检测。一旦命中,请求将被立即拒绝,从源头保障社区环境的健康。
3. 消息入库:安全合规的消息会被持久化到MySQL的messages表中,状态标记为queued。这一步保证了消息的可靠性,即使后续处理失败,消息也不会丢失。
4. 广播与入队:消息会通过WebSocket广播给所有在线用户,实现“群聊”的实时可见性。同时,消息被推送到RabbitMQ的chat.requests队列中,实现业务解耦,让耗时的AI处理异步进行。
5. AI处理与推送:后端的ChatProcessor作为消费者,从队列中获取消息,并并行调用千问、DeepSeek和豆包三个模型。这是整个流程的亮点,也是性能优化的关键。

技术亮点:从竞态问题到原子计数
在AI处理环节,我遇到了一个典型的竞态问题。早期版本使用CompletableFuture.allOf(...).thenAccept()来等待所有模型返回结果后统一推送。但这存在一个缺陷:如果某个模型快速失败,allOf可能会提前触发,导致结果不完整或推送失败。
为了解决这个问题,我重构了代码,采用handle + AtomicInteger的方案。
* 独立处理:为每个模型的CompletableFuture单独添加.handle()回调。
* 原子计数:使用一个AtomicInteger(finishedCount)来追踪已完成的模型数量。
* 立即推送:任何一个模型成功返回结果,就立即通过STOMP推送给用户,无需等待其他模型。
这个改动带来了两个显著优势:
* 速度更快:用户能第一时间收到第一个返回的AI回复,体验极佳。
* 稳定性更高:单个模型的失败不会影响其他模型的结果推送,系统容错性大大增强。
实时互动:WebSocket与跨节点通信
为了实现精准的在线人数统计和消息推送,我设计了一套基于Redis和RabbitMQ的跨节点通信方案。
* 会话跟踪:前端通过SockJS连接WebSocket后,会发送一个注册消息。后端的WebSocketSessionTracker会将用户会话信息(userId)以ZSet结构存入Redis,Key为session:{page},Score为时间戳。
* 在线统计:基于Redis的ZSet,可以轻松实现按页面分组的在线人数统计,并通过String类型的online:count:{page}进行缓存。
* 跨节点广播:由于后端部署了双实例,一个用户的消息需要被另一个实例上的用户收到。我利用RabbitMQ作为消息总线,当一个实例收到消息后,会将其广播到MQ,所有实例的CrossNodeMessageListener都会监听到该消息,并根据nodeId过滤掉自己发出的消息,再将有效消息推送给本机的客户端。
总结
博思AI智能体的架构设计,是我对高并发、分布式系统的一次实践。通过前后端分离、消息队列解耦、多模型并行处理以及精细化的实时通信方案,我成功构建了一个既能满足复杂业务需求,又具备良好性能和扩展性的AI社交平台。未来,我将继续探索更智能的模型调度策略和更极致的用户体验优化。
浙公网安备 33010602011771号