您当然可以将您的服务作为来宾可执行文件运行。确保它只在一个节点上运行可以通过在清单中将实例计数设置为 1 来完成,如下所示:
<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 中的可靠服务的工作应该不会太大。
基本服务示例:
如果您首先在 Service Fabric 应用程序中创建无状态服务,您最终会得到一个看起来像(已删除 cmets)的服务实现:
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 方法就会开始运行。它将继续运行,直到集群出于某种原因决定停止服务或将其移动到另一个节点。
在您的 Windows 服务代码中,您应该有一个在启动时运行的方法。这通常是您设置Timer 或类似的地方以开始连续做某事:
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 方法(以及您需要的任何其他代码):
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(...),它应该设置为与您的Windows 服务为Timer 设置的相同间隔。
现在,如果您已登录 Windows 服务并使用 ETW,那么这对您来说应该是开箱即用的。您现在只需设置某种方式来查看来自 Azure 的这些日志,例如使用 Log Analytics (https://docs.microsoft.com/en-us/azure/log-analytics/log-analytics-service-fabric)。
您可能需要迁移的其他事项是,如果您在关闭、继续运行特定代码,以及是否在启动时向服务发送了任何参数(例如到数据库的连接字符串)。这些需要转换为服务的配置设置,请查看SO 33928204 以了解其起点。