微服务架构设计实战:从单体到分布式
开篇:微服务到底是什么?为什么我们需要它?

你有没有遇到过这样的情况:
“我们开发了一个小商城网站,功能不多。但每次一改代码,整个系统都要重新部署一遍,而且有时候一个模块出问题了,整个网站都瘫痪。”
这就是**传统单体应用(Monolithic)**的典型问题。
而今天我们要讲的 “微服务”,就是为了解决这些问题而诞生的技术方案。
什么是微服务?
简单来说,微服务就是把原本集中在一起的大程序拆分成多个独立的小程序,每个小程序专门做一件事,并且可以独立运行、独立部署。
比如,一个商城系统原来是一个大项目,里面包含用户管理、商品展示、订单处理等功能。而在微服务架构下,这些功能会被拆成三个独立的服务:
- 用户服务(User Service)
- 商品服务(Product Service)
- 订单服务(Order Service)
它们之间通过网络互相通信(一般是 HTTP 协议),共同协作完成一个完整的业务流程。
为什么要用微服务?
- 易维护:每个服务只负责一件事,结构清晰。
- 灵活性高:你想更新某个功能时,只需要部署那个服务,不需要动其他部分。
- 扩展性强:如果某个服务访问量突然上升,我们可以单独给这个服务加机器。
- 容错性好:如果一个服务出问题,不会影响到整个系统。
当然,微服务也有一些缺点,比如部署复杂、需要考虑服务间通信等问题。不过没关系,我们一步步来,先学会怎么用它!
环境准备:搭建你的微服务开发环境

在开始编码之前,我们先来准备好开发环境。你需要安装以下工具(以 Java 语言为例):
所需软件(Windows/macOS/Linux通用)
JDK 17+
下载地址:https://adoptium.net/zh-CN/temurin/releases/
安装后,在命令行输入java -version验证是否安装成功。Maven 3.x
Maven 是 Java 中用来管理依赖和构建项目的工具。
下载地址:https://maven.apache.org/download.cgi
安装完成后输入mvn -v查看版本。IDE(推荐 IDEA 或 VS Code)
IDEA 社区版完全免费,下载地址:https://www.jetbrains.com/idea/download/Postman(用于测试接口)
下载地址:https://www.postman.com/downloads/Docker(可选)
用于后续部署多个微服务容器。
Windows 推荐使用 Docker Desktop;Linux 可安装 Docker CE。
✅ 新手建议:不要着急一步到位,先把 JDK 和 IDE 搭建好,能跑通示例再逐步完善环境。
核心概念:理解微服务的关键术语


我们来看看几个核心术语,我会用最简单的方式解释。
1. 微服务(Microservice)
前面已经提到了,就是一个“小功能模块”,例如上面提到的用户服务、订单服务等。
2. API 接口(Application Programming Interface)
通俗说就是“两个系统之间沟通的语言”。
举个例子:
- 用户服务提供一个 API:
GET /user/{id},你可以通过这个地址获取用户信息。 - 订单服务要查询某个用户的信息,就可以通过调用这个 API 来获取。
所以,API 是服务之间的“对话方式”。
3. 服务注册与发现(Service Registration & Discovery)
想象一下你有几十个微服务,你怎么知道哪个服务叫什么名字、在哪台服务器上运行呢?
这就需要有个“电话簿”一样的东西,记录所有服务的位置——这个功能叫做 服务注册与发现。
常用的工具是:Eureka(Spring Cloud) 或者 Consul。
4. 负载均衡(Load Balancing)
当一个服务有很多实例在运行时(比如 3 个相同的订单服务),客户端请求进来应该发给哪一个?
负载均衡器就会决定把请求分配到哪一台服务上。
常用的是:Ribbon 或 LoadBalancer(Spring Cloud 2020以后)
5. 网关(API Gateway)
网关就像一个“总入口”,所有的请求都要经过网关才能访问具体的微服务。
它可以做权限控制、路由转发、限流等工作。
常用网关:Zuul(老) 或 Gateway(新)
实战项目:从零开始搭建一个简单的微服务系统

我们以一个最简单的商城系统为例,搭建一个包含用户服务和订单服务的微服务系统。
项目结构如下:
microservices-demo/
├── user-service // 用户服务
└── order-service // 订单服务
我们将让订单服务通过 HTTP 请求调用用户服务,来获取用户的详细信息。
第一步:创建 Spring Boot 项目(使用 Spring Initializr)
打开 https://start.spring.io/ 创建一个新的 Spring Boot 项目。
配置如下:
- Project: Maven
- Language: Java
- Spring Boot Version: 3.x(比如 3.1.4)
- Group: com.example
- Artifact: user-service
- Dependencies:
- Spring Web(用于构建 RESTful API)
- Spring Boot DevTools(热加载,修改代码不重启服务)
- Spring Data JPA + H2 Database(可选,做数据库操作)
点击 Generate Project 下载 zip 包,解压后用 IDEA 打开。
重复以上步骤,创建第二个项目:order-service
第二步:编写 User 服务
进入 user-service,我们先写一个最简单的接口:根据用户 ID 获取用户名。
1. 修改启动类 UserServiceApplication.java
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
2. 创建 Controller 文件 UserController.java
@RestController
@RequestMapping("/user")
public class UserController {
@GetMapping("/{id}")
public String getUserById(@PathVariable Long id) {
return "用户ID:" + id + " 姓名:张三";
}
}
3. 运行项目并测试
启动项目,访问地址:http://localhost:8080/user/123,你会看到:
用户ID:123 姓名:张三
第三步:编写 Order 服务
现在我们在订单服务中调用用户服务。
1. 修改配置文件 application.yml
默认端口是 8080,为了避免冲突,我们改为 8081:
server:
port: 8081
2. 创建订单 Controller OrderController.java
@RestController
@RequestMapping("/order")
public class OrderController {
private final WebClient webClient;
public OrderController() {
this.webClient = WebClient.builder()
.baseUrl("http://localhost:8080")
.build();
}
@GetMapping("/detail")
public String getOrderDetail() {
String result = webClient.get()
.uri("/user/123")
.retrieve()
.bodyToMono(String.class)
.block(); // 注意:正式项目中应避免阻塞操作
return "订单详情:用户信息 - " + result;
}
}
这段代码的作用就是:从订单服务发起对用户服务 /user/123 的请求。
3. 启动 order-service 并测试
启动订单服务后,访问:http://localhost:8081/order/detail
你会看到输出:
订单详情:用户信息 - 用户ID:123 姓名:张三
🎉 成功!你已经实现了第一个跨服务调用!
第四步:添加服务注册中心(Eureka Server)
目前我们是“硬编码”地调用了用户服务的 URL。实际生产环境不可能这样写,因为 IP 和端口可能变化。
所以我们引入 Eureka,让服务自动注册自己,并允许其他服务动态查找。
1. 创建新的项目:eureka-server
同样去 https://start.spring.io/ 创建一个 Spring Boot 项目,名称 eureka-server,依赖项选择:
- Spring Web
- Eureka Server
2. 修改启动类 EurekaServerApplication.java
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
3. 修改配置文件 application.yml
server:
port: 8761
spring:
application:
name: eureka-server
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
4. 启动服务
访问 http://localhost:8761,你会看到 Eureka 控制台。
第五步:将 User Service 注册到 Eureka
1. 在 user-service/pom.xml 中加入:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. 修改 application.yml
spring:
application:
name: user-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
3. 重启 user-service
刷新 Eureka 控制台页面,你应该能看到一个名为 USER-SERVICE 的服务注册进来了。
第六步:让 Order Service 自动发现 User Service
同样的方法:
1. 在 order-service/pom.xml 添加 Eureka 客户端依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
2. 修改配置文件 application.yml
spring:
application:
name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
3. 使用 LoadBalancer 替换硬编码 URL
修改 OrderController.java,使用 RestTemplate 或 WebClient 结合服务名调用。
private final WebClient webClient;
public OrderController() {
this.webClient = WebClient.builder()
.baseUrl("http://user-service") // 注意这里不再是IP+端口,而是服务名
.build();
}
⚠️ 此处还需要在主类中启用负载均衡:
@SpringBootApplication
@EnableDiscoveryClient
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
现在再次访问 /order/detail,你会发现依然可以正常调用!
常见问题解答(FAQ)
Q1:我调用服务时报错,连接不上 user-service,怎么办?
A:可能是没有正确注册服务。请检查:
- 服务名是否拼写正确(比如 user-service 和 UserService 是否一致)
- Eureka Server 是否正常运行
- 网络是否通顺,防火墙是否放行端口
Q2:WebClient 和 RestTemplate 有什么区别?
A:两者都能发送 HTTP 请求,但 WebClient 更现代化,支持响应式编程风格。RestTemplate 则更简单直接,适合初学者使用。
Q3:我能不能不用 Eureka,自己维护服务列表?
A:当然可以,但这被称为“静态配置”,不适合大规模微服务系统。随着服务数量增加,维护起来非常麻烦。
学习建议:下一步你该学什么?
恭喜你完成了第一阶段的微服务学习!接下来你可以沿着以下路径继续深入:
第一阶段(基础篇):
- ✅ 已掌握:服务拆分、HTTP 通信、服务注册发现
第二阶段(增强篇):
- 引入 API Gateway(推荐 Spring Cloud Gateway)
- 实现统一配置中心(Spring Cloud Config)
- 添加服务链路追踪(Sleuth + Zipkin)
- 设置断路器(Hystrix,现已较少使用,可用 Resilience4j)
- 学习日志聚合(ELK Stack)
第三阶段(进阶篇):
- 消息队列(如 RabbitMQ、Kafka)实现异步通信
- 持续集成与持续部署(CI/CD)自动化部署微服务
- 容器化部署(Docker + Kubernetes)
结语

本教程带你从零开始,了解了什么是微服务,搭建了本地开发环境,实现了两个服务的通信,还引入了服务注册中心 Eureka。这只是一个起点,后面还有更多精彩内容等着你。
记住一句话:
“微服务不是银弹,但它是一把强大的锤子。”
只要你掌握了基础原理,不断实践,就能灵活应对各种复杂业务场景。加油,未来你也能成为微服务高手!
如果你觉得这篇教程对你有帮助,欢迎关注我的博客或视频课程,我们将继续深入更多后端开发实战技巧。

评论 0