微服务架构中的业务逻辑应该放在哪里?


12

由于我习惯于采用单片方法,因此仍在尝试围绕微服务架构

假设我们尝试构建一个极其简化的 Uber预订系统。为简单起见,我们假设我们有3个服务和客户端的网关API: ,,Booking 和我们有以下流程:DriversNotification

创建新预订时:

  1. 检查现有用户是否已有预订
  2. 获取可用驱动程序列表
  3. 发送通知给司机以领取预订
  4. 司机接机

假设所有消息传递都是通过http调用完成的,而不是通过类似kafka的消息传递总线来完成的。

因此,在这种情况下,我认为该Booking服务可以对现有预订进行检查。但是,谁应该得到可用驱动程序和通知的列表呢?我正在考虑在网关级别执行此操作,但是现在逻辑可以分为两个地方:

  • Gateway -获取可用驱动程序列表+发送通知
  • Booking -检查现有预订

而且我很确定网关不是正确的选择,但是我觉得如果我们在Booking服务中使用它,它将变得紧密相连吗?

更复杂的是,如果我们有另一个项目想要重用预订系统,但又要有其自己的业务逻辑,该怎么办?这就是为什么我考虑在网关级别执行此操作,以便新项目网关可以将其自己的业务逻辑与现有逻辑分开。

我想的另一种做法是,每个项目都有自己的预订服务,该服务将与核心预订服务对话,但是我不确定这里最好的方法是什么:-)


2
没有整个上下文,很难回答。即使知道这一点,启动一个在微服务上传播业务逻辑的项目也不总是一个好主意,这就是为什么有些人采用“ Monolith First”的原因,因为在开始时您并不真正了解其中的每个部分的职责。你的申请。这只有在以后才变得清楚。
Dherik

Answers:


14

人们经常听到“微服务”而认为“纳米服务”,这可能会引起一些混乱。这些是服务,因此您不需要为每个实体提供单独的服务。您尝试做的所有事情都应该在bookingnotification服务中。您不需要driver服务(针对您描述的任何活动)。

获取可预订的驱动程序列表属于该booking服务。一个常见的陷阱是不将相关活动分组到同一服务中,这称为低一致性,这是非常糟糕的。请记住,您是按问题域而不是按实体将事物分组到服务中。

现在,关于重用,拥有单独的微服务的优势在于,现在您可以拥有三个独立的团队来制作面向消费者的应用程序。一个小组负责标准html网络应用,一个android应用和一个ios应用。所有这些不同的应用程序都可以完全不同地构建,并且看起来适合于它们的特定平台(无需重复代码)。booking所有这三个应用程序都可以重用该服务代码,因为这三个应用程序都对该服务进行http调用,而不是拥有自己的预订代码。

典型的预订流程如下所示:

  1. android应用调用该booking服务以获取可用驱动程序列表
  2. 预订服务将驱动程序列表返回给应用程序
  3. 然后,用户选择其驱动程序,应用程序将调用该booking服务的“预订”方法
  4. booking服务的服务调用notification与预订信息服务
  5. notification服务会向驾驶员发送通知,告知其预订
  6. 驾驶员应用程序notification在距客户一英里的范围内时,会向服务发送消息
  7. notification服务将警报发送给客户,告知他们的司机已经快到了

希望这有所帮助;请记住,它们是微服务,而不是纳米服务,不要试图划分相同的问题域。因此,为了回答问题的标题,当您将微服务保持适当的大小时,该问题域的所有或大部分业务逻辑都可以存在于该微服务中。


1

这完全取决于您的确切要求。

假设您有两个应用程序在进行预订:

  1. 第一种情况:一个应用程序可能允许一个用户多次预订,而另一个则只允许一个。这意味着预订的限制是在应用程序级别上的,因此,要么您的预订系统中有两个入口点(一个可以进行多次预订,一个就不能进行多次预订),或者您只是在相关的微服务中进行了检查应用。
  2. 第二种情况:这是“预订”定义的一部分,无论应用程序是什么,用户都不能拥有多个预订,这条规则适用于整个系统:这意味着您可以将支票放入预订微服务中。

至于通知系统,您可以使用微服务来预订您的预订服务,以监听任何新的预订。这样,预订微服务将通知所有订户,他们将相应地采取行动。

这种架构中的唯一问题是,在通知发布后如果某件事失败,将会发生什么,因为这两个微服务的工作方式不像在同一个数据库事务中执行的两个函数一样,您将需要优雅地处理错误并最终重播流程失败(自动或手动)


0

简单的答案是,微服务的客户端是在“纯”微服务体系结构中管理业务逻辑的对象。为了更容易理解,请考虑一个更简单的示例。一种仅基于URI返回字节流的服务。就其本身而言,它并不是非常有用。如果没有某种方式知道哪些URI中包含哪些URI,则只能猜测要从哪里提取东西。现在,假设您具有提供搜索功能的其他微服务。您发送带有查询字符串的请求,它返回URI。现在事情变得更有趣了。我可以将对第一个服务的URI的引用放入索引中。

但是,我们仍然需要以某种方式在这两者之间进行协调。有一个简单的答案:您使用浏览器从索引服务中检索URI,然后从数据服务中检索数据。两种服务都不“了解”彼此,并且它们之间绝对没有耦合。我可以将索引服务与任何其他数据服务一起使用,反之亦然。

不一定是所有方案中的最佳方法,但以这种方式构建事物有很多好处,尤其是在当前未知的方案中具有可重用性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.