微服务架构设计实战:从单体到分布式

分布式背锅侠
2025-06-22 17:09
阅读 325

开篇:微服务到底是什么?我们为什么要用它?

开篇:微服务到底是什么?我们为什么要用它?

你可能听说过“微服务”这个词,它听起来很高大上,但其实它的核心思想非常简单。

微服务(Microservices)是一种软件架构风格,它把一个大型的、复杂的系统拆分成多个小而独立的服务。每个服务可以单独开发、部署和运行,并通过网络来互相通信。

举个简单的例子:你有一个电商网站,原来是一个整体(叫单体架构),里面有用户管理、商品管理、订单管理等模块。如果所有功能都在一个应用里,随着功能变多,代码越来越难维护,修改一小部分都可能导致整个系统崩溃。

而使用微服务后,你可以把这个电商系统拆成:

  • 用户服务
  • 商品服务
  • 订单服务

这些服务各自独立,互不干扰,甚至可以用不同的编程语言来编写。它们之间通过API互相调用。

这样做的好处是:

  • 更容易维护和升级
  • 可以分别扩展性能强的部分(比如订单量大,就多给订单服务加服务器)
  • 团队可以分工协作,各管一块

现在,我们就一步一步带你了解并实践这个架构模式。


环境准备:你需要安装什么?

环境准备:你需要安装什么?

为了方便演示,我们会使用以下工具和技术栈:

  • Java 17+
  • Spring Boot + Spring Cloud(用来快速构建微服务)
  • Maven(项目依赖管理)
  • IDE:IntelliJ IDEA 或 Eclipse
  • Postman(用于测试接口)

步骤 1:安装 Java 和 Maven

  • 安装 JDK 17(推荐使用 Azul Zulu
  • 验证是否安装成功,在命令行中输入:
java -version
mvn -v

步骤 2:安装 IntelliJ IDEA

步骤 3:安装 Postman


核心概念解释:零基础也能懂的专业术语

核心概念解释:零基础也能懂的专业术语

在开始写代码前,我们先来理解几个关键概念,我会用生活中的例子来比喻,帮助你更直观地理解。

1. 单体 vs 微服务

类型 特点 比如说
单体应用 所有功能在一个程序里,部署在一起 一锅大杂烩
微服务 功能被拆分成多个服务,各自独立运行 一道道分开上的菜品

2. API(Application Programming Interface)

想象你去饭店点菜,你不需要知道厨房怎么做菜,只需要和服务员沟通菜单。这里的“菜单”就是 API。

微服务之间通过 API 进行通信,最常见的是 RESTful API。

3. 注册中心(Service Discovery)

在饭店人多的时候,顾客怎么知道自己点的菜是在哪个厨师手里处理?饭店需要一个调度员,帮你找对的人。

注册中心就像一个服务地图,告诉别的服务:“我在哪”。

常见的注册中心有:Eureka(Spring Cloud 提供)、Consul、Nacos。

4. 负载均衡(Load Balancing)

有时候一个服务员忙不过来,就需要多个服务员一起接待客户。

负载均衡就是自动帮你分配请求给不同服务实例的技术。

Spring Cloud 提供了 Ribbon 来实现负载均衡。

5. 网关(API Gateway)

还是那个饭店的例子:顾客进店前,都需要先经过前台,由前台安排座位或引导到服务员那里。

网关就是一个统一入口,负责身份验证、路由、限流等任务。

Spring Cloud Gateway 是一个常用的网关实现。


实战项目:搭建一个简单的微服务电商系统

实战项目:搭建一个简单的微服务电商系统

我们将一步步搭建一个包含用户服务、商品服务和订单服务的小型电商平台,采用 Spring Boot + Spring Cloud 实现。

第一步:创建 Eureka 注册中心

创建父工程(可选)

新建一个 Maven 工程,作为我们的总项目结构(名称随意,比如 microservice-demo)。

新建 Eureka Server 模块

  1. 使用 Spring Initializr 创建一个新项目:

    • 项目名:eureka-server
    • 依赖项:Spring Web, Eureka Server
  2. 在主类加上注解开启 Eureka:

@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}
  1. 修改 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/

启动后访问 http://localhost:8761 可看到 Eureka 的仪表盘界面。


第二步:创建第一个服务——用户服务 user-service

创建项目

使用 Spring Initializr 创建项目:

  • 名称:user-service
  • 依赖:Spring Web, Eureka Discovery Client

主类代码:

@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserServiceApplication.class, args);
    }
}

添加用户接口:

@RestController
@RequestMapping("/users")
public class UserController {
    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        return "User ID: " + id;
    }
}

配置 application.yml:

server:
  port: 8081

spring:
  application:
    name: user-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/

启动后回到 Eureka 页面可以看到 “user-service” 注册成功。


第三步:创建商品服务 product-service

重复上面步骤:

  • 项目名:product-service
  • 接口示例:
@GetMapping("/{id}")
public String getProduct(@PathVariable Long id) {
    return "Product ID: " + id;
}
  • 端口改为 8082,服务名改为 product-service

第四步:创建订单服务 order-service(调用其他服务)

我们需要让它能访问用户服务和商品服务。

主类添加 Eureka 客户端:

@EnableEurekaClient

添加 RestTemplate Bean(用于服务间调用):

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

编写 OrderController:

@Autowired
private RestTemplate restTemplate;

@GetMapping("/detail/{userId}/{productId}")
public String getOrderDetail(@PathVariable Long userId, @PathVariable Long productId) {
    String user = restTemplate.getForObject("http://user-service/users/" + userId, String.class);
    String product = restTemplate.getForObject("http://product-service/products/" + productId, String.class);
    return "Order Detail:\n" + user + "\n" + product;
}

这样,订单服务就能调用其他两个服务的数据了!


第五步:启动所有服务,测试接口

顺序依次为:

  1. 启动 Eureka Server(8761)
  2. 启动 user-service(8081)
  3. 启动 product-service(8082)
  4. 启动 order-service(默认端口 8080)

使用 Postman 测试:

访问:http://localhost:8080/order/detail/1001/2001

返回:

Order Detail:
User ID: 1001
Product ID: 2001

🎉恭喜!你已经完成了你的第一个微服务项目!


常见问题解答(FAQ)

Q1:为什么启动时报错“Application run failed”,或者找不到 bean?

可能是依赖没有正确导入,检查 pom.xml 中是否有正确的依赖,例如:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

也可以尝试重新导入 Maven 依赖。


Q2:服务之间无法互相调用,返回 404?

检查服务是否已注册到 Eureka,可以通过访问 Eureka 的页面查看状态。

另外确认接口路径是否正确,以及是否开启了负载均衡器。


Q3:RestTemplate 报错“UnknownHostException”

请确保你的 application.yml 中服务名字拼写正确,并且 Eureka 已正确配置。


Q4:我想用 Nacos 替代 Eureka 怎么办?

后续学习可以考虑替换为 Nacos,只需替换依赖并修改配置。这属于进阶内容。


学习建议:下一步该怎么学?

当你掌握了本教程的内容之后,可以继续深入以下方向:

✅ 推荐学习路径:

  1. 学习 Spring Cloud Gateway
    掌握统一入口的搭建与请求分发逻辑。

  2. 加入 Feign / OpenFeign 实现声明式远程调用
    比较 RestTemplate 更简洁的调用方式。

  3. 引入 Config Server 统一管理配置文件

  4. 掌握 Sleuth + Zipkin 实现日志追踪

  5. 结合 Docker 部署微服务

  6. 使用 Kubernetes 进行编排与集群管理

同时,推荐阅读书籍:

  • 《Spring微服务实战》
  • 《领域驱动设计精粹》
  • 《微服务设计》

如果你在学习过程中遇到任何疑问,欢迎随时回来查阅这篇文章,或者继续提问。微服务虽然看起来复杂,但只要跟着步骤一步步来,就能稳扎稳打学会它!

祝你成为优秀的后端开发者!🚀

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝