【微服务架构】让我们谈谈“拥有”他们的数据的微服务

简介: 【微服务架构】让我们谈谈“拥有”他们的数据的微服务

前几天我和一位同事讨论了我的微服务将用来公开特定数据集的接口的设计。数据由我的微服务保存在 Elastic Search 中,并根据最终用户将选择的过滤器以不同的形式由 UI 使用和呈现。当我仅仅提出让 UI 后端直接从 Elastic Search 查询数据的亵渎想法时,经典的“微服务不应该暴露其底层数据存储”的论点被点燃了。


  • Who owns the data??

暴露数据的服务

我会从头开始。微服务可以以任何方式或使用他们希望的任何技术公开数据,具体取决于用例。

让我们想象一个简单的数据项并通过一些示例。

有问题的数据项将是这个表示消息的简单 JSON 对象:

{
id: 2321387
sender: “Joe”
message_content: “Hello World Message”
}

公开这些数据的最无争议的方式可能是:

  • · REST API
  • · GraphQL

这些是“纯”API,因为它们提供了接口和底层数据存储的完全解耦。今天我可能会在 Couchbase 中保存数据,明天在 Redis 中,下周我会将其移动到 S3。如果我改变实现,消费者不需要知道任何事情。

  • Exposing Data via REST API — Not Controversial

那么消息队列中的消息呢?像 Kafka 或 RabbitMQ 之类的东西?软件工程社区仍将这些技术定义为公开数据的非争议方式。在许多产品的架构中,微服务通过消息队列相互通信,对吗?如果我想将我的实现从 Kafka 更改为 RabbitMQ 会发生什么,消费者是否也需要更改他们的实现?他们当然会,但您可能会争辩说,完全改变产品中的整个消息传递技术确实不太可能。


  • Exposing Data via Message Queues — Not Controversial

现在让我们朝这个方向再走一步。数据仓库和数据湖呢?将您的数据保存在 S3 中并让消费者使用 Athena/Presto/BigQuery 在其上运行查询怎么样?在这个用例中封装数据发生了什么?令人惊讶的是,“接口-数据存储解耦”范式的纯粹主义者根本不认为这是一种不好的做法。

我试图争辩说,数据湖/仓库用例与通过 Elastic Search、Couchbase、Redis 或任何其他技术公开数据之间没有真正的区别。数据的位置不是问题,因此解耦不是解决方案。我们以错误的方式看待这个问题。


内部数据 VS 公开数据

真正的区别应该是您定义为服务的“内部”数据或状态,以及您定义为服务的“公开”数据。问题不在于您选择使用哪种技术存储数据。

内部数据是其位置和架构可以更改而不事先通知的数据。它完全在服务和拥有团队内部,任何消费者都不应该依赖它。一天它可以是内存中的 HashMap,另一天它可以是 DynamoDB 中的一个表,第三天开发人员可以决定将它存储在 S3 中,因为它太大而且太贵了。只要将这些数据定义为内部数据,我们就可以在任何时间点引入“破坏性更改”,因为它不会“破坏”任何消费者。

公开数据是您向消费者公开并提交给它及其模式的数据。无论您是通过定义良好的 REST API、定义良好的 Kafka 消息、S3 中定义良好的 ORC 文件还是 Couchbase 中定义良好的记录来公开它都没有关系。只要您和您的消费者同意这是公开的公共数据,您就不能在不通知消费者的情况下引入重大更改。您甚至可以想象一个使用 2 个 Couchbase 存储桶的服务——一个用于内部数据,一个用于公开数据。同样,技术并不重要,重要的是数据用途的定义。

重要的是要澄清,即使这些数据被公开和共享,消费者也只能从中读取。在这种模式下,拥有服务仍然是唯一对公开数据具有写访问权限的实体(显然对内部数据也是如此)。您可以将其视为微服务的一种 CQRS 实现。

为什么你甚至想通过 Couchbase 或 Athena 而不是严格地通过 REST 或 GraphQL 等 WEB API 来公开你的数据,你可能会问。

Amazon Athena 就是一个很好的例子,因为它通过多台服务器并行运行您的查询,因此您的数据消费者可以利用 Athena 的强大功能进行快速的大数据查询。有什么选择?您会在自己的服务中构建类似的功能并通过 Web API 公开它们吗?您将如何通过 Web API 公开丰富的 SQL 语言?GraphQL 能否涵盖 SQL 提供的所有选项?API 是否会是您将在内部传递给 Athena 并将结果分页给消费者的通用字符串?

相同的概念可以应用于 Couchbase、DynamoDB、Aurora 或任何其他数据存储。创建这些工具是为了扩大规模,旨在每秒接受和响应数十万个请求。如果一切都严格通过您的服务进行,则意味着您的开发人员将需要在他们自己的服务中重写这些技术的功能,或者只是在逻辑上降级数据存储的真正底层功能。

总结

您需要在内部和共享之间逻辑划分数据。后者是您与世界共享的数据,而内部数据是您的消费者不需要知道的完全封装的实现。一个数据集可以被认为是内部的并且驻留在 State Store 中,而相同数据的投影可以驻留在同一个 State Store 中并暴露在外部。这完全取决于您的用例,以及向消费者公开数据以优化使用数据的最佳方式是什么。

评论1

SQL server 是隔离的,可独立部署的,通过网络消息与其他服务通信,拥有自己的数据,是唯一可以写入磁盘来持久化它的,那么它怎么不是微服务呢?因为它的边界是由技术要求而不是业务要求决定的?因为太复杂了?因为是第三方?荒谬的。没有人真正根据约束的类型来定义技术概念。

从本质上讲,您的文章侵蚀了微服务的概念,而这正是困扰人们的地方。就是“如果我们允许这样做,它会在哪里停止?”思维。但答案很简单:它不会停止。定义微服务的方式取决于组织内部解决方案的架构师。他们可以准确地确定什么是微服务,什么不是。作为一般概念,对微服务的限制是没有用的。

我会更进一步:微服务纯度(与任何其他类型或对纯度的追求一样,但这已经太笼统了)是有毒的。接受现实中任何值得该死的系统都是技术的混合体,其中微服务只是其中的一部分,这要健康得多。

评论2:

我基本同意,我们应该专注于逻辑划分数据,而纯粹的微服务架构是弊大于利的。虽然有些观点我认为你没有做对。

当您质疑数据库和仓库是用来回答数千个请求而 API 只能处理一个请求时,问题在于 API 的扩展方式。瘫痪 API 工作负载可以解决数据库必须提供的资源使用不足的问题。

另一件事是,如果您期望进行临时查询,他们可能应该使用另一种连接数据的方式。这是BI系统存在的主要原因。

也许我在挑剔,但这些是我对这个主题的想法。我不愿意让其他人看到我的数据:p

相关文章
|
存储 BI Shell
Doris基础-架构、数据模型、数据划分
Apache Doris 是一款高性能、实时分析型数据库,基于MPP架构,支持高并发查询与复杂分析。其前身是百度的Palo项目,现为Apache顶级项目。Doris适用于报表分析、数据仓库构建、日志检索等场景,具备存算一体与存算分离两种架构,灵活适应不同业务需求。它提供主键、明细和聚合三种数据模型,便于高效处理更新、存储与统计汇总操作,广泛应用于大数据分析领域。
1346 2
|
SQL 缓存 前端开发
如何开发进销存系统中的基础数据板块?(附架构图+流程图+代码参考)
进销存系统是企业管理采购、销售与库存的核心工具,能有效提升运营效率。其中,“基础数据板块”作为系统基石,决定了后续业务的准确性与扩展性。本文详解产品与仓库模块的设计实现,涵盖功能概述、表结构设计、前后端代码示例及数据流架构,助力企业构建高效稳定的数字化管理体系。
|
数据采集 缓存 前端开发
如何开发门店业绩上报管理系统中的商品数据板块?(附架构图+流程图+代码参考)
本文深入讲解门店业绩上报系统中商品数据板块的设计与实现,涵盖商品类别、信息、档案等内容,详细阐述技术架构、业务流程、数据库设计及开发技巧,并提供完整代码示例,助力企业构建稳定、可扩展的商品数据系统。
|
11月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
12月前
|
数据采集 机器学习/深度学习 搜索推荐
MIT新论文:数据即上限,扩散模型的关键能力来自图像统计规律,而非复杂架构
MIT与丰田研究院研究发现,扩散模型的“局部性”并非源于网络架构的精巧设计,而是自然图像统计规律的产物。通过线性模型仅学习像素相关性,即可复现U-Net般的局部敏感模式,揭示数据本身蕴含生成“魔法”。
425 3
MIT新论文:数据即上限,扩散模型的关键能力来自图像统计规律,而非复杂架构
|
JSON Java 数据格式
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——封装统一返回的数据结构
本文介绍了在Spring Boot中封装统一返回的数据结构的方法。通过定义一个泛型类`JsonResult<T>`,包含数据、状态码和提示信息三个属性,满足不同场景下的JSON返回需求。例如,无数据返回时可设置默认状态码"0"和消息"操作成功!",有数据返回时也可自定义状态码和消息。同时,文章展示了如何在Controller中使用该结构,通过具体示例(如用户信息、列表和Map)说明其灵活性与便捷性。最后总结了Spring Boot中JSON数据返回的配置与实际项目中的应用技巧。
1104 0
|
JSON Java fastjson
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——使用 fastJson 处理 null
本文介绍如何使用 fastJson 处理 null 值。与 Jackson 不同,fastJson 需要通过继承 `WebMvcConfigurationSupport` 类并覆盖 `configureMessageConverters` 方法来配置 null 值的处理方式。例如,可将 String 类型的 null 转为 "",Number 类型的 null 转为 0,避免循环引用等。代码示例展示了具体实现步骤,包括引入相关依赖、设置序列化特性及解决中文乱码问题。
829 0
|
JSON Java fastjson
微服务——SpringBoot使用归纳——Spring Boot返回Json数据及数据封装——Spring Boot 默认对Json的处理
本文介绍了在Spring Boot中返回Json数据的方法及数据封装技巧。通过使用`@RestController`注解,可以轻松实现接口返回Json格式的数据,默认使用的Json解析框架是Jackson。文章详细讲解了如何处理不同数据类型(如类对象、List、Map)的Json转换,并提供了自定义配置以应对null值问题。此外,还对比了Jackson与阿里巴巴FastJson的特点,以及如何在项目中引入和配置FastJson,解决null值转换和中文乱码等问题。
1891 0
|
12月前
|
JSON 供应链 监控
1688商品详情API技术深度解析:从接口架构到数据融合实战
1688商品详情API(item_get接口)可通过商品ID获取标题、价格、库存、SKU等核心数据,适用于价格监控、供应链管理等场景。支持JSON格式返回,需企业认证。Python示例展示如何调用接口获取商品信息。

热门文章

最新文章