【问题标题】:Migrating multi-module project to microservices?将多模块项目迁移到微服务?
【发布时间】:2018-01-06 02:14:57
【问题描述】:

我有多模块应用程序。更明确地说,这些是 Maven 模块,其中高级模块依赖于低级模块。 以下是一些模块:-

    user-management
    common-services
    utils
    emails

例如:- 如果user management 模块想要使用来自utils 模块的任何服务,它可以调用它的服务,因为 utils 的依赖关系已经在用户管理下注入。 为了真正遵循微服务架构转换/调用我的项目,我相信我需要将每个模块转换为可独立部署的服务,其中每个模块都是一个战争模块 并通过http(主要作为resful web services)提供服务。这是正确的还是其他需要注意的?

现在可能每个模块都必须得到保护和身份验证层?

如果这就是微服务的症结所在,当有人问你是否像我一样从事微服务工作时,我真的不明白它不是工具/平台/框架,而是一个简单的 将您的单体应用程序划分为较小的可部署模块集的概念,这些模块的服务可通过 HTTP 获得。不是吗?可能是它的另一个流行词。

更新:- 显然,采用微服务方式有优势,例如独立的单元可测试模块,可扩展,因为它可以部署在单独的机器上,松散耦合等,但我认为我还需要处理两个复杂的问题

  1. 身份验证:- 对于每个模块,我需要确保它对请求进行身份验证,但目前情况并非如此
  2. 事务:- 我无法跨不同服务维护事务原子性,目前我可以很容易地做到这一点

【问题讨论】:

  • 这些模块中哪些公开服务,哪些不公开?

标签: java microservices


【解决方案1】:

您的理解非常好,并且您已经找到了微服务在单体(分布式事务)上变得复杂的正确领域,但让我澄清一些关于微服务的观点。

  1. 微服务并不意味着通过 HTTP 暴露的独立服务:一个微服务可以通过同步或异步的方式与其他服务进行通信,因此 REST 是其中一种解决方案,适用于同步通信但是您也可以执行异步通信,例如使用 Kafka 或 hornetq 等进行消息驱动。在同步通信中,底层服务也可以通过 Thrift 协议调用。

  2. 微服务遵循 SRP:微服务的美妙之处在于每个服务只集中在一个业务领域用例上,因此它只处理一个领域对象的功能。但是 utils 模块用于通用方法,因此每个微服务都依赖它。因此,即使 utils 模块中的一个小改动也需要构建所有其他微服务,因此它违反了微服务 12 原则,因此解散 utils 服务并使其与每个服务一起本地化。

  3. 处理身份验证:具体来说,微服务可以是以下三种类型之一:
    一种。 核心服务:只需执行域操作(如帐户创建/更新/删除)
    湾。 聚合服务:调用一个或多个核心服务,收集结果并对其执行一些操作。
    C。 边缘服务:暴露给客户端(如移动/浏览器等)。我们有时称其为网关服务;该服务的关键是接受用户请求并基于 URL 将其转发到实际的微服务。因此,如果它对所有微服务都是通用的,那么它是放置身份验证的理想场所。

  4. 处理分布式事务:是的,这是微服务中最难的部分,但您可以通过事件驱动/消息驱动的方式来实现。每个动作都会弹出一个事件;此事件的订阅者接收到相同的内容并执行一些操作并生成另一个事件。如果发生故障,它会生成一个反向事件来补偿创建的第一个事件。

    例如,假设我们从 micoservice A 中扣除了 100 卢比,因此创建一个 AccountDebited 事件。现在在微服务 B 中,我们尝试记入该帐户。如果成功,我们创建AccountCredited,A 接收它并创建另一个事件AmountTransfered。如果失败,我们会生成一个AccountCreditedFailed 事件,该事件被 A 接收并生成一个反向事件 - AccountSpecialCredit - 它保持原子性。

【讨论】:

  • 我认为在第四点,你说的是两阶段提交?还有身份验证呢。现在,每个微服务都必须实现自己的身份验证机制,而不是在入门级仅进行一次身份验证的单体应用程序。我相信即使需要完成,身份验证也可以是独立的微服务,所有其他微服务都调用它来进行身份验证?
  • 嗨,Emily,在第四点我想谈谈事件流模式,其中有一个使用 Kafka 的公共事件总线——因为它分布在多个节点上,没有 SPF,每个服务都听那个总线所以每个服务都会通知他们订阅的事件然后执行它的操作并再次生成一个事件到事件总线。对于我之前所说的身份验证,我们可以使用 Zuul 将其放在网关服务上——您可以对其进行配置。网关服务接受用户的所有请求,然后路由到专用服务,它是一种前端控制器,因此您可以轻松地将常用代码放在那里。
【解决方案2】:

您所拥有的大部分是正确的,但您似乎将某些东西视为需求而不是需求,并且您忘记了微服务应该具有的一个非常重要的特征。

微服务的主要特点是无状态和独立性。它们是否是“WAR”模块以及它们是否通过“HTTP”提供服务(当然它们是否是 RESTful)是次要问题,您可能会听到相反的论点。

无状态意味着没有单个微服务可能包含状态。 (缓存除外。)微服务应该始终将持久化数据的任务委托给某个数据库模块,这样它们就不会在内存中保留任何状态。这样做的想法是,如果一个微服务发生故障,(或者如果包含许多微服务的整台机器发生故障),您可以将传入请求路由到另一个实例(或另一台机器),一切都会继续工作。

(当然,如果你想听我的意见,那只是对我们不知道如何编写可靠的高并发软件这一事实的怯懦承认,但是数据库人很聪明,他们似乎已经想通了。出来,所以我们只会将维护我们状态的问题委托给他们编写的软件。)

【讨论】:

    【解决方案3】:

    在我看来,微服务架构与 DDD 结合得很好

    我认为您应该将您的多模块项目视为“单体”,并根据领域概念而不是 maven 项目进行微服务分离。

    例如:不要创建一个名为“utils”的微服务,而是创建一个名为“accounts”或“user-management”的微服务或任何您的域。我认为如果没有领域驱动开发,它就会失去它的用处。

    知道 域 的不同方面是相互独立的,之后就可以很容易地处理它。你应该看看 Alistair Cockburn 的六边形架构

    【讨论】:

      【解决方案4】:

      如何拆分应用程序取决于您拥有的模块类型。如果模块包含业务逻辑,那么创建新服务并通过 Http 或消息传递进行通信是有意义的。另一方面,如果您的模块没有业务逻辑,但只有一组辅助函数可能会更好地将其提取到单独的公共/私有 maven 包中并将其用作依赖项。

      是的,microservice 是一个最近才流行起来的流行词,但这个概念已经存在了一段时间。但它也带来了更多的东西。虽然它提供了可扩展和独立服务部署的好处,但它以管理和编排大量服务的复杂性为代价。

      例如,在单体应用程序中,当您只是从另一个模块调用一个函数时,您肯定知道它始终可以调用。对于微服务,一些服务可能会因为中断或部署而关闭,在这种情况下,您必须考虑优雅地处理这些情况(例如应用 circuit breaker 模式)。

      在做微服务时还有很多其他的事情需要考虑,并且有很多关于这个主题的文献。我从 Nginx 阅读了Microservices: From Design to Deployment。又短又甜。

      所以当人们问你Have you worked with microservices before? 时,我猜他们想知道你是否熟悉这个概念的所有陷阱并有一些经验。

      【讨论】:

      • 感谢奥斯塔普。一个问题,为什么将模块(包含业务逻辑)作为微服务而不是只包含辅助方法的模块有意义?
      • 这是个好问题。这对我来说就像一个常识。但是,例如,当您使用来自 maven 的某个库时,您不会创建服务只是为了使用该库。该库是其他服务的一部分。将库作为单独的微服务并没有真正利用微服务带来的好处,同时仍然需要处理您提到的身份验证等问题。与微服务的代码相比,库或实用程序代码的更改通常也不那么频繁。
      【解决方案5】:

      在一个方面你是对的,从外部看,在微服务中它看起来像这样。当您正确地提到两个复杂的问题时:

      身份验证:- 对于每个模块,我需要确保它对请求进行身份验证,但目前情况并非如此

      事务:- 我无法保持跨不同服务的事务原子性,目前我可以很容易地做到这一点

      除此之外,还有很多事情需要了解,否则做和部署微服务将非常困难:

      我在这里提到了一些,完整的列表你可以从我的帖子中看到:

      • 究竟什么是微服务?有人说它不应该超过 1,000 行代码。有人说它应该适合一个限界上下文(如果你不知道限界上下文是什么,现在不要理会它;继续阅读)。
      • 甚至在决定什么是“微”服务之前,服务到底是什么?
      • 微服务不允许同时更新多个实体;我将如何保持实体之间的一致性?
      • 我是否应该为所有微服务使用一个数据库集群?
      • 每个人都在谈论的最终一致性是什么?
      • 我将如何整理由驻留在不同服务中的多个实体组成的数据?
      • 如果一项服务出现故障会怎样?依赖服务的行为如何?
      • 是否应该在微服务之间进行同步调用以始终获得一致的数据?
      • 如何管理对部分或全部微服务的版本升级?是否总是可以在不停机的情况下做到这一点?
      • 最后一个不可避免的问题——如何将整个应用程序作为一个集成应用程序进行测试?
        • 如何进行断路? (如果一项服务停机不应影响其他服务)
        • CI/CD 管道和......

      在开始我们的微服务之旅时,我们理解的是:

      1. 解决微服务业务问题的设计模式是领域驱动设计
      2. 支持微服务开发的平台。 (我们为此使用了 Lagom)解决了上述一些开箱即用的问题

      所以总而言之,同时朝着多进程架构迈进。使用 Rest 或其他一些方法进行通信时,需要注意在 Monolithic 中不直接可见的新注意事项,人们想知道你是否知道这些注意事项。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-23
        • 2021-05-04
        • 2019-06-26
        • 2016-01-07
        • 2021-05-06
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        相关资源
        最近更新 更多