- 我们有几个项目是微服务,每个项目都是独立的(在单独的 Spring Boot 服务器上运行,暴露其余服务,使用单独的 DB 模式......)
- 我们使用 maven 来管理依赖关系。
让父 pom 将每个微服务声明为模块是个好主意吗?因此有助于管理公共依赖项(例如每个项目中都使用 lib servlet-api 女巫,将其从所有项目中删除并仅在父 pom 中声明)
让父 pom 将每个微服务声明为模块是个好主意吗?因此有助于管理公共依赖项(例如每个项目中都使用 lib servlet-api 女巫,将其从所有项目中删除并仅在父 pom 中声明)
多模块父 pom 的“问题”是,如果没有复杂的配置文件,它将模块锁定在同一个发布周期中(假设您正在使用Release Plugin,您应该使用它)。
我使用 Maven 的方式是有一个父 pom 声明:
dependencyManagement
项。pluginManagement
。每个模块都将父 pom 作为其父级,但父级对模块一无所知。
这样做的好处来自上面最后两个项目符号,即“管理”部分。“管理”部分中包含的任何内容都需要在想要使用特定依赖项或插件的模块中重新声明。
例如,父级可能如下所示:
<project>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0.00-SNAPSHOT</version>
...
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>2.1</version>
</dependency>
</dependencyManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</project>
该模块可能如下所示:
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>parent</artifactId>
<version>1.0.00-SNAPSHOT</version>
</parent>
<groupId>com.example</groupId>
<artifactId>module</artifactId>
<version>1.0.00-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
</dependency>
</dependencies>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</project>
该模块将:
org.slf4j:slf4j-api:1.7.7:compile
于junit:junit:4.11:test
和commons-lang:commons-lang:2.6:compile
。org.apache.maven.plugins:maven-assembly-plugin:2.4
我会避免在父 pom 中的依赖。如果您的一个(独立)微服务需要其他一些东西,那就太尴尬了。让父母知道每个微服务是很奇怪的。
如果需要,您可以坚持使用 dependencyManagement 来建议默认版本/范围。父 pom 非常方便地定义插件、存储库等。
相反,我会将一组常见的依赖项分组到一个特定的工件中,这可能只是一个具有依赖项的 pom。然后你可以依赖,比如“com.example/common-db-dependencies/1.2”来包含一组标准的数据库依赖项,比如hibernate、apache derby和JPA规范。(或您正在使用的任何东西)。不使用 JPA/SQL 的服务可以完全避免这种依赖关系。
不过不要纠缠自己。如果您试图涵盖每种情况,很容易过度使用依赖结构。所以,只尝试标准化大多数服务真正使用的东西。
我肯定会使用父项目。
我多年来一直在使用这两种结构......微服务与否,模块化与否,Ant,Maven 和 Gradle..
我们需要明白,使用父 pom 并不意味着谈论不耦合和独立的微服务:
我听说“一个微服务可能需要对一个依赖项使用不同的版本”,你可以,只需覆盖特定微服务 pom.xml 中的依赖项即可。
我们需要关注“这里有什么好处,有什么坏处”:
以及更多:
缺点呢? 我暂时看不到任何异常,因为可以通过覆盖特定微服务 pom 中的常见行为来管理异常,我仍然可以隔离管理任何事情(隔离构建,隔离发布,隔离部署..)什么都没有耦合
还不确定我们所说的“它在同一个发布周期中锁定模块”是什么意思它不是,除非您使用外部 SNAPSHOT,否则我可以重新使用相同的父版本单独发布一个微服务。
例如,我可以让模块 1 声明 Parent 1.0 并单独发布,而无需从父模块运行发布过程,我可以直接在子模块上运行它,但我不需要在子模块项目中声明任何外部 SNAPSHOT(您有或没有父母都会有同样的问题)
这里有一个依赖和依赖管理的问题。假设您的一个微服务出于某种原因想要升级到较新版本的 common ......您不能这样做,因为您有父级。我确实理解减少重复插件配置等冗余事物的诱惑。在微服务中,我们需要更多地考虑每个服务的独立性。
一些配置,比如你的存储库或发布配置等可能很常见。
大多数关于微服务架构的书籍都推荐自治作为原则。使用父 pom 违反了该原则。
首先,使用父 pom,您不能再采用多语言方法并用不同的语言编写微服务。
您还将被迫使用父级规定的依赖项,尤其是在使用强制插件时。
微服务将不再可独立部署。
如果该工作涉及更改父级,那么您在任何一个微服务上的工作也可能会破坏其他微服务。
在微服务中使用父 pom 方法的一个主要缺点是它会使微服务的发布管理变得有点棘手。一些相关的指针 -
建议 -