Post by account_disabled on Jan 29, 2024 7:11:10 GMT
虽然微服务都是炒作,但著名专家警告不要以这种方式开始。相反,您可能想首先构建一个模块化整体,如果考虑稍后进入微服务但尚未立即需要,这是一个安全的选择。本文向您展示如何使用 OSGi 构建精益整体架构,当该风格成为满足应用程序扩展要求的适当解决方案时,该架构足够模块化,无需太多努力即可拆分为微服务。 创建良好模块化解决方案的一个非常好的策略是实施领域驱动设计(Eric Evans)。它已经专注于业务功能,并具有提供必要的模块化的有界上下文的概念。在本文中,我们将使用 OSGi 来实现服务,因为它为模块(捆绑包)和它们之间的轻量级通信(OSGi 服务)提供了良好的支持。正如我们将看到的,这也将为以后的微服务提供一个很好的途径。 本文不需要 OSGi 的先验知识。我将在讨论过程中解释相关方面,如果您读完本文后了解到 OSGi 可用于构建解耦的整体架构,为可能的微服务迁移做好准备,那么它就实现了其目标。您可以在 GitHub 上找到示例应用程序的源代码。
我们的领域:模块化消息应用程序 为了保持较低的业务复杂性,我们将使用一个相当简单的示例 - 聊天应用程序。我们希望应用程序能够发送和接收广播消息,并在三个截然不同的渠道中实现这一点: 外壳支持 互联网资源中心支持 使用基于 Tinkerforge 的显示器和运动检 WhatsApp 号码数据 测器支持物联网 每个通道都使用相同的接口来发送和接收消息。应该可以插入和拔出通道并自动将它们相互连接。在 OSGi 术语中,每个通道都将是一个捆绑包,并使用 OSGi 服务与其他通道进行通信。 如果您没有 Tinkerforge 硬件,请不要担心。显然,Tinkerforge 模块将无法工作,但不会影响其他通道。 通用项目设置和 OSGi 包 示例项目将使用 Maven 构建,大部分常规设置在父 pom中完成。 OSGi 捆绑包只是带有增强清单的 JAR 文件,其中包含 OSGi 特定条目。一个包必须声明它从其他包导入哪些包以及导出哪些包。幸运的是,大多数情况都是通过使用bnd-maven-plugin自动发生的。它分析 Java 源并自动创建合适的导入。导出和其他特殊设置在特殊文件中定义bnd.bnd。在大多数情况下,该文件可以为空,甚至可以省略。 下面的两个插件确保每个 Maven 模块创建一个有效的 OSGi 包。
各个模块不需要在 pom 中进行特殊的 OSGi 设置 - 对于它们来说,引用此处正在构建的父 pom 就足够了。maven-jar-plugin 定义我们要使用MANIFESTbnd 中的文件而不是默认的 Maven 生成的文件。 我们下面设计的每个模块都会创建一个 OSGi 包。每个模块的 pom 都非常简单,因为大部分设置已经在父模块中完成,因此我们省略这些。请查看OSGi 聊天项目的源代码以了解详细信息。 声明式服务 该示例使用声明式服务 (DS)作为依赖项注入和服务框架。这是一个由 OSGi 规范定义的非常轻量级的系统,允许发布和使用服务以及使用配置。DS 非常适合 OSGi,因为它支持 OSGi 的完整动态,其中捆绑包和服务可以随时进出。DS 中的组件可以提供 OSGi 服务并依赖于其他 OSGi 服务和配置。每个组件都有自己的动态生命周期,并且仅在所有强制依赖项都存在时才会激活。它还将动态适应服务和配置的变化,因此变化几乎可以立即应用。 由于 DS 负责处理依赖关系,因此开发人员可以专注于业务领域,而不必编写 OSGi 的动态代码。作为 DS 组件的第一个示例,请参阅ChatBroker下面的服务。在运行时 DS 使用 XML 文件来描述组件。 聊天 API 在我们简单的聊天域中,我们只需要一个服务接口ChatListener来接收或发送聊天消息。
我们的领域:模块化消息应用程序 为了保持较低的业务复杂性,我们将使用一个相当简单的示例 - 聊天应用程序。我们希望应用程序能够发送和接收广播消息,并在三个截然不同的渠道中实现这一点: 外壳支持 互联网资源中心支持 使用基于 Tinkerforge 的显示器和运动检 WhatsApp 号码数据 测器支持物联网 每个通道都使用相同的接口来发送和接收消息。应该可以插入和拔出通道并自动将它们相互连接。在 OSGi 术语中,每个通道都将是一个捆绑包,并使用 OSGi 服务与其他通道进行通信。 如果您没有 Tinkerforge 硬件,请不要担心。显然,Tinkerforge 模块将无法工作,但不会影响其他通道。 通用项目设置和 OSGi 包 示例项目将使用 Maven 构建,大部分常规设置在父 pom中完成。 OSGi 捆绑包只是带有增强清单的 JAR 文件,其中包含 OSGi 特定条目。一个包必须声明它从其他包导入哪些包以及导出哪些包。幸运的是,大多数情况都是通过使用bnd-maven-plugin自动发生的。它分析 Java 源并自动创建合适的导入。导出和其他特殊设置在特殊文件中定义bnd.bnd。在大多数情况下,该文件可以为空,甚至可以省略。 下面的两个插件确保每个 Maven 模块创建一个有效的 OSGi 包。
各个模块不需要在 pom 中进行特殊的 OSGi 设置 - 对于它们来说,引用此处正在构建的父 pom 就足够了。maven-jar-plugin 定义我们要使用MANIFESTbnd 中的文件而不是默认的 Maven 生成的文件。 我们下面设计的每个模块都会创建一个 OSGi 包。每个模块的 pom 都非常简单,因为大部分设置已经在父模块中完成,因此我们省略这些。请查看OSGi 聊天项目的源代码以了解详细信息。 声明式服务 该示例使用声明式服务 (DS)作为依赖项注入和服务框架。这是一个由 OSGi 规范定义的非常轻量级的系统,允许发布和使用服务以及使用配置。DS 非常适合 OSGi,因为它支持 OSGi 的完整动态,其中捆绑包和服务可以随时进出。DS 中的组件可以提供 OSGi 服务并依赖于其他 OSGi 服务和配置。每个组件都有自己的动态生命周期,并且仅在所有强制依赖项都存在时才会激活。它还将动态适应服务和配置的变化,因此变化几乎可以立即应用。 由于 DS 负责处理依赖关系,因此开发人员可以专注于业务领域,而不必编写 OSGi 的动态代码。作为 DS 组件的第一个示例,请参阅ChatBroker下面的服务。在运行时 DS 使用 XML 文件来描述组件。 聊天 API 在我们简单的聊天域中,我们只需要一个服务接口ChatListener来接收或发送聊天消息。