在微服务之间共享代码 - 在这种情况下是不是合理?
Posted
技术标签:
【中文标题】在微服务之间共享代码 - 在这种情况下是不是合理?【英文标题】:Sharing code between Micro-services - is it justified in this situation?在微服务之间共享代码 - 在这种情况下是否合理? 【发布时间】:2018-05-02 01:37:41 【问题描述】:有很多答案和博客文章说“永远不要在微服务之间共享代码”,我现在想知道我应该如何遵循这个建议。我有以下微服务,每个微服务都通过 RabbitMQ 进行通信:
express server 和两个不同的后台服务有完全不同的代码,而 request workers 只是多个实例。每个请求工作者都应该处理一个请求,并在完成后直接回复它 (RPC)。
我的问题:
我编写了一个类 (RequestScheduler
),它提供了安排请求的方法(例如 getProfile: Promise<IProfile>
)。既然我显然不允许在微服务之间共享代码,那么用于微服务之间通信的代码呢?
我没有办法避免与左侧的微服务共享该代码。
【问题讨论】:
能否更详细地描述您的问题,目前尚不清楚您要避免复制哪些代码。如果您的 2 个后台服务共享相同的代码,是否值得将其提取到单独的微服务中? 好吧,我试图避免帮助我在微服务之间进行通信的代码(例如,如上所述的调度请求),所以这不可能是它自己的微服务。需要有一点 RabbitMQ 的背景知识才能了解 RPC 需要什么,但我敢肯定,如果我使用 REST 进行通信,我会遇到同样的问题。 将该代码打包为一个模块 我在这里也会很粗鲁 - 根据意见投票结束这个问题是完全愚蠢的。为此我 +1 “不共享代码”的唯一合理含义是“不管理影响不同微服务的代码”。例如,如果微服务 A 和 B 在 v1 中使用 LibX,那么它完全可以。即使是必要的,现在没有库你怎么能开发任何东西?如果微服务 B 将 LibX 升级到 v2 则没问题,因为微服务 A 不必这样做。他们确实是独立的。所以将通用代码打包到一个库中,并确保一旦“发布”了库中的代码(在版本中)就不会改变。如果要更改库,请创建新版本。仅此而已。 【参考方案1】:在我看到的关于微服务架构的讨论中,交叉问题通常没有得到很好的记录——可能是因为乍一看,它们似乎与概念背道而驰(尽管事实并非如此)。在开发我们的应用程序(第一次使用微服务)时,我们遇到了与您提出的类似问题。在与一些比我们当时有更多经验的人交谈后,我们意识到微服务的概念更多的是关于域封装,因此围绕大小、库共享、等都是次要的微服务具有单一职责 (SRP) 和拥有单一、定义明确的域 (DDD) 的想法。
我们有一些库(我们作为 NuGet 包进行管理),用于将新服务连接到事件总线、管理授权、跨服务事件日志,甚至还有一个用于错误处理的标准中间件 - 我们几乎共享这些我们所有的服务。
虽然我们没有对其定义硬性规则,但我想说我们将代码重用处理为“如果我们生态系统中的所有微服务都需要它,它必须作为共享库提供。如果他们中的大多数人都可以使用它,它应该可用作共享库。 每个微服务都可以选择是实现共享库还是推出自己的解决方案。”
只要您的共享代码以允许每个微服务独立管理其自己的升级的方式分发,并且您的共享代码不受任何特定于域的语言或问题的影响,就一定要共享!
【讨论】:
【参考方案2】:@kentor 日志记录是一个横切关注点。如果有公司的日志记录标准并且有一个模块或库可供使用,那么您可以使用该库。它是共享的,但这很好,因为日志记录非常独立,不应干扰您的业务域逻辑或工作流程。微服务的一般准则是不共享代码。可以共享的东西是不经常更改的库,例如美国各州、颜色等。要回答您的问题what about the code for the communication between the microservices
,我会说不要共享此代码。将此代码/库的代码共享给其他应用程序可能会引入副作用错误。
【讨论】:
您是否建议每次从头开始编写通信库更不容易出错?完全不同意。顺便说一句,每个库都可能引入副作用错误。这就是您不尝试一遍又一遍地解决相同问题所付出的代价,这通常似乎更容易出错且效率更低。 IMO 中的“微服务之间的通信”是一个很好的自定义库示例,应该在微服务之间重用。 如果您拥有域和微服务,您可以创建一个公共库,该库可以共享给您域中的其他微服务。我要避免的是,如果我有一个 API,我不会创建一个客户端库来分发给我的客户消费者。 AWS SDK 不同,虽然它是提供的,但它由社区和 AWS 人员维护,而不是那些在 API 本身工作的人。【参考方案3】:code for the communication between the microservices
对我来说就像是一个库或一个包,不会经常更改。为什么不把它当成一个包来使用呢?
一个不错的选择是在私有 npm 注册表中创建一个包。然后,您将能够拥有该软件包的不同版本。因此,您将安全地使用语义版本控制。
【讨论】:
以上是关于在微服务之间共享代码 - 在这种情况下是不是合理?的主要内容,如果未能解决你的问题,请参考以下文章
JWT 注销:在微服务架构中的服务之间共享被列入黑名单的无效令牌