如何在微服务中处理数据库架构更新

Sen*_*nne 4 database architecture microservices

我们将从这个模式开始

CREATE TABLE [dbo].[Label]
(
    [Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, 
    [Prefix] VARCHAR(50) NOT NULL UNIQUE,
    [ArtistName] VARCHAR(MAX) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

我们还有一个管理“标签”的微服务。http://labels.example.com/v1/all将以这种格式返回所有标签:

{ Id = xxx, Prefix = xxx, ArtistName = xxx }
Run Code Online (Sandbox Code Playgroud)

我们如何处理不影响此微服务消费者的架构更改?

我们必须进行一些重构,然后艺术家移到他自己的桌子上。

CREATE TABLE [dbo].[Label]
(
    [Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, 
    [Prefix] VARCHAR(50) NOT NULL UNIQUE,
    [ArtistId] UNIQUEIDENTIFIER NOT NULL,

    CONSTRAINT FK_Label_Artist
        FOREIGN KEY (ArtistId) REFERENCES Artist(Id)
)

CREATE TABLE [dbo].[Artist]
(
    [Id] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, 
    [Name] VARCHAR(MAX) NOT NULL,
    [Country] VARCHAR(MAX) NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

我们的微服务需要返回以下对象

{ Id = xxx, Prefix = xxx, Artist = { Id = xxx, Name = xxx, Country = xxx } }
Run Code Online (Sandbox Code Playgroud)

我们将不得不创建一个返回这个新结构的 v2 api 调用。我们还必须将数据迁移到新结构。这意味着 v1 也需要更改以支持新模式,但它仍将返回相同的对象。

当您对微服务进行版本控制时,这是完成工作的方式吗?需要注意的事项?有没有不同的方法来做到这一点?

Osw*_*ann 5

听起来您走在正确的轨道上。微服务架构风格的发明是为了允许组织构建具有明确定义接口的逻辑分离的开发团队。接口是服务 API 或其他任何暴露给消费者的接口。

数据库模式应该是内部服务,因此会随着时间的推移而发展,作为您常规开发过程的一部分。只有在对您的服务使用者产生影响时(通过更改服务接口),您才必须确保有一个正式的版本控制过程。

正式流程还应包括适用于外部依赖项的所有方面。您可以以 facebook 为例,因为他们发布了公共 API 的新版本,并在一段时间后淘汰了旧版本。你应该有一个类似的过程,提前用时间表通知你的消费者,然后并行部署新旧服务版本,让你的消费者有时间采用并最终淘汰旧服务。当您并行运行这两个服务时,您应该监控两者的流量,如果流量没有随着时间的推移而切换,则向您的消费者发送提醒。

简而言之 - 像对待外部依赖一样对待内部依赖。

一些额外的想法:

  • 扩展比修改更容易:有时您可以在不破坏现有使用者的情况下扩展 API 返回的数据结构。在您的示例中,这可能意味着返回如下所示的结构:

    { Id = xxx, Prefix = xxx,  ArtistName = xxx, Artist = { Id = xxx, Name = xxx, Country = xxx } }
    
    Run Code Online (Sandbox Code Playgroud)

    在这里,您将支付数据冗余以保持兼容性。

  • 你应该只是经常更改:通常最好在单个版本升级中积累大量更改,而不是经常升级很少更改。

  • 您可以使用版本架构来指示重大更改:例如,次要版本更改 1.1 与版本 1.0 兼容,但主要版本更改 2.0 与 1.1 不兼容。

  • 客户端适配器:有时 API 带有客户端库,以便更轻松地访问并独立于传输格式等。在这种情况下,客户端库也需要正确版本控制,并且应该支持所有活动版本。

  • 工具:查看像 GraphQL 之类的标准,这些标准有助于完成许多与 API 相关的任务。


小智 0

有多种方法可以做到这一点,我发现的最“正确”的方法是使用媒体类型,以便客户端可以指定它期望返回的版本。这将允许实现休息服务向后移植数据结构,以便仍然可以使用旧版本。这假定这不是一个重大变更,这需要一个谁