【问题标题】:Data Migration into Service Fabric Stateful Service将数据迁移到 Service Fabric 有状态服务
【发布时间】:2018-10-30 15:38:15
【问题描述】:

我有一个有状态的服务,它存储了一堆关于我的用户的数据,这些数据存储在一个可靠的字典中,显然也可以从那里检索它。

不过,我也有一个使用存储此信息的 SQL 数据库。在初始化新的有状态服务实例时,我需要将该信息从我的 SQL 数据库迁移到新的可靠存储机制中。从那时起,有状态的服务就是事实的来源。理想情况下,我想延迟我的有状态服务的可用性,直到这个初始化过程完成。

对于如何做到这一点有什么建议吗?

【问题讨论】:

  • 在状态尚未导入的情况下调用服务时只返回错误状态或抛出异常是否可以接受?这将是迄今为止最容易实现的。或者,您可以尝试使用 Task 或 TaskCompletionSource 在打开通信侦听器之前等待 Task。
  • @PeterBons - 是的,我很乐意服务返回“未准备好”或类似的异常(就像 SF 当前所做的那样)。按照您的建议,我应该在我的服务中覆盖哪个功能?

标签: .net-core service-fabric-stateful azure-service-fabric


【解决方案1】:

类似的东西可以解决问题:

public interface IStateful1 : IService
{
    Task MyMethod();
}

internal sealed class Stateful1 : StatefulService, IStateful1
{
    private bool isReady = false; 

    public Stateful1(StatefulServiceContext context)
        : base(context)
    { }

    public Task MyMethod()
    {
        if(!isReady)
            throw new NotImplementedException(); // Probably throw or return something more meaningful :-) 

        return Task.CompletedTask; // Do your thing here
    }

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
        return new ServiceReplicaListener[0];
    }

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        await Task.Run(() => {
            // Simulation of some work
            Thread.Sleep((int)TimeSpan.FromMinutes(5).TotalMilliseconds);
        });

        isReady = true;
    }
}  

在此设置中,从 DB 导入可靠集合是在 RunAsync 方法中完成的。

不幸的是,AFAIK,以后无法插入通信侦听器。这会让事情变得更容易。

如果CreateServiceReplicaListeners 是一个异步操作,我们可以在这里等待初始化任务,但我们现在不能。使用.Wait() 将不起作用,因为它会报告实例运行时间过长,并将实例标记为不健康。

可以在the docs中找到服务生命周期的完整概述

【讨论】:

    【解决方案2】:

    我不确定我是否正确。但根据您的评论,我建议在迁移期间返回“未准备好”响应的以下解决方案。

    public interface IMigrationService
    {
        bool IsDone();
    }
    
    public class MigrationService : IMigrationService
    {
        private bool migrating = tu;
    
        public bool BeginMigration()
        {
            this.migrating = true;
        }
        public bool EndMigration()
        {
            this.migrating = false;
        }
        public bool IsDone()
        {
            return this.migrating;
        }
    }
    
    // WebHost startup class
    public class Startup
    {
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            // Register a middle-ware that would short circuit responses
            // while migration is in progress.
            app.Use(
                async (context, next) =>
                {
                    var migrationService = 
                        context.RequestServices.GetService<IMigrationService>();
                    if (!migrationService.IsDone())
                    {
                        /* short circuit the response with approriate error message */
                    }
    
                    await next();
                });
    
            app.UseMvc();
        }
    }
    
    public class Stateful : StatefulService
    {
        private readonly IMigrationService migrationService;
    
        public Stateful(StatefulServiceContext context)
          : base(context)
        { 
            this.migrationService = new MigrationService();
        }
    
        protected override IEnumerable<ServiceReplicaListener>
            CreateServiceReplicaListeners()
        {
            /* 
                Create a listener here with WebHostBuilder
    
                Use Startup class with the middle-ware defined and 
                add configure services -> .ConfigureServices() 
                with services.AddSingleton<IMigrationService>(this.migrationService)
            */
        }
    
        protected override async Task 
            RunAsync(CancellationToken cancellationToken)
        {
            this.migrationService.StartMigration();
    
            /* Migration code */
    
            this.migrationService.EndMigration();
        }
    }
    

    这将允许您推出一个新版本的服务,该服务会在迁移过程中缩短所有请求并显示相应的错误消息。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2019-02-09
      • 2017-02-08
      • 1970-01-01
      • 2017-06-22
      • 2018-08-29
      • 1970-01-01
      • 2016-11-16
      • 2020-01-07
      • 1970-01-01
      相关资源
      最近更新 更多