微服务架构实战项目打包和部署的注意事项

项目源码拿到了,在 IDEA 中对项目进行编码修改和功能测试也完成了,终于到了打包和部署的环节。其实步骤并不复杂,只需要在命令行中进入当前项目的顶级目录,然后执行 Maven 的打包命令。

命令如下:

mvn clean package -Dmaven.test.skip
bash

经过一段时间的等待后,项目中的所有模块都按照 pom.xml 文件中的配置 “打包成功” 了,如图 14-46 所示。

用户微服务、购物车微服务、推荐微服务、商品微服务、订单微服务和两个服务网关实例都会被打包成一个可执行的 Jar 包,如 newbee-mall-cloud-user-web-0.0.1-SNAPSHOT.jarnewbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar 等可执行文件。打包成功后,进入对应的 target 目录中启动 Jar 包来启动不同的微服务实例。

image 2025 04 18 17 34 09 198
Figure 1. 图14-46 newbee-mall-cloud 项目打包过程

执行的命令如下:

javar -jar xxxx.jar
bash

以启动商品微服务为例,进入 newbee-mall-cloud-goods-web/target 目录,执行 java-jarnewbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar 命令启动商品微服务实例。

是的,没有成功,启动时报错了,如图 14-47 所示。Jar 中没有主清单属性。不止是商品微服务,网关实例也没有启动成功,报错内容相同,这就说明打的包存在问题。

这是一个微服务架构的多模块项目,多模块项目中又包含多个 Spring Boot 项目,用户微服务、购物车微服务、推荐微服务、商品微服务、订单微服务和两个服务网关实例其实都是 Spring Boot 项目。在这种多模块、多 Spring Boot 实例的项目中,需要在 pom.xml 文件中增加一些配置,不然打包后的 Jar 包就无法正常启动。

这里涉及一个知识点:“使用 Maven 构建多个 Spring Boot 实例”。这个知识点其实不常碰到,平时开发的基本是单个的 Spring Boot 项目,打包时肯定不会遇到这个问题,而开发复杂架构下的项目则会遇到这个问题。解决办法也不复杂,在对应的 pom.xml 文件中加入一些打包所需的 plugin 并指定对应实例的主启动类的全类名。

image 2025 04 18 17 35 06 323
Figure 2. 图14-47 报错信息

打开用户微服务、购物车微服务、推荐微服务、商品微服务、订单微服务和两个服务网关实例所对应的 newbee-mall-cloud-xxx-web 工程目录,并在各自的 pom.xml 文件中增加一些配置,下面以商品微服务和商城端网关为例讲解。

打开 newbee-mall-cloud-goods-web 目录下的 pom.xml 文件,在原配置的基础上增加如下代码:

<build>
    <resources>
        <resource>
            <filtering>true</filtering>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>ltd.goods.cloud.newbee.NewBeeMallCloudGoodsService
                    Application</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
xml

增加打包所需的 plugin 插件并指定商品微服务主启动类 NewBeeMallCloudGoodsServiceApplication 类的全类名。

打开 newbee-mall-cloud-gateway-mall 目录下的 pom.xml 文件,在原配置的基础上增加如下代码:

<!-- 打包 -->
<build>
    <resources>
        <resource>
            <filtering>true</filtering>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <configuration>
                <encoding>${project.build.sourceEncoding}</encoding>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <mainClass>itd.gateway.cloud.newbee.NewBeeMallCloudMallGatewayApplication</mainClass>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
xml

同样增加打包所需的 plugin 插件并指定网关层主启动类 NewBeeMallCloudMallGatewayApplication 类的全类名。其他需要打包成 Jar 包模块下的 pom.xml 配置文件也需要增加上述的打包配置项,这里就不再赘述了。

配置完成后,进入当前项目的顶级目录,执行 Maven 的打包命令。打包成功后,再次执行启动 Jar 包的命令,可以看到 “Jar 中没有主清单属性”的问题已经不存在了,Jar 包可以顺利启动,一切正常,如图 14-48 所示。

image 2025 04 18 17 40 01 401
Figure 3. 图14-48 newbee-mall-cloud 项目打包和项目启动过程

项目打包和项目部署是两个步骤,获得各个微服务实例的可执行 Jar 包后,就可以进入部署环节了,不管是部署在服务器还是部署在本地,基本上都是在命令行执行 java -jar 命令。

这里讲几个在 Linux 服务器上部署时的注意事项。

启动命令:

java -jar newbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar
bash

这样启动的项目并没有在后台运行,一旦退出终端项目基本上就跟着停掉了,这时就需要在命令行前后分别添加 nohup 命令和 & 符号,这样就能够让项目一直在后台运行,并且项目的运行日志会输出到 nohup.out 文件中,此时的命令如下:

nohub java -jar newbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar &
bash

想要关闭这个项目,可以查询它运行时的进程号,之后用 kill 命令关闭它。

想要部署服务集群,可以使用 --server.port 参数指定多个端口号。以部署商品微服务集群为例,执行的命令如下:

#启动时使用 application.properties 配置文件中配置的端口号 29010
nohup java -jar newbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar &
#启动时自定义端口号
nohup java -jar newbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar --server.port=29011 &
nohup java -jar newbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar --server.port=29012 &
bash

这样就可以部署成一个微服务实例的集群了,这些启动后的 Jar 包实例都会将自己注册到 Nacos Server 中,被其他微服务调用时也会根据负载均衡算法提供服务。

另外,如果服务器中的内存并不宽裕,则启动过多的微服务实例可能有些吃力,此时可以在启动命令中添加 JVM 参数限制一下项目消耗的内存资源,执行的命令如下:

nohup java -jar -server -Xms128m -Xmx384m newbee-mall-cloud-goods-web-0.0.1-SNAPSHOT.jar &
bash

至此,本节的内容介绍完毕。

虽然新蜂商城项目微服务版本的功能模块已经全部讲解完,但是新蜂商城的优化和迭代工作不会停止,更新和优化的内容都会上传到开源仓库中供读者学习和使用。行文至此,笔者万般不舍。在本书的最后,诚心地祝愿各位读者能够在编程道路上寻找到属于自己的精彩!