搭建项目骨架

万丈高楼平地起。

接下来,笔者进行微服务架构项目第一个步骤的编码:新建一个文件夹,把项目的基础骨架搭建出来。

由于已经构建过 Spring Cloud Alibaba 整合服务治理后的多模块模板项目,因此这里直接使用 spring-cloud-alibaba-multi-service-demo 进行简单的改造即可。

构建项目并整理依赖关系

先把项目名称修改为 newbee-mall-cloud-dev-step01,再将 order-service-demo 修改为 newbee-mall-cloud-gateway-admin、将 shopcart-service-demo 修改为 newbee-mall-cloud-user-service,并删除 goods-service-demo 模块(本开发步骤中只需要两个 Maven 模块),然后删除 newbee-mall-cloud-gateway-admin 项目和 newbee-mall-cloud-user-service 项目中已存在的包和代码,只保留项目中基础的 Maven 目录结构。

下面整理项目中的依赖项和依赖关系。

修改 root 节点的 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ltd.newbee.cloud</groupId>
    <artifactId>newbee-mall-cloud</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>newbee-mall-cloud</name>
    <packaging>pom</packaging>
    <description>新蜂商城微服务版本(Spring Cloud Alibaba)</description>
    <modules>
        <module>newbee-mall-cloud-user-service</module>
        <module>newbee-mall-cloud-gateway-admin</module>
    </modules>
    <properties>
        <spring.boot.version>2.6.3</spring.boot.version>
        <spring.cloud.dependencies.version>2021.0.1</spring.cloud.dependencies.version>
        <spring.cloud.alibaba.version>2021.0.1.0</spring.cloud.alibaba.version>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring.cloud.dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <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>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring.cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${spring.boot.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>central</id>
            <url>https://maven.aliyun.com/repository/central</url>
            <name>aliyun maven</name>
        </repository>
    </repositories>
</project>

主要工作是配置项目的名称和模块的依赖关系,同时管理和配置 Spring Cloud Alibaba 基础依赖、微服务发现依赖和网关依赖。

子节点 newbee-mall-cloud-gateway-adminpom.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ltd.newbee.cloud</groupId>
    <artifactId>newbee-mall-cloud-gateway-admin</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>newbee-mall-cloud-gateway-admin</name>
    <description>网关模块</description>

    <parent>
        <groupId>ltd.newbee.cloud</groupId>
        <artifactId>newbee-mall-cloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>
</project>

这是一个网关微服务,主要引入 Spring Cloud Gateway 依赖、微服务发现依赖负载均衡依赖

子节点 newbee-mall-cloud-user-servicepom.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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>ltd.newbee.cloud</groupId>
    <artifactId>newbee-mall-cloud-user-service</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>newbee-mall-cloud-user-service</name>
    <description>用户微服务</description>

    <parent>
        <groupId>ltd.newbee.cloud</groupId>
        <artifactId>newbee-mall-cloud</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>
</project>

这是整个实战项目中的用户微服务,主要引入 微服务发现依赖Web 开发依赖。因为这是开发的第一个步骤,所以主要测试基础功能和代码,后续会引入 MyBatisMySQLSwagger 等实际开发时的依赖。

以上操作主要保证基础目录搭建成功、微服务注册成功、网关层能够正常与微服务实例通信,并且项目中没有代码报错。以上操作顺利完成后,再往项目中加入业务代码。不急,一步一步来。

编写测试代码

  1. newbee-mall-cloud-user-service 项目编码

    打开 newbee-mall-cloud-user-service 项目,新建 ltd.user.cloud.newbee 包。之后创建启动类 NewBeeMallCloudUserServiceApplication,代码如下:

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

    新建 ltd.user.cloud.newbee.controller 包,在该包下新建 NewBeeMallCloudAdminUserController 类,并添加一个测试接口,代码如下:

    package ltd.user.cloud.newbee.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 NewBeeMallCloudAdminUserController {
    
        @GetMapping("/users/admin/test/{userId}")
        public String test(@PathVariable("userId") int userId) {
            String userName = "user:" + userId;
            // 返回信息给调用端
            return userName;
        }
    }

    修改该项目的配置文件,application.properties 文件代码如下:

    server.port=29000
    
    server.servlet.encoding.charset=UTF-8
    server.servlet.encoding.force=true
    server.servlet.encoding.enabled=true
    
    # 微服务名称
    spring.application.name=newbee-mall-cloud-user-service
    # Nacos地址
    spring.cloud.nacos.discovery.server-addr=localhost:8848
    # Nacos登录用户名(默认为nacos,在生产环境中一定要修改)
    spring.cloud.nacos.username=nacos
    # Nacos登录密码(默认为nacos,在生产环境中一定要修改)
    spring.cloud.nacos.password=nacos

    这里主要配置微服务名称、启动端口号,修改服务中心的相关配置项。

  2. newbee-mall-cloud-gateway-admin 项目编码

    打开 newbee-mall-cloud-gateway-admin 项目,并新建 ltd.gateway.cloud.newbee 包。之后创建启动类 NewBeeMallCloudAdminGatewayApplication,代码如下:

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

    修改该项目的配置文件,application.properties 文件中的配置项如下:

    server.port=29100
    
    server.servlet.encoding.charset=UTF-8
    server.servlet.encoding.force=true
    server.servlet.encoding.enabled=true
    
    # 微服务名称
    spring.application.name=newbee-mall-cloud-gateway-admin
    # Nacos 地址
    spring.cloud.nacos.discovery.server-addr=localhost:8848
    # Nacos 登录用户名(默认为 nacos,在生产环境中一定要修改)
    spring.cloud.nacos.username=nacos
    # Nacos 登录密码(默认为 nacos,在生产环境中一定要修改)
    spring.cloud.nacos.password=nacos
    # 网关开启服务注册与微服务发现
    spring.cloud.gateway.discovery.locator.enabled=true
    spring.cloud.gateway.discovery.locator.lower-case-service-id=true
    
    # 用户微服务的路由配置
    spring.cloud.gateway.routes[0].id=user-service-route
    spring.cloud.gateway.routes[0].uri=lb://newbee-mall-cloud-user-service
    spring.cloud.gateway.routes[0].order=1
    spring.cloud.gateway.routes[0].predicates[0]=Path=/users/admin/**

    这里主要配置微服务名称、启动端口号、路由,修改服务中心的相关配置项。

    上述操作完成后,项目的目录结构如图 2-1 所示。

  3. 效果演示

接下来需要启动 Nacos Server,之后依次启动这两个项目。如果未能成功启动,那么开发者需要查看控制台中的日志是否报错,并及时确认问题和修复。启动成功后进入 Nacos 控制台,单击 “服务管理” 中的服务列表,就可以看到列表中已经存在这两个微服务的信息了。

打开浏览器并在地址栏中输入如下网址: http://localhost:29000/users/admin/test/13

响应结果如图 2-2 所示。

image 2025 04 23 11 16 50 454
Figure 1. 图2-1 项目的目录结构
image 2025 04 23 11 18 32 993
Figure 2. 图2-2 响应结果

验证网关层与用户微服务是否能够正常通信。打开浏览器并在地址栏中输入如下网址: http://localhost:29100/users/admin/test/13

响应结果如图 2-3 所示。

image 2025 04 23 11 19 15 555
Figure 3. 图2-3 通过网关层访问的响应结果

希望读者能够根据笔者提供的开发步骤顺利地完成开发工作。

万事开头难。这句话对 newbee-mall-cloud 实战项目的开发同样适用。凭空开发一个微服务架构项目,对大部分开发人员来说都会有一定的难度,笔者刚开始做这个实战项目教程的时候同样有些束手束脚,会遇到如 “先做哪一步呢?”、“先引入哪个组件呢?”、“先改造哪个微服务呢?”、“先配置什么东西呢?” 之类的问题。

在开发前期肯定要保证项目结构、依赖关系都配置正确。同时,要保证微服务实例能够正常注册到服务中心,服务接口能够正常调用。当然,这里也加了网关模块,没有选择在开发后期引入网关服务,主要是为了在保证服务正常通信的同时,网关模块能够正常使用。虽然只是短短的一节内容,但是涉及的知识点是非常多的,如 Spring Cloud Alibaba 依赖配置、微服务实例与服务中心 Nacos 的通信、网关服务 Spring Cloud Gateway 的配置等。