且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在Azure Service Fabric中迁移Windows Service

更新时间:2023-02-20 20:00:09

您当然可以将其服务作为来宾可执行文件运行.可以通过将清单中的实例计数设置为1来确保它仅在一个节点上运行,就像这样:

You can certainly run your service as a guest executable. Making sure it only runs on one node can be done by setting the instance count to 1 in the manifest, like so:

  <Parameters>
    <Parameter Name="GuestService_InstanceCount" DefaultValue="-1" />
  </Parameters>
  ...
  <DefaultServices>
    <Service Name="GuestService">
      <StatelessService ServiceTypeName="GuestServiceType" 
                        InstanceCount="[GuestService_InstanceCount]">
        <SingletonPartition />
      </StatelessService>
    </Service>
  </DefaultServices>

或者,您实际上可以迁移它,而不仅仅是在SF环境中重新托管它...

如果您的Windows服务是用.NET编写的,而您又不想从Service Fabric中受益,那么将代码从Windows服务迁移到Service Fabric中的可靠服务的工作就不会太大.

If your Windows Service is written in .NET and the you wan't to benefit from Service Fabric then the job of migrating the code from a Windows Service to a Reliable Service in Service Fabric should not be to big.

如果首先在Service Fabric应用程序中创建无状态服务,那么最终将获得如下服务实现(已删除注释):

If you start by creating a Stateless Service in a Service Fabric application you end up with a service implementation that looks like (comments removed):

internal sealed class MigratedService : StatelessService
{
    public MigratedService(StatelessServiceContext context)
        : base(context)
    { }

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new ServiceInstanceListener[0];
    }

    protected override async Task RunAsync(CancellationToken cancellationToken)
    {
        // TODO: Replace the following sample code with your own logic 
        //       or remove this RunAsync override if it's not needed in your service.
        long iterations = 0;
        while (true)
        {
            cancellationToken.ThrowIfCancellationRequested();
            ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);
            await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
        }
    }

RunAsync方法在服务启动并在群集中的节点上运行后即开始运行.它会继续运行,直到群集出于某种原因决定停止该服务或将其移至另一个节点.

The RunAsync method starts running as soon as the Service is up and running on a node in the cluster. It will continue to run until the cluster, for some reason, decides to stop the service, or move it to another node.

在Windows服务代码中,您应该有一个在启动时运行的方法.通常,您可以在其中设置Timer或类似名称,以连续地开始做某事:

In your Windows Service code you should have a method that is run on start. This is usually where you set up a Timer or similar to start doing something on a continuous basis:

protected override void OnStart(string[] args)
{
  System.Timers.Timer timer = new System.Timers.Timer();
  timer.Interval = 60000; // 60 seconds
  timer.Elapsed += new System.Timers.ElapsedEventHandler(this.OnTimer);
  timer.Start();
}

public void OnTimer(object sender, System.Timers.ElapsedEventArgs args)
{
    ...
    DoServiceStuff();
    Console.WriteLine("Windows Service says hello");
}

现在在OnTimer中获取该代码并将其放入您的RunAsync方法(以及您需要的任何其他代码)中:

Now grab that code in OnTimer and put it in your RunAsync method (and any other code you need):

protected override async Task RunAsync(CancellationToken cancellationToken)
{
    while (true)
    {
        cancellationToken.ThrowIfCancellationRequested();
        DoServiceStuff();
        ServiceEventSource.Current.ServiceMessage(this.Context, 
            "Reliable Service says hello");
        await Task.Delay(TimeSpan.FromSeconds(60), cancellationToken);
    }
}

请注意Task.Delay(...),对于Timer,应将其设置为与Windows服务相同的时间间隔.

Note the Task.Delay(...), it should be set to the same interval as your Windows Service had for it's Timer.

现在,如果您已经登录Windows服务并且使用了ETW,那么应该可以立即使用.您只需要设置某种方式立即从Azure查看这些日志,例如使用Log Analytics( https://docs.microsoft.com/zh-CN/azure/log-analytics/log-analytics-service-fabric ).

Now, if you have logging in your Windows Service and you use ETW, then that should work out of the box for you. You simply need to set up some way of looking at those logs from Azure now, for instance using Log Analytics (https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-service-fabric).

您可能需要迁移的其他事情是,如果在关闭,继续时运行特定的代码,并且在启动时有任何参数发送给服务(例如,数据库的连接字符串).需要将这些设置转换为服务的配置设置,请参阅 SO 33928204 作为起点.

Other things you might have to migrate is if you run specific code on shut down, on continue, and if you have any parameters sent to the service on startup (for instance connection strings to databases). Those need to be converted to configuration settings for the service, look at SO 33928204 for a starting point for that.