如何处理微服务架构中的共享状态?

Víc*_*tor 19 architecture deployment integration-testing test-environments microservices

在我们公司,我们正在从庞大的单片应用程序转变为微服务架构.这个决定的主要技术驱动因素是需要能够独立扩展服务和开发的可扩展性 - 我们有十个Scrum团队在不同的项目(或"微服务")工作.

过渡进程顺利,我们已经开始受益于这种新技术和组织结构的优势.另一方面,现在我们正在努力解决一个主要问题:如何管理这些微服务之间依赖关系的"状态".

让我们举一个例子:其中一个微服务处理用户和注册.这项服务(我们称之为X)负责维护身份信息,因此是用户'ID'的主要提供者.其余的微服务都非常依赖于这一点.例如,有一些服务负责依赖于这些用户ID的用户配置文件信息(A),用户权限(B),用户组(C)等,因此需要在这些服务之间维护一些数据同步(即服务A不应该具有未在服务X中注册的userId的信息).我们目前通过使用RabbitMQ通知状态更改(例如,新注册)来维持此同步.

可以想象,有许多 X:许多"主要"服务以及它们之间更复杂的依赖关系.

管理不同的开发/测试环境时出现了主要问题.每个团队(以及每个服务)都需要经历多个环境才能实现一些代码:持续集成,团队集成,验收测试和实时环境.

显然,我们需要在所有这些环境中工作的所有服务来检查系统是否整体运行.现在,这意味着为了测试依赖服务(A,B,C,...),我们不仅要依赖服务X,还要依赖服务状态.因此,我们需要以某种方式维护系统完整性并存储全局和连贯状态.

我们当前的方法是从实时环境获取所有数据库的快照,进行一些转换以缩小和保护数据隐私,并在特定环境中进行测试之前将其传播到所有环境.在组织和计算资源方面,这显然是一个巨大的开销:我们有十个持续集成环境,十个集成环境和一个验收测试环境,所有这些都需要使用来自实时和最新版本代码的共享数据进行"刷新"经常.

我们正在努力寻找一种更好的方法来缓解这种痛苦.目前我们正在评估两个选项:

  1. 使用类似docker的容器来处理所有这些服务
  2. 每个服务有两个版本(一个用于开发该服务,另一个用作沙箱,供其他团队在开发和集成测试中使用)

这些解决方案都没有减轻服务之间共享数据的痛苦.我们想知道其他一些公司/开发人员如何解决这个问题,因为我们认为这在微服务架构中必然是常见的.

你们是怎么做到的?你也有这个问题吗?有什么建议?

很抱歉很长的解释,非常感谢!

nel*_*eus 8

这次我从不同的角度阅读你的问题,所以这里是一个"不同的意见".我知道这可能为时已晚,但希望它有助于进一步发展.

它看起来像是shared state错误解耦的结果.在"正确"的微服务架构中,所有微服务都必须在功能上而不是逻辑上进行隔离.我的意思是这三个user profile information (A), user permissions (B), user groups (C)看起来在功能上相同,或多或少在功能上连贯.它们似乎是一个user microservice具有连贯存储的单一存储.我没有看到任何解耦他们的原因(或者至少你没有告诉他们).

所以真正的问题与微服务隔离有关.理想情况下,每个微服务都可以作为完整的独立产品生存,并提供明确定义的业务价值.在详细阐述系统架构时,我们将其分解为微小的逻辑单元(在您的情况下为A,B,C等,甚至更小),然后定义功能相干的子组.我不能告诉你如何做到这一点的确切规则,也许是一些例子.单元之间复杂的通信/依赖关系,无处不在的语言中的许多常见术语,因此看起来这些单元属于同一个功能组,因而属于微服务.

因此,从您的示例中,由于存在单个存储,因此您只能像管理一样来管理其一致性.

顺便说一下,我想知道你解决问题的实际方法是什么?如果你喜欢我的想法也可以随意接受它.


Eug*_*ene 0

从我的角度来看,只有使用服务的对象才应该具有状态。让我们考虑一下您的示例:服务 X 负责用户 ID,服务 A 负责配置文件信息等。让我们假设用户 Y 拥有一些安全令牌(例如可以通过使用其用户名和密码创建 - 应该是唯一)的系统条目。然后,包含用户信息的客户端将安全令牌发送到服务 X。服务 X 包含有关链接到该令牌的用户 ID 的信息。对于新用户,服务 X 创建新 ID 并存储其令牌。然后服务X将ID返回给用户对象。用户对象通过提供用户 ID 向服务 A 询问用户配置文件。服务 A 获取该 ID 并询问服务 X 该 ID 是否存在。服务 X 发送肯定答案,然后服务 A 可以通过用户 ID 搜索个人资料信息或要求用户提供此类信息以便创建它。相同的逻辑应该适用于 B 和 C 服务。他们必须相互交谈,但不需要了解用户状态。

关于环境的几句话。我建议使用木偶。这是自动化服务部署过程的方法。我们使用木偶在不同的环境中部署服务。puppet脚本是可以实现的并且允许灵活的配置。