微服务架构设计实战:从单体到分布式
开篇:什么是微服务?它用来做什么?

你有没有见过一座摩天大楼?它看起来又高又大,但其实是由很多小房间、走廊和楼梯组成的。微服务架构就像是这栋大楼的设计方式 —— 它不是把所有的功能都放在一个“大盒子”里(也就是传统常说的“单体应用”),而是把每个功能独立成一个个小的服务。
比如,如果你做一个网上商城系统,传统的做法是:一个程序负责用户注册、商品展示、下单、支付等所有功能。而微服务的做法是:
- 用户管理是一个单独的服务
- 商品信息是另一个服务
- 订单处理又是第三个服务
- 支付系统又是一个服务
这些服务之间可以互相通信,但它们各自运行,各自开发、部署、维护。这样一来,团队协作更方便了,系统也更容易扩展。
在本教程中,我们将带你从零开始,逐步实践搭建一个简单的微服务项目。即使你是完全的新手,也能轻松上手!
环境准备:搭建你的开发环境

所需工具清单:
| 工具 | 作用 | 下载链接 |
|---|---|---|
| Java JDK 11+ | 编写后端服务的基础语言 | https://openjdk.java.net |
| Maven | 依赖管理工具,帮助你快速加载代码库 | https://maven.apache.org |
| Spring Boot CLI (可选) | 快速创建Spring Boot项目 | https://spring.io/projects/spring-boot#cli |
| IntelliJ IDEA 或 VSCode | 编写Java代码的IDE推荐 | https://www.jetbrains.com/idea/download/ |
| Docker | 运行微服务容器(后期用) | https://www.docker.com/get-started |
步骤一:安装JDK
我们使用 OpenJDK,它是免费且被广泛使用的版本。
打开浏览器访问OpenJDK官网
根据你的操作系统下载对应版本(建议选择JDK 11或更高)
安装完成后打开终端(Windows用cmd),输入:
java -version如果看到类似输出表示安装成功:
openjdk version "11.0.16" 2022-07-19 OpenJDK Runtime Environment Adoptium-11.0.16+8 (build 11.0.16+8)
步骤二:安装Maven
- 打开Maven官网
- 下载
Binary zip archive - 解压到任意目录,例如:
C:\dev\apache-maven-3.8.6 - 配置环境变量:
- 新建系统变量
MAVEN_HOME: 值为解压路径 - 在
Path中添加%MAVEN_HOME%\bin
- 新建系统变量
- 检查安装是否成功,在终端中输入:
成功显示版本号即可。mvn -v
步骤三:安装IDE(推荐IntelliJ IDEA)
- 下载社区版即可(完全免费)
- 安装过程中勾选与Java和Spring相关的组件
- 启动IDEA,选择新建项目,选择Spring Initializr,填写基础信息即可创建项目
步骤四:安装Docker(用于后面部署)
Windows用户推荐安装Docker Desktop
Mac用户也可以直接通过命令行安装
brew install --cask docker
安装完成后启动Docker应用,并在终端执行:
docker run hello-world
如果输出一段英文欢迎语,说明Docker已经正常运行。
核心概念解析:用最简单的话解释关键术语


在学习微服务之前,我们要先理解几个核心的概念。别担心,我会尽量用比喻来帮你理解。
1. 单体应用 vs 微服务
| 对比项 | 单体应用 | 微服务 |
|---|---|---|
| 结构 | 一个大的应用程序包含所有功能 | 多个小型服务,每个只负责一部分功能 |
| 部署 | 修改一个功能要重新部署整个程序 | 只需要更新涉及的部分 |
| 维护 | 越大越难维护 | 更灵活,容易拆分 |
| 团队合作 | 一组人一起修改一个文件 | 不同团队各自开发自己的服务 |
举个例子:假如你在做生日蛋糕,单体就是一个人做完全部工作;微服务就像分成多个小组:一个做奶油、一个做装饰、一个写祝福卡。
2. REST API 和 HTTP 请求
REST API 就是一种让不同服务之间能够互相打招呼的方式。
你可以把它想象成两个人之间的对话:
- A服务问:“嘿,你知道用户ID=1的信息吗?”
- B服务回答:“当然知道,给你看这个用户的名字叫张三。”
具体来说,我们可以用 GET /user/1 来请求用户信息,B服务返回JSON数据:
{
"id": 1,
"name": "张三"
}
3. Eureka 服务发现(Service Discovery)
在微服务中,服务数量变多,A服务怎么知道B服务在哪呢?这就需要用到 Eureka。
想象一下,公司里的电话总机:你想联系技术部的人,就打个电话给总机,告诉他们你要找谁。
同样地,我们的服务在启动时会向Eureka注册自己,其他服务就可以通过Eureka找到它。
4. Feign 远程调用
Feign 是一种让你在微服务之间远程调用的方法。
它就像打电话一样简单:
@FeignClient(name = "product-service")
public interface ProductServiceClient {
@GetMapping("/products/{id}")
Product getProductById(@PathVariable("id") Long id);
}
这段代码的意思是:我想要连接名为“product-service”的服务,并调用它的 /products/{id} 接口。
5. Spring Cloud Gateway
当你有多个服务时,用户应该去哪个地址访问?这时候我们就需要一个统一的入口,这就是 API网关(Gateway)。
比如:
- 用户访问:
http://api.example.com/user/1→ 路由到 user-service - 用户访问:
http://api.example.com/product/1→ 路由到 product-service
这样用户只需要记住一个网址,内部由网关自动分配。
实战项目:一步步构建两个微服务并实现通信

现在,我们将动手完成一个完整的微服务项目!目标是搭建两个服务:
user-service:用来管理用户信息product-service:用来管理商品信息- 最终实现:用户调用API获取某个商品信息(模拟跨服务调用)
第一步:创建两个Spring Boot项目
使用IntelliJ IDEA 或者访问 Spring Initializr
创建 user-service
- Group:
com.example - Artifact:
user-service - Dependencies:
- Spring Web
- Spring Cloud Discovery (Eureka Client)
创建 product-service
- Group:
com.example - Artifact:
product-service - Dependencies:
- Spring Web
- Spring Cloud Discovery (Eureka Client)
将这两个项目分别导入IDE。
第二步:配置Eureka服务注册中心
我们需要先启动一个Eureka Server。
创建一个新的Spring Boot项目:eureka-server
- Dependencies:
- Spring Cloud Discovery (Eureka Server)
打开 application.yml 文件,添加如下配置:
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
然后在主类上加上注解启用Eureka:
@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
启动后访问 http://localhost:8761 应该能看到Eureka控制台界面。
第三步:配置两个微服务注册到Eureka
在 user-service 和 product-service 的 application.yml 中添加以下内容:
spring:
application:
name: user-service # 或 product-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
并在主类加上注解启用Eureka客户端:
@EnableEurekaClient
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
重启服务后,再次进入Eureka控制台,你就能看到两个服务注册进来了。
第四步:编写产品服务接口
在 product-service 中创建一个控制器 ProductController.java:
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{id}")
public Map<String, Object> getProductById(@PathVariable Long id) {
Map<String, Object> product = new HashMap<>();
product.put("id", id);
product.put("name", "iPhone 15");
product.put("price", 6999);
return product;
}
}
测试访问 http://localhost:8081/products/1001 是否能正常返回商品信息。
第五步:用户服务调用产品服务(Feign)
在 user-service 中添加Feign依赖:
在 pom.xml 中加上:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
然后启用Feign,在主类上加上:
@EnableFeignClients
创建 ProductServiceClient.java:
@FeignClient(name = "product-service")
public interface ProductServiceClient {
@GetMapping("/products/{id}")
Map<String, Object> getProductById(@PathVariable("id") Long id);
}
最后在 UserController.java 中注入并调用:
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private ProductServiceClient productServiceClient;
@GetMapping("/product/{id}")
public Map<String, Object> getUserAndProduct(@PathVariable Long id) {
Map<String, Object> response = new HashMap<>();
response.put("user", "张三");
response.put("product", productServiceClient.getProductById(id));
return response;
}
}
测试访问 http://localhost:8080/users/product/1001,你应该可以看到:
{
"user": "张三",
"product": {
"id": 1001,
"name": "iPhone 15",
"price": 6999
}
}
✅ 到此为止,两个服务已经完成了通信!
常见问题解答(FAQ)
Q1:为什么启动Eureka的时候报错 “No instances available for service”?
这是因为你的微服务没有正确注册到Eureka。检查以下几点:
- 确保Eureka已先于其他服务启动
- 检查
application.yml中的spring.application.name和eureka.client.service-url是否正确 - 查看日志是否有错误提示,如网络不通、端口占用等
Q2:Feign调用失败怎么办?
常见的原因有:
- 目标服务未启动或者没有注册到Eureka
- Feign接口中的URL路径写错了
- Feign没有启用(忘记加
@EnableFeignClients) - 没有添加Feign依赖
建议先直接访问目标服务的API,确保没问题后再接入Feign。
Q3:微服务运行很慢,怎么优化?
你可以尝试:
- 使用缓存(如Redis)减轻数据库压力
- 异步调用(如RabbitMQ)
- 服务限流与熔断(Hystrix)
这些高级功能将在后续学习中展开。
学习建议:下一步你该学什么?
恭喜你,你已经迈出了学习微服务的第一步!
接下来建议按照以下路径继续学习:
✅ 第一阶段:掌握微服务核心组件
| 技术 | 用途 |
|---|---|
| Spring Cloud Config | 集中管理各个服务的配置文件 |
| Hystrix | 服务熔断,防止雪崩效应 |
| Zuul / Gateway | API网关统一入口 |
| Sleuth & Zipkin | 分布式链路追踪,方便排查问题 |
✅ 第二阶段:深入生产级技能
| 技术 | 用途 |
|---|---|
| Docker + Kubernetes | 服务编排与自动化部署 |
| Prometheus + Grafana | 服务监控与可视化 |
| ELK Stack(Elasticsearch + Logstash + Kibana) | 日志分析与查询 |
| Kafka / RabbitMQ | 异步消息通信,提升系统性能与解耦 |
✅ 推荐学习顺序图示:
单体应用 ➔ REST API ➔ Eureka 注册中心 ➔ Feign 远程调用 ➔ 网关 ➔ 配置中心 ➔ 熔断机制 ➔ 服务编排(Docker/K8s)
结尾语:编程是一门“做中学”的艺术
微服务并不是一开始就复杂的,它是随着业务需求一点点演化出来的。你现在写的每一行代码,每一个小Demo,都是你通往强大后端工程师之路的基石。
遇到不懂的地方不要怕,多查文档、多敲代码、多提问。你会越来越熟练!
如果你希望获得更多实战案例,欢迎关注我的系列教程《微服务架构进阶实战》,我们会从“小玩具”变成“真家伙”,一步步打造属于你自己的微服务平台!
文末彩蛋:源码托管地址(GitHub 示例)
点击链接即可查看完整工程结构与源码,欢迎大家Star和Fork学习!

评论 0