DAO 作为服务与 DAO 作为库

DAO as Service vs DAO as Library

我有 3 个不同的服务需要访问同一个数据库。这些服务中的每一个都将服务于不同的目的和不同的查询。我可以通过以下方式概括它们

  1. 服务 1 -> 客户查询
  2. 服务 2 -> 订单处理器(e.g.workflow 已下订单)
  3. 服务 3 -> 报告

我写了一个 DAO 来公开数据。我正在评估两个系统设计的可扩展性和维护性。

Option 1: Write one more service to expose DAO functionality as Data Service.

Pros:

  1. Load on database will be controlled and easy to scale-in/out as needed
  2. Easy to maintain for future updates
  3. Access control for various actions
  4. clients doesn't have full access on underlying database

Cons:

  1. Single point of failure
  2. management of extra service
  3. Need to enforce backward compatibility rules
  4. In case of DataService downtime every service is affected (factors other than database downtime)

Option 2: Create a storage library out of DAO and use these library in above mentioned three services.

Pros:

  1. distributed, impact radius is very small

Cons:

  1. Every service get full access on database
  2. Needs to update all three services for new features

这是一个意见...当需要对数据库进行共享访问时,我们使用选项 1。封装使我们能够支持向后兼容的服务调用,这使我们能够更多地重用我们的服务。管理开销较高,但如果您获得大量客户端服务,那么控制访问的能力非常值得。

想一想,如果您有 10-20 项服务正在数十个应用程序中使用。如果您需要重构数据库(这会发生),更新所有这些应用程序并同步它们的部署的成本是巨大的。此外,正如您所说,缓存之类的事情可以在集中式服务中集中完成并轻松扩展。分布式缓存失效是那些棘手的问题之一,其最终成本远远超过首先通过集中访问来避免该问题。

这只是我的经验。 YMMV。如果您的数据库模式非常静态,您可能不会获得太多好处,或者您预计不会出现很多扩展问题。就像我说的,这是一个意见。

首先,我会为每个服务构建单独的 DAO,因为它们都与您的描述不同 bounded contexts。例如,"Service 3 -> Reporting" 很可能是用于提取聚合数据的只读服务,它不应该知道订单处理器和客户查询的内容。此外,如果您期望有大量数据,请考虑使用单独的数据库来报告查询,因为它可能对一个数据库来说负载太大,并且更容易扩展它。
关于您关于公开数据的服务的问题,每个服务都有单独的 DAO,我认为最好将 DAO 放在一个库中。这样每项服务将只能访问它需要的数据,如果您只需要对一个 DAO 进行更改,则不必部署所有服务。此外,您可能希望有一个基本的 DAO 来封装很少更改的公共逻辑。请记住,除非您将服务部署到与数据库相同的机器上,否则拥有公开数据的服务将增加一层数据传递直到它到达数据库。这对于高性能应用程序可能至关重要。

感谢 Rob 和 Maksym 的投入。

我根据限界上下文分离了查询,并为不同的上下文创建了库和服务。

服务

查询和订购服务 使用数据服务访问数据。这帮助我控制了嘈杂的邻居和资源分配。

图书馆

我将数据从主数据库复制到报告数据库,并为 报告服务 构建了一个库以访问报告数据库。