Skip to content

技术选型理由

本页作为网站详细版页面维护,重点回答两个问题:

  1. 这个项目为什么选这一套技术;
  2. 这些选型在代码里到底有没有真正落下来。

0. 先看这页最有说服力的代码证据

相比单纯罗列技术名词,这个项目的选型更值得从“工程密度”来看:

  • 16 个业务模块,19 个服务应用,已经不是单体项目能舒服承接的规模
  • 18 个 @FeignClient,说明跨服务调用是常态,不是“微服务壳子”
  • 30 个 @RabbitListener,说明异步削峰、补偿和解耦已经进入主链路
  • 26 个 @XxlJob 处理器,说明定时扫描、兜底补偿、重建任务都已体系化
  • 4 类向量检索空间(店铺 / 商品 / 博客 / 评价),说明 AI 不是单点问答演示
  • 6 类审核策略(用户 / 店铺 / 博客 / 商品 / 评论 / 评价),说明治理链路已抽象成统一模型

所以这页不是在解释“为什么选了一套流行栈”,而是在解释: 为什么这套技术组合最适合支撑当前这份真实代码。

1. 为什么服务基础选 Spring Boot,并在微服务治理层使用 Spring Cloud Alibaba

我的选择:Spring Boot + Spring Cloud Alibaba

  • 职责边界清楚:Spring Boot 负责单服务开发底座,Spring Cloud Alibaba 负责注册发现、配置管理、网关入口与治理协同
  • 更贴当前项目规模:项目已经拆到 19 个服务应用、16 个业务模块,只靠 Spring Boot 已经不足以覆盖服务编排和配置治理
  • 和当前技术栈贴合:Nacos、Gateway、Sentinel、Seata 预留、Spring AI、MyBatis Plus 都能自然接入
  • 统一 starter 体系:公共能力被沉淀到了 smartLive-common-* 这组模块里,服务推进更稳定
  • 不走传统 SSM:样板代码更多,服务治理和环境管理能力也更弱
  • 只用 Spring Boot 不选原因:适合单体或少量服务,不适合当前这种多服务协作场景

2. 为什么注册中心和配置中心选 Nacos,而不是 Eureka / Consul

我的选择:Nacos

  • 注册 + 配置一体化:同一套组件同时解决服务发现和配置管理,减少组件碎片化
  • 更贴当前工程结构:当前服务数量已经不少,各模块都依赖统一配置,Nacos 更容易做环境隔离和集中维护
  • 与 Spring Cloud Alibaba 集成顺滑:和 Gateway、Sentinel、Seata 预留一起接入更自然
  • Eureka 不选原因:更偏传统注册中心,只解决发现问题,配置中心还要额外引入
  • Consul 暂不选原因:能力并不差,但在当前 Java 微服务语境下,资料沉淀和接入习惯不如 Nacos 顺手

3. 为什么调度中心选 XXL-JOB,而不是 Quartz / 纯 MQ

我的选择:XXL-JOB + RabbitMQ 分工协作

  • 职责边界清楚:RabbitMQ 负责实时异步解耦,XXL-JOB 负责定时扫描、补偿兜底、批量重建和后台可视化运维
  • 更贴当前代码现状:仓库里已经落了 26 个 @XxlJob 处理器,后台对外展示为 28 个调度任务
  • 适配当前任务类型:订单超时、临期提醒、热榜重建、秒杀预热、数据修复,都更适合集中调度
  • Quartz 不选原因:适合嵌入式单体或少量任务,但后台可视化、执行器拆分和分布式治理不如 XXL-JOB
  • 只靠 MQ 不选原因:MQ 擅长事件驱动,不擅长按时间窗口做扫描、兜底和全量修正

4. 为什么对象存储选 MinIO,而不是直接接 OSS / COS

我的选择:MinIO

  • 本地和服务器更容易统一:开发、测试、部署环境都能用同一套对象存储接口
  • 数据可控:头像、图片、文件都落在自己可控的存储节点上,不依赖第三方云厂商账号和计费策略
  • 兼容 S3 协议:后续切到云上对象存储也有平滑迁移路径
  • OSS / COS 暂不选原因:更适合成熟生产环境,但当前阶段会引入额外账号、计费和环境依赖

5. 为什么搜索层选 Elasticsearch,而不是 MySQL LIKE / 复杂联表

我的选择:Elasticsearch

  • 更适合搜索场景:关键词匹配、热词统计、排序、分页和高频查询都比 MySQL LIKE 更适合
  • 支持地理位置与多条件组合:店铺搜索里需要 LBS、评分、距离、分类等多维条件,ES 更容易表达
  • 和当前架构契合:项目里已经有搜索同步链路,业务写入与搜索读取是解耦的
  • MySQL LIKE 不选原因:适合小规模后台检索,不适合承接前台高频搜索、模糊匹配和复杂排序

6. 为什么缓存层选 Redis,而不是 Memcached

我的选择:Redis

  • 数据结构够丰富:当前项目已经实际用到了 String / ZSet / Hash / Set / Geo / Lua
  • 更贴业务读写模型:登录态、验证码、热点详情、Feed 滚动分页、热榜、LBS、秒杀库存校验,都不是单一 String 能舒服承接的
  • 能和异步链路配合:Redis 既承担读写性能,也承担幂等键、短期状态和部分恢复性数据
  • Memcached 不选原因:结构单一,不适合当前项目的热榜、滚动分页、地理位置、库存脚本这类场景

7. 为什么向量检索选 Milvus,而不是 Pinecone / Weaviate

我的选择:Milvus

  • 开源可控:可以部署在自己的服务器上,数据安全与成本更可控
  • 更贴当前 AI 场景:项目里已经实际拆成了 店铺 / 商品 / 博客 / 评价 四类向量空间
  • 本地联调更稳:Milvus 不可用时,代码里已经做了 SimpleVectorStore 降级,不会把整条 AI 链路直接拖死
  • Pinecone 不选原因:云服务形态更重,存在额外成本和供应商绑定问题
  • Weaviate 暂不选原因:当前项目已经围绕 Spring AI + MilvusVectorStore 落了实现,没有必要再额外切换技术路线

8. 为什么 AI 编排层选 Spring AI,而不是手写 OpenAI SDK / LangChain4j

我的选择:Spring AI

  • 更贴当前技术栈:和 Spring Boot、向量存储、工具调用、配置中心能够自然接到一起
  • 足够承接当前能力:用户端问答、RAG 检索、博客生成、评价生成、商家助手都能在统一抽象层上做
  • 抽象层更统一:模型调用、Prompt、向量检索、Advisor、Memory、Tool 都有统一接口
  • 手写 OpenAI SDK 不选原因:灵活但太底层,模型切换、上下文管理、RAG 拼装都要自己维护
  • LangChain4j 暂不选原因:也能做类似能力,但当前项目已经全面站在 Spring 体系上,Spring AI 一致性更高

9. 为什么消息中间件选 RabbitMQ,而不是 Kafka

我的选择:RabbitMQ

  • 更贴当前消息类型:订单状态流转、退款补偿、向量同步、IM 广播、互动同步,都偏业务事件驱动
  • 死信 / TTL / ACK/NACK 更顺手:项目里已经真实使用了死信、重试、确认与幂等消费这套能力
  • 运维成本更合适:当前阶段 RabbitMQ 足够承接,不需要为了吞吐冗余引入 Kafka 集群复杂度
  • 代码落地密度高:仓库里已经有 30 个 @RabbitListener
  • Kafka 不选原因:更适合超大吞吐日志流和实时流处理;对当前项目来说能力偏重、运维更复杂

10. 为什么长连接层选 Netty + WebSocket,而不是 Spring WebSocket

我的选择:Netty + WebSocket

  • 更贴当前 IM 需求:项目里单独拆了 smartLive-im 模块,不只是页面层的“假聊天”
  • 链路更可控IdleStateHandlerWebSocketServerProtocolHandlerChannelGroup、在线用户映射都能细粒度控制
  • 能和业务持久化拆开:Netty 负责实时连接与推送,chat 模块负责会话落库与聚合,职责分离更清楚
  • Spring WebSocket 不选原因:快速起步更容易,但在当前这种要做在线状态、广播、会话同步的场景下,控制力不够细

11. 为什么数据访问层选 MyBatis Plus,而不是 JPA

我的选择:MyBatis Plus

  • SQL 可控性更强:当前项目有不少复杂查询、批量更新、状态扫描和后台治理查询,手写 SQL 更稳
  • 更贴当前国内项目习惯:SQL 即所见即所得,排查问题时更直接
  • 兼顾效率和灵活性:简单 CRUD 用 MyBatis Plus,复杂场景用自定义 SQL,不会被 ORM 抽象反噬
  • JPA 不选原因:在当前项目这种状态流转、联表治理、批量处理较多的场景下,SQL 透明度和调优空间不如 MyBatis Plus

12. 从代码看,这些选型不是“名单堆砌”

如果只看技术名词,这一页很容易像“常见后端八股”。但结合代码,这些选型其实已经落成了具体结构:

  • Gateway 前置安全AuthFilter / XssFilter / ValidateCodeFilter / BlackListUrlFilter
  • 微服务协同18 个 @FeignClient
  • 消息可靠链路30 个 @RabbitListener + 死信 / ACK / 幂等键
  • 调度补偿体系26 个 @XxlJob
  • 向量检索与降级MilvusVectorStore + SimpleVectorStore fallback
  • 实时通讯架构NettyServer + NettyChatHandler + RemoteChatService

所以这页最想表达的不是“我知道这些技术名词”,而是: 当前代码规模和业务复杂度,确实需要这套选型组合来支撑。