我想使用Service fabric将使用.net编写的典型Windows服务迁移到Azure。
为了实现这一点,我创建了一个服务结构应用程序,其中包含一个微服务作为来宾可执行文件,它使用.exe的Windows服务并将应用程序包部署到服务结构集群。
在群集上部署服务架构应用程序后,我希望Windows服务应该安装&然后在所有节点上自动启动,但应用程序在任何单个节点上运行。我希望Windows服务一次只能在一个节点上运行。
请帮助实现这一点。
答案 0 :(得分:3)
您当然可以将您的服务作为来宾可执行文件运行。确保它只在一个节点上运行可以通过在清单中将实例计数设置为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应用程序中创建无状态服务,最终会得到一个看起来像的服务实现(删除注释):
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作为起点。
答案 1 :(得分:1)
服务结构背后的理念是管理您的服务,从部署和运行。一旦将服务/应用程序部署到服务结构实例,它就像运行Windows服务(有点),因此您不需要安装Windows服务。如果您正在使用类似TopShelf的东西,您可以运行exe,一切都将在服务结构中完全运行。