Spring Cloud 微服务从零起步:手把手教你搭建第一个分布式系统

周末写代码
2025-12-26 23:10
阅读 628

大家好,我是一名工作五年的后端工程师,也带过不少刚入行的新人。很多人一听到“微服务”“Spring Cloud”就头皮发麻,觉得这玩意儿高深莫测。其实我当初学的时候也一样——看文档像读天书,跑个 Demo 半天起不来,差点以为自己不适合干这行。

今天我就用最直白的方式,带你从零开始搭建一个真正的 Spring Cloud 微服务项目。哪怕你连“微服务”是什么都不知道,也能跟着做完!

顺便说一句:虽然标题里提到了“爬虫”和“Python”,但别担心——这不是一篇讲 Python 的文章。我们会在最后用 Python 写一个极简爬虫,用来调用我们搭建的微服务接口,这样你就能看到前后端协作的真实场景了!


为什么需要微服务?

想象一下:你开发了一个电商网站,所有功能(用户登录、商品展示、订单支付)都写在一个 Java 项目里。一开始没问题,但随着业务增长,代码越来越臃肿,改一个小功能可能要重新部署整个系统,团队协作也变得混乱。

微服务就是把大项目拆成多个小服务,每个服务独立开发、部署、运行。比如:

  • user-service 负责用户管理
  • product-service 负责商品信息
  • order-service 负责下单逻辑

它们之间通过网络互相调用,就像乐高积木一样灵活组合。

Spring Cloud 就是一套工具箱,帮你解决微服务之间的通信、配置、容错等问题。


环境准备:5 分钟搭好开发环境

⚠️ 注意:本教程基于 Java 17 + Maven + IntelliJ IDEA。如果你还没装 JDK,请先安装。

1. 安装必要软件

软件 版本建议 作用
JDK 17(推荐 OpenJDK) 运行 Java 程序
Maven 3.8+ 项目依赖管理
IntelliJ IDEA 社区版即可 代码编辑器
Python 3.8+ 最后一步写爬虫用

你可以通过命令行验证是否安装成功:

java -version    # 应显示 17.x
mvn -v           # 显示 Maven 版本
python --version # 显示 Python 3.x

2. 创建父工程(Maven 聚合项目)

微服务项目通常包含多个子模块,我们先建一个“空壳”父工程来统一管理。

在终端执行:

mkdir spring-cloud-demo
cd spring-cloud-demo

然后创建 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>spring-cloud-demo</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
        <relativePath/>
    </parent>

    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2023.0.0</spring-cloud.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <modules>
        <!-- 后面会添加子模块 -->
    </modules>
</project>

这一步只是定义了项目的基础结构,还没写任何业务代码。


核心概念:微服务三要素

在动手前,先搞懂三个关键角色:

1. 服务注册中心(Eureka)

就像公司的通讯录——每个服务启动时都要去“登记”自己的名字和地址,其他服务想调用它,就去通讯录里查。

2. 服务提供者

提供具体功能的微服务,比如返回商品列表。

3. 服务消费者

调用其他服务的微服务,比如订单服务需要调用用户服务获取用户信息。

✅ 简单记:注册中心是“中介”,提供者是“卖家”,消费者是“买家”


实战:搭建你的第一个微服务系统

我们将创建三个模块:

  • eureka-server:服务注册中心
  • product-service:商品服务(提供者)
  • order-service:订单服务(消费者)

第一步:创建 Eureka 注册中心

在项目根目录下执行:

mkdir eureka-server

eureka-server 目录中创建 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>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0.0</version>
    </parent>

    <artifactId>eureka-server</artifactId>

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

然后创建主启动类 src/main/java/com/example/EurekaServerApplication.java

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@SpringBootApplication
@EnableEurekaServer // 启用 Eureka 服务端
public class EurekaServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaServerApplication.class, args);
    }
}

再加一个配置文件 src/main/resources/application.yml

server:
  port: 8761

eureka:
  client:
    register-with-eureka: false  # 不向自己注册
    fetch-registry: false       # 不拉取注册表
  server:
    wait-time-in-ms-when-sync-empty: 0

💡 为什么端口是 8761?这是 Eureka 默认端口,约定俗成。

第二步:创建商品服务(提供者)

mkdir product-service

product-service/pom.xml

<project ...>
    <parent>
        <groupId>com.example</groupId>
        <artifactId>spring-cloud-demo</artifactId>
        <version>1.0.0</version>
    </parent>
    <artifactId>product-service</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
</project>

主启动类 ProductServiceApplication.java

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

控制器 ProductController.java

@RestController
public class ProductController {

    @GetMapping("/products/{id}")
    public Map<String, Object> getProduct(@PathVariable Long id) {
        return Map.of("id", id, "name", "iPhone 15", "price", 5999);
    }
}

配置文件 application.yml

server:
  port: 8081

spring:
  application:
    name: product-service  # 服务名,必须唯一!

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

第三步:创建订单服务(消费者)

同样创建 order-service 模块,pom.xmlproduct-service 一样。

关键区别在于:我们要调用商品服务。

主启动类加上 @EnableDiscoveryClient

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

    // 注册 RestTemplate 用于远程调用
    @Bean
    @LoadBalanced // 开启负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

订单控制器:

@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/orders/{id}")
    public String createOrder(@PathVariable Long id) {
        // 通过服务名调用,而不是 IP+端口!
        String url = "http://product-service/products/" + id;
        Map product = restTemplate.getForObject(url, Map.class);
        return "已下单:" + product.get("name");
    }
}

配置文件 application.yml

server:
  port: 8082

spring:
  application:
    name: order-service

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

第四步:启动并测试

  1. 启动 EurekaServerApplication(访问 http://localhost:8761,应看到 Eureka 面板)
  2. 启动 ProductServiceApplication
  3. 启动 OrderServiceApplication

几秒后,刷新 Eureka 页面,你会看到两个服务已注册:

Application         AMIs     Availability Zones
PRODUCT-SERVICE     1        (1)
ORDER-SERVICE       1        (1)

现在访问订单接口:

curl http://localhost:8082/orders/1001
# 返回:已下单:iPhone 15

✅ 成功!订单服务通过服务名 product-service 找到了商品服务,完全不需要知道它的 IP 和端口!


用 Python 爬虫调用微服务(资源联动)

前面提到“爬虫”和“Python”,这里我们用 Python 写一个脚本,模拟外部系统调用我们的微服务。

创建 call_order.py

import requests

def place_order(product_id):
    url = f"http://localhost:8082/orders/{product_id}"
    response = requests.get(url)
    if response.status_code == 200:
        print("✅ 订单成功:", response.text)
    else:
        print("❌ 调用失败:", response.status_code)

if __name__ == "__main__":
    place_order(1001)

安装依赖并运行:

pip install requests
python call_order.py

输出:

✅ 订单成功: 已下单:iPhone 15

🌟 这就是微服务的价值:无论你是前端、Python 脚本、手机 App,只要知道接口地址,就能使用服务!


新手常见问题 & 避坑指南

Q1:启动报错 “Cannot resolve configuration property”?

A:检查 application.yml 缩进是否正确。YAML 对空格敏感,必须用空格,不能用 Tab。

Q2:服务没出现在 Eureka 页面?

A:检查三点:

  1. 提供者/消费者是否配置了 eureka.client.service-url.defaultZone
  2. 服务名(spring.application.name)是否重复
  3. 防火墙是否阻止了 8761 端口

Q3:调用时报 UnknownHostException: product-service

A:确保 RestTemplate 加了 @LoadBalanced 注解!这是 Spring Cloud 实现服务发现的关键。

Q4:为什么不用 Nacos 而用 Eureka?

A:Eureka 是 Spring Cloud Netflix 套件中最经典的注册中心,学习曲线平缓。后续你可以无缝迁移到 Nacos、Consul 等。


下一步怎么学?

你已经迈出了微服务的第一步!接下来建议:

  1. 深入学习 Spring Cloud Alibaba(国内更流行)
  2. 加入配置中心(如 Spring Cloud Config 或 Nacos Config)
  3. 引入网关(Spring Cloud Gateway)统一入口
  4. 学习熔断机制(Sentinel 或 Hystrix)防止雪崩

📌 我的经验:不要一开始就追求“高可用”“分布式事务”。先跑通一个完整链路,再逐步优化。


结语

微服务不是银弹,但它是现代后端开发的必备技能。今天这个 Demo 虽小,却包含了服务注册、发现、调用的核心逻辑。你写的每一行代码,都是通往架构师之路的基石

如果你跟着做完了,恭喜你——你已经超越了 80% 只看不练的初学者!

有问题欢迎留言,我会一一解答。下期我们聊聊“如何用 Docker 一键部署整套微服务”。

Happy coding!

评论 0

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