如何在微服务架构中管理多对多关系?
How to manage Many To Many relations in microservices architecture?
如果我在两个单独的微服务中有以下实体:
class Employee {
@Id
private Long employeeId;
private String name;
...
}
class Department {
@Id
private Long deptId;
private String name;
...
}
如何在实体之间添加多对多关系?
我想在网关上将两个实体合并为一个实体:
class Empl_Dept{
List<Long> employeeIds;
List<Long> departmentIds;
}
所以结点 table 将在网关端。
有没有更好的解决办法??
每个微服务都应该有自己的数据库,所以连接 table 没有意义,因为它是一个关系解决方案。
您可以考虑这两种方法中的一种,如果 Empl_Dept 是一个域对象,您应该将它放在第三个微服务中,如果它没有将员工关系放入部门,反之亦然。
希望对您有所帮助。
假设您的域建模正确,这似乎是集成事件的简单修复。
向部门服务添加 EmployeeIds
table,向员工服务添加 DepartmentIds
table。当您创建、中断或更改 Employee
和 Department
之间的分配时,发布两个服务都订阅的 EmployeeDepartmentUpdated
事件。然后,每个服务可以处理事件并更新自己的数据以保持同步。
你不想开始将数据放入你的网关API,这不是它的目的(这意味着如果你有多个网关到同一个后端服务,只有一个人会知道该信息)。
拥抱Eventual Consistency,您的微服务之旅会因此变得更好!
编辑:
关于事件对性能和复杂性的影响的问题,答案是 "no" 和 "yes."
首先,不,我不认为事件溯源会对系统性能产生负面影响。事实上,它们的异步性质使事件处理成为与 API 响应能力分开的问题。
我确信有一些方法可以在没有消息传递平面的情况下构建面向服务的架构(SOA,微服务本质上是其中的一个子集),但根据我的经验,拥有一个是松散耦合通信的绝佳方式发生了。
服务之间的任何直接调用——无论协议(HTTP、gRPC 等)如何,都意味着这些服务之间的紧密耦合。端点名称、参数等都是重大更改的机会。当您使用消息传递时,每个服务负责发出向后兼容的事件,并且每个其他服务都可以选择它关心的事件,订阅它们,并且永远不知道发出服务是否 运行,死了,改变等
对于你的第二个问题,答案绝对是"yes" - 事件处理是额外的复杂性。然而,当您选择微服务架构风格时,这是您注册的复杂性的一部分(而且远非最糟糕的)。分布式授权、通过在多个服务之间组织的多个后端调用保持 UI 性能、容错和 health/performance 监控都是(至少以我的经验)更大的挑战。
郑重声明,我们使用了 CloudAMQP.com 的 RabbitMQ 托管实例,效果很好。性能很好,他们有很多可扩展的软件包可供选择,而且我们在性能或停机时间方面的问题为零。最新的 RabbitMQ 3.8 版本现在也包括 OAuth,所以我们目前正在努力将我们的 Authz 流程与我们的消息代理集成,并将有一个很好的端到端安全解决方案。
- 我假设,第三个微服务需要这个多对多映射。然后在员工和部门
之间创建映射 table 就很简单了
- 如果您只有这 2 个微服务,那么您必须在一个服务中添加
employee_department_map
,在第二个服务中添加 department_employee_map
。
在设计微服务时始终考虑到您不能更改其他服务中的任何内容(假设它是第三方服务 api)
如果我在两个单独的微服务中有以下实体:
class Employee {
@Id
private Long employeeId;
private String name;
...
}
class Department {
@Id
private Long deptId;
private String name;
...
}
如何在实体之间添加多对多关系?
我想在网关上将两个实体合并为一个实体:
class Empl_Dept{
List<Long> employeeIds;
List<Long> departmentIds;
}
所以结点 table 将在网关端。
有没有更好的解决办法??
每个微服务都应该有自己的数据库,所以连接 table 没有意义,因为它是一个关系解决方案。
您可以考虑这两种方法中的一种,如果 Empl_Dept 是一个域对象,您应该将它放在第三个微服务中,如果它没有将员工关系放入部门,反之亦然。
希望对您有所帮助。
假设您的域建模正确,这似乎是集成事件的简单修复。
向部门服务添加 EmployeeIds
table,向员工服务添加 DepartmentIds
table。当您创建、中断或更改 Employee
和 Department
之间的分配时,发布两个服务都订阅的 EmployeeDepartmentUpdated
事件。然后,每个服务可以处理事件并更新自己的数据以保持同步。
你不想开始将数据放入你的网关API,这不是它的目的(这意味着如果你有多个网关到同一个后端服务,只有一个人会知道该信息)。
拥抱Eventual Consistency,您的微服务之旅会因此变得更好!
编辑:
关于事件对性能和复杂性的影响的问题,答案是 "no" 和 "yes."
首先,不,我不认为事件溯源会对系统性能产生负面影响。事实上,它们的异步性质使事件处理成为与 API 响应能力分开的问题。
我确信有一些方法可以在没有消息传递平面的情况下构建面向服务的架构(SOA,微服务本质上是其中的一个子集),但根据我的经验,拥有一个是松散耦合通信的绝佳方式发生了。
服务之间的任何直接调用——无论协议(HTTP、gRPC 等)如何,都意味着这些服务之间的紧密耦合。端点名称、参数等都是重大更改的机会。当您使用消息传递时,每个服务负责发出向后兼容的事件,并且每个其他服务都可以选择它关心的事件,订阅它们,并且永远不知道发出服务是否 运行,死了,改变等
对于你的第二个问题,答案绝对是"yes" - 事件处理是额外的复杂性。然而,当您选择微服务架构风格时,这是您注册的复杂性的一部分(而且远非最糟糕的)。分布式授权、通过在多个服务之间组织的多个后端调用保持 UI 性能、容错和 health/performance 监控都是(至少以我的经验)更大的挑战。
郑重声明,我们使用了 CloudAMQP.com 的 RabbitMQ 托管实例,效果很好。性能很好,他们有很多可扩展的软件包可供选择,而且我们在性能或停机时间方面的问题为零。最新的 RabbitMQ 3.8 版本现在也包括 OAuth,所以我们目前正在努力将我们的 Authz 流程与我们的消息代理集成,并将有一个很好的端到端安全解决方案。
- 我假设,第三个微服务需要这个多对多映射。然后在员工和部门 之间创建映射 table 就很简单了
- 如果您只有这 2 个微服务,那么您必须在一个服务中添加
employee_department_map
,在第二个服务中添加department_employee_map
。
在设计微服务时始终考虑到您不能更改其他服务中的任何内容(假设它是第三方服务 api)