【问题标题】:DAO as Service vs DAO as LibraryDAO 即服务与 DAO 即库
【发布时间】:2017-11-18 10:25:10
【问题描述】:
我有 3 个不同的服务需要访问同一个数据库。这些服务中的每一项都将服务于不同的目的和不同的查询。我可以通过以下方式概括它们
- 服务 1 -> 客户查询
- 服务 2 -> 订单处理器(例如下订单的工作流程)
- 服务 3 -> 报告
我编写了一个 DAO 来公开数据。我正在评估两种系统设计的可扩展性和维护性。
选项 1:再编写一项服务以将 DAO 功能公开为数据服务。
优点:
- 数据库负载将受到控制,并可根据需要轻松扩展/扩展
- 易于维护以备将来更新
- 各种操作的访问控制
- 客户端没有对底层数据库的完全访问权限
缺点:
- 单点故障
- 额外服务的管理
- 需要强制执行向后兼容规则
- 如果 DataService 停机,每个服务都会受到影响(数据库停机以外的因素)
还有
选项 2: 在 DAO 之外创建一个存储库,并在上述三个服务中使用这些库。
优点:
- 分散,影响半径很小
缺点:
- 每个服务都可以完全访问数据库
- 需要更新所有三项服务以获取新功能
- 哪个选项好,为什么?
- 还有其他需要考虑的想法/架构设计吗?
- 在选择架构时我需要考虑哪些事项?
【问题讨论】:
标签:
design-patterns
architecture
software-design
design-principles
【解决方案1】:
这是一个意见...当需要对数据库进行共享访问时,我们使用选项 1。封装使我们能够支持向后兼容的服务调用,这使我们能够更多地重用我们的服务。管理开销较高,但如果您获得大量客户端服务,那么控制访问的能力非常值得。
想一想,如果您有 10-20 种服务在数十个应用中使用。如果您需要重构数据库(这将发生),更新所有这些应用程序以及同步它们的部署的成本是巨大的。此外,正如您所说,缓存之类的事情可以集中完成,并且可以在集中式服务中轻松扩展。分布式缓存失效是那些棘手的问题之一,其最终成本远远超过通过集中访问首先避免该问题。
这只是我的经验。 YMMV。如果您的数据库模式是非常静态的,您可能不会获得太多好处,或者如果您不希望出现很多扩展问题。就像我说的,这是一种意见。
【解决方案2】:
首先,我将为每个服务构建单独的 DAO,因为它们都有不同的bounded contexts,从您的描述来看。例如,最有可能的是,“服务 3 -> 报告”将是用于提取聚合数据的只读服务,它不应该知道订单处理器和客户查询的东西。此外,如果您期望有大量数据,请考虑使用单独的数据库来报告查询,因为它可能对一个数据库来说负载过大,并且更容易扩展它。
关于您关于公开数据的服务的问题,每个服务都有单独的 DAO,我认为最好将 DAO 放在一个库中。这样,每个服务都只能访问它需要的数据,如果您只需要对一个 DAO 进行更改,您就不必部署所有服务。此外,您可能希望有一个基本 DAO 来封装很少更改的通用逻辑。请记住,除非您将服务部署到与数据库相同的机器上,否则拥有公开数据的服务将增加一层数据,直到数据到达数据库为止。这对于高性能应用程序可能至关重要。
【解决方案3】:
感谢 Rob 和 Maksym 的投入。
我根据有界上下文分离查询,并为不同的上下文创建库和服务。
服务
查询和订购服务使用数据服务访问数据。这有助于我控制嘈杂的邻居和资源分配。
图书馆
我将数据从主数据库复制到报告数据库,并为报告服务构建了一个库以访问报告数据库。