database 微服务:如何处理外键关系
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44870461/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Microservices: how to handle foreign key relationships
提问by
Microservices architecture suggest that each service should handle it's own data. Hence any service (Service A) dependent on data owned by other service (service B) should access such data not by making direct DB calls but through the api provided by the second service (service B).
微服务架构建议每个服务都应该处理自己的数据。因此,依赖于其他服务(服务 B)拥有的数据的任何服务(服务 A)不应通过直接调用 DB 而是通过第二个服务(服务 B)提供的 api 访问此类数据。
So what does microservices best practices suggest on checking foreign key constrains.
那么微服务最佳实践对检查外键约束有什么建议呢?
Example: I am developing a delivery feature (microservice 1) for products and certain products are deliverable to only certain locations as mentioned in the products table accessible to only products micro service (mircoservice 2).
示例:我正在为产品开发交付功能(微服务 1),并且某些产品只能交付到只有产品微服务(微服务 2)可访问的产品表中提到的某些位置。
How do I make sure that microservice 1 (i.e delivery feature) does not take an order to a unserviced location. I have this question because delivery feature can not directly access products database, so there is no constraints applicable at DB level when a delivery order is place in to delivery data base (no check is possible to see if a foreign key match exists in products database or table).
我如何确保微服务 1(即交付功能)不会将订单带到未提供服务的位置。我有这个问题,因为交付功能不能直接访问产品数据库,所以当交付订单放入交付数据库时,在 DB 级别没有适用的约束(无法检查产品数据库中是否存在外键匹配)或表)。
回答by Ali Sa?lam
It is possible to use a shared database for multiple microservices. You can find the patterns for data management of microservices in this link: http://microservices.io/patterns/data/database-per-service.html. By the way, it is a very useful blog for microservices architecture.
可以为多个微服务使用共享数据库。您可以在此链接中找到微服务数据管理的模式:http: //microservices.io/patterns/data/database-per-service.html。顺便说一句,这是一个非常有用的微服务架构博客。
In your case, you prefer to use database per service pattern. This make microservices more autonomous. In this situation, you should duplicate some of your data among multiple microservices. You can share the data with api calls between microservices or you can share it with async messaging. It depends on your infrastructure and frequency of change of the data. If it is not changing often, you should duplicate the data with async events.
在您的情况下,您更喜欢按服务模式使用数据库。这使微服务更加自治。在这种情况下,您应该在多个微服务之间复制一些数据。您可以通过微服务之间的 api 调用共享数据,也可以通过异步消息共享。这取决于您的基础架构和数据更改频率。如果它不经常更改,您应该使用异步事件复制数据。
In your example, Delivery service can duplicate delivery locations and product information. Product service manage the products and locations. Then the required data is copied to Delivery service's database with async messages (for example you can use rabbit mq or apache kafka). Delivery service does not change the product and location data but it uses the data when it is doing its job. If the part of the product data which is used by Delivery service is changing often, data duplication with async messaging will be very costly. In this case you should make api calls between Product and Delivery service. Delivery service asks Product service to check whether a product is deliverable to a specific location or not. Delivery service asks Products service with an identifier (name, id etc.) of a product and location. These identifiers can be taken from end user or it is shared between microservices. Because the databases of microservices are different here, we cannot define foreign keys between the data of these microservices.
在您的示例中,送货服务可以复制送货地点和产品信息。产品服务管理产品和位置。然后将所需的数据与异步消息一起复制到交付服务的数据库(例如,您可以使用 rabbit mq 或 apache kafka)。送货服务不会更改产品和位置数据,但会在执行其工作时使用这些数据。如果交付服务使用的产品数据部分经常更改,则异步消息传递的数据复制将非常昂贵。在这种情况下,您应该在 Product 和 Delivery 服务之间进行 api 调用。交付服务要求产品服务检查产品是否可交付到特定位置。交付服务向产品服务询问产品和位置的标识符(名称、ID 等)。这些标识符可以从最终用户那里获取,也可以在微服务之间共享。因为这里微服务的数据库不同,我们无法在这些微服务的数据之间定义外键。
Api calls maybe easier to implement but network cost is higher in this option. Also your services are less autonomous when you are doing api calls. Because, in your example when Product service is down, Delivery service cannot do its job. If you duplicate the data with async messaging, the required data to make delivery is located in the database of Delivery microservice. When Product service is not working you will be able to make delivery.
Api 调用可能更容易实现,但在此选项中网络成本更高。当您进行 api 调用时,您的服务也不太自主。因为,在您的示例中,当产品服务关闭时,交付服务无法完成其工作。如果使用异步消息复制数据,则交付所需的数据位于交付微服务的数据库中。当产品服务不工作时,您将能够交付。
回答by Sean Farmar
When distributing your code to achieve reduced coupling, you want to avoid resource sharing, and data is a resource you want to to avoid sharing.
在分发代码以实现降低耦合时,您要避免资源共享,而数据是您要避免共享的资源。
Another point is that only one component in your system owns the data (for state changing operations), other components can READ but NOT WRITE, they can have copies of the data or you can share a view model they can use to get the latest state of an object.
另一点是系统中只有一个组件拥有数据(用于状态更改操作),其他组件可以读取但不能写入,它们可以拥有数据的副本,或者您可以共享它们可用于获取最新状态的视图模型的一个对象。
Introducing referential integrity will reintroduce coupling, instead you want to use something like Guids for your primary keys, they will be created by the creator of the object, the rest is all about managing eventual consistency.
引入参照完整性将重新引入耦合,相反,您希望为主键使用 Guid 之类的东西,它们将由对象的创建者创建,其余的都是关于管理最终一致性。
Take a look at Udi Dahan's talk in NDC Oslo for a more details
更多细节请看 Udi Dahan在 NDC Oslo的演讲
Hope this helps
希望这可以帮助

