在开始微服务改造之前,我们需要思考几个关键问题:
- 设计上:怎么划分服务? 按照什么原则将单体应用拆分为多个微服务?
- 实现上:用什么技术? 选择什么技术栈来支撑微服务架构?
- 治理上:如何管理服务? 如何实现服务注册发现、配置管理、监控等?
本节主要讲解微服务改造的方案设计模块。
服务划分
微服务拆分是整个改造过程中最关键的一步,拆分得好不好直接决定了后续开发和维护的复杂度。
拆分原则
在进行微服务拆分时,我们遵循以下原则:
- **业务领域驱动:**按照业务功能进行拆分,确保每个服务都有明确的业务边界。比如用户管理、应用管理、AI 代码生成等,每个领域的业务逻辑相对独立。
- **数据一致性:**相关性强的数据保持在同一服务中,减少跨服务的数据依赖。比如用户信息和用户权限放在同一个服务中,避免跨服务查询。
- **团队组织:**考虑团队规模和技能分工,确保每个服务都有专门的团队负责。一般来说,一个微服务团队的规模在2-8人之间比较合适。
- **性能考虑:**将重计算模块独立出来,便于单独优化和扩展。比如AI代码生成和网页截图都是计算密集型任务,独立部署便于资源优化。
注意!++拆分微服务时一定要灵活,不能拆的不要硬拆!++如果两个功能模块耦合度很高,频繁需要相互调用,那么强行拆分反而会增加系统复杂度。
基础服务划分
基于以上原则,我们可以将系统划分为以下模块:
通用模块
这些模块不是独立的服务,而是被其他服务依赖的公共组件:
- ai-code-common:包含所有服务公用的代码,如异常处理、工具类、常量定义等,为其他服务提供基础设施支持。
- ai-code-model:统一的数据模型定义,包含实体类、DTO、VO、枚举类等,确保各服务间数据格式的一致性。
- ai-code-client:定义需要内部调用的服务接口,作为服务间通信的契约,实现服务间松耦合。
业务服务
这些是真正的微服务,(原则上来说)每个服务都有独立的进程和端口:
- 用户服务:作为整个系统的基础,统一管理用户状态和权限。负责用户注册、登录、注销、权限验证等核心功能。由于几乎所有业务都需要用户信息,所以用户服务是其他服务的基础依赖。
- 应用服务:业务核心服务,负责应用的完整生命周期管理。包括应用创建、编辑、删除、对话历史、代码保存、项目下载等功能,集成了文件操作、缓存管理、限流控制等能力。
- AI 服务:专门处理代码生成相关功能,集成 LangChain4j 支持流式响应。包含 AI 模型调用、代码生成功能。
- 截图服务:独立的 IO 密集型服务,使用 Selenium WebDriver 进行网页截图。由于截图操作比较消耗 CPU 和内存资源,独立部署便于单独优化和扩展。
当然,这只是初步的划分,也是比较理想的情况,实际上真的能这么操作么?还得看看各个服务间的依赖关系。
服务间依赖关系
在微服务架构中,服务间不能像之前那样通过本地方法调用,需要通过网络进行远程调用。我们的服务间依赖关系如下:
- 应用服务 → 用户服务:应用服务需要调用用户服务获取用户信息、进行权限验证。比如创建应用时需要验证用户身份,查询应用列表时需要获取创建者信息。
- 应用服务 → 截图服务:应用服务在生成代码后,需要调用截图服务生成应用的预览图,方便用户查看效果。
- 应用服务 ←→ AI 服务:这是一个双向依赖关系。应用服务需要调用 AI 服务进行代码生成,而 AI 服务在生成完成后需要调用应用服务保存聊天历史。
服务划分结果
通过梳理服务间依赖关系,我们发现应用服务和 AI 服务是强绑定的关系,因此 AI 服务不能作为完全独立的服务占用独立端口,而是作为 SDK 模块引入到应用服务中。
当然,还有其他的原因:
技术限制:Dubbo 序列化机制不支持 Flux 类型,无法通过 Dubbo 调用返回流式响应。
性能考虑:AI 代码生成是流式响应,如果通过网络传输会增加延迟和复杂度。
最后,我们需要整理出一个微服务划分表。包括各个服务的职责、端口分配、路由规划和依赖关系,便于后续的开发实现。
| 服务名称 | 端口和路由前缀 | 主要功能 | 依赖服务 |
|---|---|---|---|
| 通用模块 | |||
| ai-code-common | 注解、异常处理、工具类、常量、公共响应类 | ||
| ai-code-model | 实体类、DTO、VO、枚举类、AI 模型类 | common | |
| ai-code-client | 服务接口定义、内部调用契约 | common、model | |
| 业务服务 | |||
| ai-code-user | /api/user/** | 用户管理、权限认证、用户信息维护 | Redis、MySQL |
| ai-code-app | /api/app/api/chatHistory/ | 应用管理、聊天历史、项目下载、代码解析保存 | Redis、MySQL、用户服务、截图服务 |
| ai-code-ai | AI 代码生成、模型管理 | AI 大模型 |
微服务技术选型
微服务架构需要解决服务拆分、服务间通信、服务发现、统一网关等核心问题。对应这些需求,我们需要选择合适的技术栈,包括开发框架、注册中心、服务调用、微服务网关。项目将使用Spring Cloud Alibaba、Nacos、Dubbo、Higress 网关这套完整的解决方案。
微服务开发框架
微服务开发框架是构建微服务应用的基础,它提供了服务注册发现、配置管理、负载均衡、熔断降级等微服务治理能力的统一抽象。没有框架的话,开发者需要自己处理这些复杂的分布式问题,开发效率会大大降低。
目前主流的 Java 微服务开发框架包括:
- Spring Cloud:基于 Spring Boot 的微服务框架,生态完善,社区活跃
- Spring Cloud Alibaba:阿里基于 Spring Cloud 的扩展,集成了阿里云的微服务组件
- Dubbo:阿里开源的高性能 RPC 框架,专注于服务调用
本项目选择 Spring Cloud Alibaba 作为微服务开发框架,它包含了开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
核心组件包括:
- 服务发现与配置管理:集成了 Nacos 作为服务注册与发现、分布式配置管理的解决方案。
- 分布式事务:提供了 Seata 分布式事务解决方案,保证跨服务的数据一致性。
- 限流降级:集成了 Sentinel 流量控制组件,提供流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性。
- 消息驱动:提供了对 RocketMQ 的支持,实现消息驱动的微服务架构。
- 分布式调度:集成了 SchedulerX 任务调度平台,提供分布式任务调度能力。

Spring Cloud Alibaba 的优势在于它完全兼容 Spring Cloud 标准,同时提供了阿里在分布式系统方面多年的技术积累和最佳实践。对于咱们国内开发者,Spring Cloud Alibaba 还提供了更好的中文文档和社区支持,个人也会更推荐使用它而不是 Spring Cloud。
注册中心
注册中心是微服务架构的核心组件,它解决了服务发现问题。
什么是服务发现呢?
在微服务环境中,服务实例会动态启动和停止,IP 地址和端口也可能经常变化,服务消费者需要知道服务提供者的准确地址才能发起调用。注册中心就像一个电话簿,服务启动时向注册中心报告自己的地址信息,服务调用时从注册中心查询目标服务的地址。

本项目选择和 Spring Cloud Alibaba 兼容的 Nacos 作为注册中心。
Nacos(Naming and Configuration Service)由阿里开源,是易于构建云原生应用的动态服务发现、配置管理和服务管理平台。它集成了服务注册与发现、配置中心、服务元数据管理等功能,是构建微服务架构的重要基础设施。

除了 Nacos,其他注册中心比如 Eureka 适合 Spring Cloud 生态、Consul 提供了丰富的服务治理功能、Zookeeper 则适合高可用场景。
微服务调用
微服务调用是指不同服务之间的通信方式。在单体应用中,不同模块之间通过本地方法调用进行交互,而在微服务架构中,服务部署在不同的进程甚至不同的机器上,需要通过网络进行远程调用。
常见的微服务调用技术包括:
- HTTP/REST:基于 HTTP 协议的 RESTful API 调用,简单易用,跨语言支持好
- RPC:远程过程调用,如 Dubbo、gRPC,性能更高,但通常需要相同的技术栈
- 消息队列:如 RocketMQ、Kafka,支持异步调用,适合解耦场景
HTTP 和 RPC 之间有什么区别呢?
简单来说,RPC 调用更像是本地方法调用,性能更高;而 HTTP 调用更加通用和标准化,跨语言支持更好。
一个简易的 RPC 框架架构图:

本项目选择 Dubbo 作为主要的服务调用方式。Apache Dubbo 是阿里开源的高性能 RPC 框架,提供了面向接口的远程方法调用、容错和负载均衡等能力,以及服务自动注册和发现。

微服务网关
微服务网关是微服务架构的统一入口,它解决了客户端如何访问多个微服务的问题。没有网关的话,客户端需要直接调用各个微服务(输入不同的访问地址),这会导致客户端与服务的强耦合,并且难以统一处理认证、限流、监控等横切关注点。网关就像一个门卫,统一处理外部请求,然后转发到内部的具体服务。
常见的微服务网关技术包括:
- Spring Cloud Gateway:Spring 官方出品,和 Spring Cloud 生态集成度高
- Higress:阿里巴巴开源的云原生 API 网关,基于 Envoy,性能优异
- Kong:基于 Nginx 的开源网关,插件丰富
- Zuul:Netflix 开源,较为成熟但性能一般
本项目选择 Higress 作为微服务网关。Higress 是基于阿里内部多年 Envoy Gateway 实践的 云原生 + AI 原生 API 网关,采用 C++ 实现,相比传统的 Java 网关具有更高的性能和更低的内存占用,而且能够和 Nacos 和 Dubbo 轻松集成。

下面是 Higress 与 Spring Cloud Gateway 的详细对比:
不过如何你需要在网关中写一些业务逻辑,Higress 可能就不适合了,而 Spring Cloud Gateway 是可以在代码中引入并且自定义 Java 业务逻辑的。
微服务部署架构图
可以通过下面这个完整的部署架构图,更直观地理解我们的微服务架构设计:

恭喜你学会了微服务的拆分!