快速开始 #

一、项目规划 #

1.1 项目结构 #

我们将创建一个简单的微服务项目,包含以下模块:

text
spring-cloud-demo/
├── pom.xml                          # 父工程POM
├── eureka-server/                   # 注册中心
│   ├── pom.xml
│   └── src/main/java/
│       └── com/example/eureka/
│           └── EurekaServerApplication.java
├── service-provider/                # 服务提供者
│   ├── pom.xml
│   └── src/main/java/
│       └── com/example/provider/
│           ├── ProviderApplication.java
│           └── controller/
│               └── HelloController.java
└── service-consumer/                # 服务消费者
    ├── pom.xml
    └── src/main/java/
        └── com/example/consumer/
            ├── ConsumerApplication.java
            └── controller/
                └── ConsumerController.java

1.2 技术选型 #

组件 版本
JDK 17
Spring Boot 3.2.0
Spring Cloud 2023.0.0
注册中心 Eureka

二、创建父工程 #

2.1 创建项目目录 #

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

2.2 父工程POM #

创建 pom.xml

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>

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

    <modules>
        <module>eureka-server</module>
        <module>service-provider</module>
        <module>service-consumer</module>
    </modules>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot BOM -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Spring Cloud BOM -->
            <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>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
</project>

三、创建注册中心 #

3.1 创建模块 #

bash
mkdir -p eureka-server/src/main/java/com/example/eureka
mkdir -p eureka-server/src/main/resources

3.2 模块POM #

创建 eureka-server/pom.xml

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>
        <!-- Eureka Server -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3.3 启动类 #

创建 EurekaServerApplication.java

java
package com.example.eureka;

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

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

3.4 配置文件 #

创建 application.yml

yaml
server:
  port: 8761

spring:
  application:
    name: eureka-server

eureka:
  instance:
    hostname: localhost
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

3.5 启动测试 #

bash
cd eureka-server
mvn spring-boot:run

访问 http://localhost:8761 查看Eureka控制台。

四、创建服务提供者 #

4.1 创建模块 #

bash
mkdir -p service-provider/src/main/java/com/example/provider/controller
mkdir -p service-provider/src/main/resources

4.2 模块POM #

创建 service-provider/pom.xml

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>service-provider</artifactId>

    <dependencies>
        <!-- Eureka Client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

4.3 启动类 #

创建 ProviderApplication.java

java
package com.example.provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

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

4.4 控制器 #

创建 HelloController.java

java
package com.example.provider.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/hello/{name}")
    public String hello(@PathVariable String name) {
        return "Hello " + name + "! From Provider, Port: " + port;
    }
}

4.5 配置文件 #

创建 application.yml

yaml
server:
  port: 8001

spring:
  application:
    name: service-provider

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

五、创建服务消费者 #

5.1 创建模块 #

bash
mkdir -p service-consumer/src/main/java/com/example/consumer/controller
mkdir -p service-consumer/src/main/resources

5.2 模块POM #

创建 service-consumer/pom.xml

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>service-consumer</artifactId>

    <dependencies>
        <!-- Eureka Client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        
        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- LoadBalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

5.3 启动类 #

创建 ConsumerApplication.java

java
package com.example.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

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

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

需要添加导入:

java
import org.springframework.cloud.client.loadbalancer.LoadBalanced;

5.4 控制器 #

创建 ConsumerController.java

java
package com.example.consumer.controller;

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;
import org.springframework.web.client.RestTemplate;

@RestController
public class ConsumerController {

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/consume/{name}")
    public String consume(@PathVariable String name) {
        String url = "http://service-provider/hello/" + name;
        return restTemplate.getForObject(url, String.class);
    }
}

5.5 配置文件 #

创建 application.yml

yaml
server:
  port: 9001

spring:
  application:
    name: service-consumer

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

六、启动测试 #

6.1 启动顺序 #

text
1. 启动 Eureka Server (端口8761)
2. 启动 Service Provider (端口8001)
3. 启动 Service Consumer (端口9001)

6.2 验证服务注册 #

访问 http://localhost:8761,查看服务是否注册成功:

text
Application           AMIs    Availability Zones    Status
SERVICE-PROVIDER      n/a     (1)                   UP (1) - 192.168.1.100:service-provider:8001
SERVICE-CONSUMER      n/a     (1)                   UP (1) - 192.168.1.100:service-consumer:9001

6.3 测试服务调用 #

bash
# 直接调用服务提供者
curl http://localhost:8001/hello/World
# 输出: Hello World! From Provider, Port: 8001

# 通过消费者调用
curl http://localhost:9001/consume/World
# 输出: Hello World! From Provider, Port: 8001

七、多实例测试 #

7.1 启动多个提供者 #

bash
# 第一个实例(默认端口8001)
cd service-provider
mvn spring-boot:run

# 第二个实例(端口8002)
mvn spring-boot:run -Dspring-boot.run.arguments=--server.port=8002

7.2 验证负载均衡 #

多次调用消费者接口,观察端口变化:

bash
for i in {1..10}; do
    curl http://localhost:9001/consume/Test
    echo ""
done

输出示例:

text
Hello Test! From Provider, Port: 8001
Hello Test! From Provider, Port: 8002
Hello Test! From Provider, Port: 8001
Hello Test! From Provider, Port: 8002
...

八、常见问题 #

8.1 服务注册失败 #

问题: 服务未在Eureka显示

排查步骤:

yaml
# 检查配置
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
    enabled: true

8.2 服务调用失败 #

问题: 调用时报错 UnknownHostException

解决方案: 确保使用服务名而非IP调用,并添加 @LoadBalanced 注解

8.3 端口冲突 #

问题: 端口被占用

解决方案: 修改 application.yml 中的端口配置

九、总结 #

9.1 核心要点 #

要点 说明
父工程 使用BOM管理版本
注册中心 Eureka Server提供服务注册
服务提供者 注册到Eureka并提供服务
服务消费者 通过服务名调用服务

9.2 下一步 #

现在你已经创建了第一个微服务项目,接下来让我们学习 核心概念,深入理解微服务架构的核心原理!

最后更新:2026-03-28