我的目标是创建一个体系结构,其中服务应该能够彼此独立地部署并且是完全自治的,但是如果有2个服务从DB读取相同的对象类型,您会怎么做?
在我的情况下,我有一个套接字服务器(微服务1)和一个http服务器(微服务2)。使用http服务器,我的用户创建一个名为A的资产:此资产存储在数据库中,并返回mongoID。然后,使用另一个协议和ID,调用套接字服务器需要检查该ID的有效性,因此需要从DB读取。这两个服务必须共享A的模型才能将其映射到一个对象,但这意味着这两个服务必须共享代码,这是不行的。
我需要其他服务吗?或者我应该只使service1能够从DB读取然后使第二个与服务1进行通信?
答案 0 :(得分:6)
两个微服务不应共享相同的数据模型。您可以创建一个独立负责管理数据持久性的服务,并可以在其他服务中使用它。
答案 1 :(得分:5)
...有调用套接字服务器需要检查该ID的有效性,因此需要从DB读取。这两个服务必须共享A的模型才能将其映射到一个对象,......
嗯 - 不,他们不需要共享代码!他们真正需要的唯一事情就是对数据库架构的共同理解(我假设您使用的是MongoDB)。这种理解是来自共享库中的共享类定义还是来自单独库中的重复类定义并不重要。许多开发人员现在都会因为违反DRY(不要重复自己)原则而开始尖叫我,但是对于微服务,很多东西都与我们习惯的东西不同!
在她的回答中,Priti Singh表示:
两个微服务不应共享相同的数据模型
这在微服务环境中是正确的并且被认为是良好的做法!让我告诉你原因:
在微服务模式中,服务应该独立于其他服务并且具有定义良好的接口。让两个不同的服务读取相同的DB使得该DB成为另一个服务" service" (我知道,很奇怪,对吧?!?)。根据定义,这个数据库现在需要一个定义良好的接口 - 这在无模式数据库中很难;-)不使数据库像服务那样行事的另一个原因是,一个服务的变化总会对另一个服务产生一些影响。服务访问数据。这意味着,改变"架构"在一个服务上也可能会强制您更改另一个服务,只是为了让您的系统保持运行!当您考虑使用> 100服务的完整微服务系统时,这是一个令人头疼的问题。
这就是为什么你的第二个想法:
...或者我应该只使service1能够从DB读取然后让第二个与服务1进行通信?
好多了。使用可定义版本的明确定义的接口将数据库隐藏在服务之后。像这样,您可以根据自己的心愿重构服务1,而不必影响其他服务。一旦您需要对界面进行重大更改 - 为其提供新版本并开始迁移其他服务以使用新界面。
你问题中潜在的争议是耦合与重复之间的争议。共享一个接口定义和数据库是耦合的(在一个小的改变之后的类型的耦合中唤醒你),但是将数据库模式复制到两个服务是重复的。我相信耦合会在重复之前很久就会杀了你,但是采取你的第二种方法,让http-service访问socks-service然后访问数据库应该删除重复以及减少耦合!
请告诉我这是否有用!
答案 2 :(得分:2)
微服务有助于解决耦合问题,实现您需要保持服务/组件自治,这意味着它们不能共享任何内容,而不是代码程序集或任何资源,尤其不是数据库。强>
如果您需要数据的只读副本,您可以使用发布订阅等模式来保存组件所需的某些信息的本地副本(订阅NewUserCreatedEvent
之类的事件:创建了新用户并且他的ID例如,这是guid),系统中只有一个用户数据的所有者,并且所有者是唯一可以修改他拥有的数据状态的人,系统中的其余组件可以保留本地参考数据的副本仅供参考。
此资产存储在数据库中,并返回mongoID。然后,使用 另一个协议和ID,有调用套接字服务器 需要检查该ID的有效性,因此需要从DB中读取
在您的场景中,创建用户的客户端应提供id(guid),拥有用户的组件(因此它是创建用户的组件)将发布其他组件(服务)订阅和存储的事件它在自己的数据库中需要的数据。
这有意义吗?