微服务入门指南:从小白到理解架构演进
本文面向零基础读者,用通俗的语言讲清楚:什么是微服务、为什么用它、怎么上手。
一、从一个餐厅说起
想象你开了一家餐厅。
单体架构就像一个大排档:一个厨师负责所有事 — 炒菜、凉菜、烧烤、甜品、收银全是一个人。生意少的时候还行,一旦客满,厨师忙不过来,而且万一他生病了,整个店关门。
微服务架构就像一个专业餐厅:后厨分成热菜组、凉菜组、烧烤组、甜品组,前台有专门的服务员、收银员。每组各司其职,互不干扰。菜量大了可以给热菜组加人,烧烤组忙不过来了就多招一个烧烤师傅。
这就是微服务的核心思想:把一个大系统拆成多个独立的小服务,每个服务专注做一件事。
二、单体 vs 微服务:一张表看懂
| 对比维度 | 单体架构 | 微服务架构 |
|---|---|---|
| 部署 | 打一个包,一次部署 | 每个服务独立打包部署 |
| 扩展 | 整体扩缩,浪费资源 | 按需扩缩,哪个服务忙就扩哪个 |
| 开发 | 所有人在一个代码仓库 | 每个服务独立仓库、独立团队 |
| 故障隔离 | 一个模块挂了,整个系统可能崩 | 一个服务挂了,其他不受影响 |
| 技术选型 | 一套技术栈用到死 | 每个服务可以选最合适的语言/框架 |
| 上手难度 | 简单,适合小项目 | 复杂,运维成本高 |
三、微服务长什么样?一张图看懂
四、核心概念逐个讲
4.1 服务拆分
怎么把一个系统拆成微服务?常见思路是按业务领域拆分:
-
电商系统 → 用户服务、商品服务、订单服务、支付服务、物流服务
-
博客系统 → 用户服务、文章服务、评论服务、搜索服务
拆分原则:高内聚、低耦合。一个服务内部的数据和方法紧密相关,服务之间尽量少依赖。
4.2 API 网关 — "前台"
所有客户端请求先到网关,由网关转发到对应的服务。
作用:统一入口、身份认证、限流、日志、路由。
常用方案:Spring Cloud Gateway、Kong、Nginx + Lua。
4.3 服务注册与发现 — "通讯录"
几十个服务之间怎么找到对方?需要一个通讯录:
-
注册:每个服务启动时把自己的地址(IP + 端口)报到注册中心
-
发现:服务 A 要调服务 B 时,先去注册中心查到 B 的地址
常用方案:Nacos(阿里)、Consul、Eureka(已停更)。
4.4 远程调用 — "怎么交流"
微服务之间需要互相调用,常见方式:
| 方式 | 说明 | 常用框架 |
|---|---|---|
| HTTP/REST | 最通用,同步调用 | Spring Cloud OpenFeign |
| RPC | 高性能,像调本地方法 | Dubbo、gRPC |
| 消息队列 | 异步解耦 | RabbitMQ、Kafka、RocketMQ |
4.5 配置中心 — "统一管理配置"
每个服务都有自己的配置文件(数据库地址、端口号等),几十个服务散落各处根本管不过来。
配置中心把所有配置统一管理,改了配置不用重启服务就能生效。
常用方案:Nacos Config、Apollo(携程开源)。
4.6 服务熔断与降级 — "保险丝"
服务 A 调用服务 B,B 挂了,A 还在不停地重试,最终连 A 也被拖垮 — 这叫雪崩效应。
熔断:B 不可用时,A 直接不再调用 B,快速失败,就像保险丝熔断。
降级:B 不可用时,A 返回一个兜底结果,保证核心流程能走通。
常用方案:Sentinel(阿里)、Hystrix(已停更)。
五、关键词速查表
以下是你学习微服务时一定会反复遇到的术语,每个都用一句话讲清楚。
基础概念
| 关键词 | 一句话解释 |
|---|---|
| 微服务 Microservice | 把一个大系统按业务拆成多个独立的小服务,各自开发、部署、升级 |
| 单体 Monolith | 所有功能写在一个项目里,打成一个包部署 |
| 服务 Service | 独立运行、对外提供特定功能的一个程序,比如「用户服务」只管用户登录注册 |
| 实例 Instance | 同一个服务可以启动多份,每一份就是一个实例,用来分担流量 |
| 集群 Cluster | 同一个服务的多个实例组成一个集群,对外像一个整体 |
| 节点 Node | 集群中的一台机器或一个容器 |
通信相关
| 关键词 | 一句话解释 |
|---|---|
| REST / RESTful | 一种用 HTTP 协议设计接口的风格,URL 表示资源,GET/POST/PUT/DELETE 表示操作 |
| RPC | 远程过程调用,像调用本地方法一样调用远程服务,性能比 HTTP 高 |
| 序列化 | 把对象转成字节流,方便网络上传输。常见:JSON、Protobuf |
| 负载均衡 Load Balance | 把请求分摊到多个实例上,避免一个被打爆。网关自带这个能力 |
| 同步调用 | A 调用 B,A 要等 B 返回结果才能继续。类似打电话 |
| 异步调用 | A 给 B 发个消息就去干别的了,不等结果。类似发微信 |
中间件与基础设施
| 关键词 | 一句话解释 |
|---|---|
| 注册中心 Nacos | 服务的「黄页电话本」,记录哪些服务在哪些地址上运行着 |
| 配置中心 Apollo / Nacos | 把各服务的配置文件统一放在一个地方管理,改配置不用重启 |
| API 网关 Gateway | 系统唯一的入口,负责路由、认证、限流,请求先过它再转发到具体服务 |
| 消息队列 MQ | 异步通信的中间件,发消息的不用等接收方处理完。RabbitMQ、Kafka、RocketMQ |
| Sentinel | 阿里的流量防卫兵,做限流、熔断、降级 |
| Seata | 阿里的分布式事务方案,解决跨服务数据一致性问题 |
| SkyWalking | 链路追踪工具,一个请求跨了多少个服务、每个耗时多少一目了然 |
部署与运维
| 关键词 | 一句话解释 |
|---|---|
| Docker | 把应用和环境打包成镜像,到处都能一样地运行。"在我机器上能跑啊"的终结者 |
| Docker Compose | 一条命令启动多个 Docker 容器,本地开发必备 |
| Kubernetes (K8s) | 容器的编排调度平台,管理成百上千个容器的部署、扩缩容、故障恢复 |
| 容器 Container | Docker 跑起来的一个隔离环境,类似一个超轻量的虚拟机 |
| 镜像 Image | 容器的模板,就像操作系统的安装盘。Dockerfile 描述怎么构建镜像 |
| CI/CD | 持续集成 / 持续部署:代码提交 → 自动构建 → 自动测试 → 自动部署到服务器 |
| DevOps | 开发 + 运维一体化,团队既要写代码也要管部署,打破"开发写完扔给运维"的墙 |
| 敏捷开发 Agile | 把大需求拆成小迭代,每 1-2 周交付一部分,快速试错。微服务天然适配这种模式 |
六、手把手跑通一个微服务项目
用 Spring Cloud Alibaba 全家桶,搭一个最简单的「用户服务 → 订单服务」调用链。
6.1 环境准备
| 工具 | 版本要求 | 作用 |
|---|---|---|
| JDK | 17+ | Java 运行环境 |
| Maven | 3.8+ | 项目构建 |
| Nacos | 2.x | 服务注册 + 配置中心 |
| IDEA | 社区版即可 | 写代码 |
6.2 启动 Nacos
Nacos 是第一个要启动的东西,所有服务都依赖它。
# 1. 下载 Nacos(Windows 用 zip,Mac/Linux 用 tar.gz) # 下载地址:https://github.com/alibaba/nacos/releases # 2. 解压后进入 bin 目录,启动(单机模式) # Windows: startup.cmd -m standalone # Mac / Linux: sh startup.sh -m standalone # 3. 浏览器访问 http://localhost:8848/nacos # 账号 nacos,密码 nacos # 看到控制台页面就说明启动成功了
6.3 创建父工程
先建一个空的 Maven 项目作为父工程,统一管理依赖版本。
pom.xml(父工程):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>microservice-demo</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.0</spring-boot.version>
<spring-cloud.version>2023.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.1.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
6.4 创建用户服务 user-service
在父工程下新建 Module:user-service。
pom.xml(user-service):
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>microservice-demo</artifactId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>user-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Nacos 服务注册发现 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> </dependencies> </project>
application.yml(user-service):
server: port: 8081 spring: application: name: user-service # 服务名,注册到 Nacos 时用的就是这个 cloud: nacos: discovery: server-addr: localhost:8848 # Nacos 地址
启动类 UserServiceApplication.java:
package com.example.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
写一个接口 UserController.java:
package com.example.user.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@GetMapping("/user/{id}")
public String getUser(@PathVariable Long id) {
return "用户-" + id + "(来自 user-service)";
}
}
6.5 创建订单服务 order-service
同样新建 Module:order-service。这次它要调用 user-service。
pom.xml(order-service):
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>microservice-demo</artifactId> <version>1.0.0</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>order-service</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- OpenFeign:声明式 HTTP 调用 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <!-- Spring Cloud LoadBalancer:负载均衡 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> </dependencies> </project>
application.yml(order-service):
server: port: 8082 spring: application: name: order-service cloud: nacos: discovery: server-addr: localhost:8848
启动类 OrderServiceApplication.java(注意加上 @EnableFeignClients):
package com.example.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients // 开启 Feign 远程调用
public class OrderServiceApplication {
public static void main(String[] args) {
SpringApplication.run(OrderServiceApplication.class, args);
}
}
Feign 接口 UserClient.java(声明要调哪个服务的什么接口):
package com.example.order.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
// value 的值就是目标服务在 Nacos 里注册的名字
@FeignClient(value = "user-service")
public interface UserClient {
@GetMapping("/user/{id}")
String getUser(@PathVariable("id") Long id);
}
订单接口 OrderController.java(调用 user-service):
package com.example.order.controller;
import com.example.order.client.UserClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class OrderController {
@Autowired
private UserClient userClient;
@GetMapping("/order/{orderId}")
public String getOrder(@PathVariable Long orderId) {
// 远程调用 user-service
String userInfo = userClient.getUser(1L);
return "订单-" + orderId + ",关联用户信息:" + userInfo;
}
}
6.6 启动与验证
按顺序启动:
1. Nacos(已经在跑了) 2. UserServiceApplication(user-service,启动后去 Nacos 控制台能看到它) 3. OrderServiceApplication(order-service,同样会注册到 Nacos)
验证调用链:浏览器访问 http://localhost:8082/order/100
你应该看到:
订单-100,关联用户信息:用户-1(来自 user-service)
发生了什么?
-
浏览器请求 order-service 的
/order/100 -
order-service 通过 Feign 去 Nacos 查到 user-service 的地址
-
Feign 发 HTTP 请求到 user-service 的
/user/1 -
user-service 返回字符串
-
order-service 拼上自己的内容,返回给浏览器
这就是一次最基础的微服务远程调用。
6.7 完整项目结构
microservice-demo/ ├── pom.xml # 父工程 ├── user-service/ │ ├── pom.xml │ └── src/main/ │ ├── java/com/example/user/ │ │ ├── UserServiceApplication.java │ │ └── controller/ │ │ └── UserController.java │ └── resources/ │ └── application.yml └── order-service/ ├── pom.xml └── src/main/ ├── java/com/example/order/ │ ├── OrderServiceApplication.java │ ├── controller/ │ │ └── OrderController.java │ └── client/ │ └── UserClient.java └── resources/ └── application.yml
七、微服务不是银弹:什么时候别用?
微服务不是越微越好,以下情况建议老老实实用单体:
-
🚫 团队不到 5 个人
-
🚫 项目刚起步,需求还不明确
-
🚫 业务逻辑简单,没有高并发压力
-
🚫 团队没有 DevOps 经验和容器化基础
Martin Fowler 的建议:先单体,等真正遇到单体的瓶颈了再拆。不要为了微服务而微服务。
八、推荐学习路线
第1步:理解概念 + 关键词(本文第五、六节) ↓ 第2步:跟着第六节跑通第一个微服务调用链 ↓ 第3步:学 Spring Boot(微服务的基础,一个服务就是一个 Spring Boot 项目) ↓ 第4步:深入 Nacos(服务注册 + 配置中心二合一,阿里出品) ↓ 第5步:深入 OpenFeign(服务间 HTTP 调用) ↓ 第6步:学 Sentinel(熔断降级) ↓ 第7步:学 Gateway(API 网关) ↓ 第8步:学 Docker + 基本部署 ↓ 第9步:做一个小项目,比如拆一个单体电商系统
写在最后
微服务是一门实践性很强的技术。概念看再多,不如亲手拆一个项目。建议用 Spring Cloud Alibaba 全家桶入门,国内生态最完善,文档也是中文的,对新手友好。
有问题欢迎在评论区交流,一起进步 🚀
更多推荐

所有评论(0)