web-services - 在隔离的微服务之间共享数据

标签 web-services heroku database-design web-applications microservices

我想在新系统上使用微服务架构模式,但是在弄清楚服务彼此隔离时如何在服务之间共享和合并数据时遇到了麻烦。特别是,我正在考虑返回整合数据以通过HTTP填充Web应用程序UI。

就上下文而言,我打算将每个服务部署到其自己的隔离环境(Heroku)中,在该环境中我将无法在服务之间进行内部通信(例如,通过//localhost:PORT。我计划使用RabbitMQ进行服务间通信,而Postgres则用于数据库。

服务的解耦对于CREATE操作很有意义:

  • 使用UserId的经过身份验证的用户在前端
  • 上提交“加入组”网络表单
  • 包含GroupJoinRequest的新UserId已添加到RabbitMQ队列
  • Groups服务获取事件并对其进行处理,并参考用户的UserId

  • 但是,如果我想跨表/方案合并数据,则READ操作要困难得多。假设我想获取特定组中所有用户的详细信息。在单片设计中,我只是在Users和Groups表之间执行SQL JOIN,但是却失去了微服务的隔离优势。

    我的选择似乎如下:

    每个服务的数据库,每个服务的 public API

    要查看Users中的所有Group,站点访问者将从Groups服务中获取与某个群组相关联的UserID的列表,然后分别查询Users服务以获取其名称。

    优点:
  • 非常清晰的关注点分离
  • 每个服务完全负责自己的数据

  • 缺点:
  • 需要多个HTTP请求
  • 客户端
  • 必须做很多后期处理
  • 无法优化多个SQL查询

  • 每个服务数据库,服务通过HTTP,单个 public API共享数据

    public API服务器处理请求端点。 API服务器中的应用程序逻辑通过HTTP通道向每个服务发出请求,而该请求只能由系统中的其他服务访问。

    优点:
  • 关注点分离良好
  • 每个服务都负责API合同,但只要API响应不改变
  • ,它就可以对模式和数据存储做任何它想做的事情

    缺点:
  • 性能不佳
  • HTTP似乎可用于内部通信的奇怪传输机制
  • 最终向 public Internet公开了多种服务(即使它们在概念上被锁定),因此安全威胁会随着攻击面的扩大而增加

  • 每服务数据库,服务通过消息代理共享数据

    鉴于我已经在运行RabbitMQ,我可以使用它对数据请求进行排队,然后发送数据本身。因此,例如:
  • 客户端请求组
  • 中的所有用户
  • public API服务发送带有GetUsersInGroupRequestID事件
  • Groups服务将其提取出来,并将UserID添加到队列
  • 用户服务将其选中,并将用户数据添加到队列
  • API服务使用RequestID侦听事件,等待响应,将数据合并为正确的格式,然后发送回客户端

  • 优点:
  • 使用现有基础结构
  • 很好的解耦
  • 服务间请求保留在内部(无 public API)

  • 缺点:
  • 多个SQL查询
  • 应用程序层上的大量数据处理
  • 很难推理
  • 似乎很奇怪,无法通过事件系统
  • 传递大量数据
  • 延迟?

  • 服务共享一个数据库,由模式分隔,其他服务则从VIEW中读取

    服务被隔离到数据库架构中。模式只能由其各自的服务写入。服务在其架构上公开一个SQL VIEW层,其他服务可以查询该层。
    VIEW充当API合约;即使基础架构或服务应用程序逻辑发生更改,VIEW也会公开相同的数据,因此

    优点:
  • 性能可能更高(单个SQL查询可以获取所有相关数据)
  • 外键管理容易得多
  • 维护
  • 的基础设施较少
  • 易于运行跨多个服务的报告

  • 缺点:
  • 服务之间的紧密耦合
  • 打破了根本不了解彼此的原子服务的想法
  • 添加了可能难以扩展的整体组件(数据库)(与原子服务可根据需要独立扩展数据库的原子服务相反)
  • 将所有服务锁定为使用相同的记录系统(Postgres可能不是所有服务的最佳数据库)


  • 我倾向于最后一种选择,但是希望您对其他方法有任何想法。

    最佳答案

    为了评估优缺点,我认为您应该专注于微服务架构要实现的目标。在我看来,微服务是旨在构建松耦合应用程序的体系结构样式。它不是为构建高性能应用程序而设计的,因此当我们决定以微服务方式构建应用程序时,我们已经可以接受降低性能和减少数据冗余的问题。

    我认为您的服务不应共享数据库。紧密的耦合消除了微服务架构的主要目标。我的建议是创建一个统一的数据服务,该服务将从所有其他服务中获取数据更改事件并更新其背后的数据库。您可能希望以一种针对查询优化的方式(例如数据仓库)设计合并数据服务背后的数据库,因为这将用于所有服务。您可能要考虑使用NoSQL数据库来支持您的统一数据服务。

    关于web-services - 在隔离的微服务之间共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40422613/

    相关文章:

    c# - 对 asmx 服务的异步/等待调用

    heroku - 在 Heroku 上调用 clojure 工作线程的最佳方法是什么?

    sql-server - 在 sql server 中存储持续时间(时间跨度)

    java - 移动应用程序避免或保护 CORS?

    c# - 如何从网络服务返回多个字符串?

    python - Heroku Python/Django 应用程序全部同时开发 ImportError

    MySQL性能调优

    database-design - 有关继承和数据库设计的更多信息

    asp.net - 使用 ASP.NET 和 Web 服务时最有效地获取 SQL 连接

    Heroku 不会在 Rails 4 中的 Assets 管道下编译文件