微服务架构设计实战:从单体到分布式(新手友好版)

架构师Data
2025-06-23 14:39
阅读 586

开篇:微服务到底是什么?

开篇:微服务到底是什么?

在传统的开发中,很多项目都是“单体应用”——也就是所有功能都写在一个程序里,像一块大石头。比如一个电商系统,商品、订单、支付、用户管理等模块都在一个系统里面。这种做法简单易懂,但问题是:

  • 系统太大会导致开发困难
  • 一旦某个模块出问题,整个系统都可能崩溃
  • 想用不同技术栈?几乎不可能

于是,“微服务架构”应运而生。

📌 什么是微服务?

微服务是一种软件架构风格,把原本庞大的一个系统拆分成多个小的服务,每个服务独立运行、部署、维护。

打个比方: 如果你要做一锅汤,以前是全部材料一起下锅煮(单体); 现在则是先分别煮好鸡肉汤、蔬菜汤、海鲜汤,最后再混合在一起(微服务)。

这样做的好处是:

  • 易于开发和维护
  • 出问题只影响其中一个服务,而不是整个系统
  • 不同服务可以用不同的编程语言或数据库

听起来是不是很酷?接下来,我们就来一步步动手实践!


环境准备:你只需要几个工具

环境准备:你只需要几个工具

我们使用 Java + Spring Boot + Maven + REST API + Docker 来做这个简单的实战。以下是安装步骤:

✅ 安装步骤:

1. 安装 Java(JDK)

2. 安装 IDE(开发工具)

推荐使用 IntelliJ IDEA 社区版VSCode + Java插件

3. 安装 Maven

Maven 是用来管理依赖包的工具

4. 安装 Postman(可选,测试接口用)

下载地址:https://www.postman.com/downloads/

5. 安装 Docker(稍后使用)

📌 小贴士:
安装过程中如果遇到权限问题,可以右键以管理员身份运行安装程序。


核心概念讲解(通俗易懂)

为了理解微服务,我们需要先认识几个关键概念:

名词 含义解释
服务 一个完成特定业务功能的小应用,比如“用户服务”、“订单服务”
API 接口 服务之间通信的方式,就像人与人之间交流的语言
注册中心 所有服务都在这里“报到”,其他服务可以通过它找到对方
网关 所有请求都会经过网关,由它统一管理路由、安全、负载均衡等
配置中心 存放所有服务的配置文件,避免重复修改
负载均衡 当多个实例同时运行时,平衡请求压力,提高可用性

⚠️ 初学者常见误区:
认为“服务越多越好”是错误的。微服务不是越多越好,而是要根据业务逻辑合理拆分。


实战项目:搭建两个微服务,并实现互相调用

我们要做一个最基础的例子:

  • 用户服务:提供用户信息
  • 商品服务:显示用户购买的商品信息

这两个服务将通过 REST API 相互调用。


第一步:创建父项目(多模块结构)

打开IDEA → 新建项目 → Maven → 创建一个空项目作为父工程
名字叫:microservice-demo

然后在这个父项目下面创建两个子模块:

  • user-service
  • product-service

目录结构如下:

microservice-demo/
├── pom.xml
├── user-service/
│   └── pom.xml
└── product-service/
    └── pom.xml

📌 Tips:这样做是为了便于管理多个服务的公共依赖。


第二步:创建用户服务(user-service)

1. 添加依赖项(Spring Boot)

打开 user-service/pom.xml 文件,添加以下内容:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

2. 编写用户Controller类

新建一个包,例如:com.example.user.controller

创建一个Java类:

@RestController
@RequestMapping("/users")
public class UserController {

    @GetMapping("/{id}")
    public String getUser(@PathVariable Long id) {
        return "User ID: " + id + ", Name: 张三";
    }
}

3. 启动类

创建主启动类:

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

4. 配置端口

resources/application.yml 中添加:

server:
  port: 8081

现在你可以运行这个服务了。浏览器访问:http://localhost:8081/users/1
应该会看到输出:User ID: 1, Name: 张三


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

同样,先加依赖、写代码、启动类、配置端口:

pom.xml 中添加同样的依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

写ProductController:

@RestController
@RequestMapping("/products")
public class ProductController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/{userId}")
    public String getProduct(@PathVariable Long userId) {
        String url = "http://localhost:8081/users/" + userId;
        String response = restTemplate.getForObject(url, String.class);
        return "用户:" + response + " 购买了 iPhone 16!";
    }
}

启动类:

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

application.yml 设置端口:

server:
  port: 8082

运行这个服务,访问:http://localhost:8082/products/1
你会看到返回:

用户:User ID: 1, Name: 张三 购买了 iPhone 16!

🎉 恭喜!你已经完成了第一个“微服务之间的调用”!


第四步:引入注册中心(Eureka Server)

目前我们是直接通过 URL 地址调用用户服务,这种方式在微服务环境下不方便。真正的做法是让服务自己去“注册中心”注册,其他服务再去查找。

我们使用 Netflix 提供的 Eureka 做注册中心。

1. 创建 eureka-server 模块

在父项目 microservice-demo 中新增子模块:eureka-server

2. 添加 Eureka Server 依赖

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

3. 配置 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/

4. 主启动类加上注解:

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

运行这个模块。访问 http://localhost:8761 看到Eureka界面即说明启动成功。


第五步:让用户服务注册到 Eureka

修改 user-service 模块:

1. 加入 Eureka Client 依赖:

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

2. 修改 yml 文件:

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka
spring:
  application:
    name: user-service

重新运行 user-service,刷新Eureka页面,你应该能看到 user-service 已注册。


第六步:让商品服务通过服务名调用用户服务

现在我们不靠 IP+端口了,而是通过服务名调用:

修改 product-service 的 controller:

@GetMapping("/{userId}")
public String getProduct(@PathVariable Long userId) {
    String url = "http://user-service/users/" + userId;
    String response = restTemplate.getForObject(url, String.class);
    return "用户:" + response + " 购买了 iPhone 16!";
}

API接口文档-1

注意:此时必须开启“服务发现”的功能。

在 product-service 的启动类上加注解:

@EnableDiscoveryClient

运行 product-service,再次访问 /products/1,仍然可以看到正确结果!


第七步:使用 Ribbon 实现负载均衡

当有多个 user-service 实例时,我们需要让它自动选择一个来处理请求。

1. 在 product-service 添加 Ribbon 依赖:

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

2. 在 RestTemplate 上加 @LoadBalanced 注解

修改配置类或在main方法中:

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

现在你可以启动多个 user-service 实例(改端口),你会发现请求会被平均分配。


常见问题解答(FAQ)

Q1:我启动服务时报错 Cannot connect to database.

A:本教程未涉及数据库操作,所以请确保你的代码没有数据库配置或相关依赖。

Q2:为什么 product-service 调用 user-service 的时候能用服务名称?

A:因为我们用了 Eureka 和 Ribbon,它们内部做了 DNS 解析和服务发现。

Q3:服务注册不上怎么办?

A:检查 Eureka Server 是否运行正常,服务的 application.name 是否配置正确。

Q4:RESTful API 和普通接口有什么区别?

A:RESTful 更强调使用 HTTP 方法(GET、POST、PUT、DELETE)来表达资源操作,更规范、易读、标准化。


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

恭喜你完成了入门实战!接下来你可以深入学习以下几个方向:

  1. Spring Cloud Gateway:替代传统的 Zuul 网关,统一入口管理
  2. Config Server:统一管理各服务配置
  3. Sleuth & Zipkin:微服务链路追踪,方便排查问题
  4. Docker + Kubernetes:容器化部署微服务集群
  5. 消息队列(如 RabbitMQ / Kafka):异步处理、事件驱动
  6. OAuth2 / JWT:微服务权限控制体系

📌 推荐学习路线图:

Spring Boot → REST API → Eureka → Feign/Ribbon → Gateway → Config → Kubernetes

总结

在这篇文章中,我们从零开始,搭建了一个基础的微服务项目,实现了两个服务之间的通信、服务注册与发现、以及简单的负载均衡。

虽然只是冰山一角,但这正是通向分布式世界的第一步!

🔥 继续加油,未来你可以构建出一个高性能、高可用的微服务系统!

如果你觉得这篇文章对你有帮助,请点赞、收藏、转发给更多初学者!

评论 0

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