我想使用Service Fabric将以.net编写的典型Windows服务迁移到Azure。
为了实现这一点,我正在创建一个包含一个微服务作为来宾可执行文件的服务结构应用程序,该应用程序使用Windows服务的.exe,并将应用程序包部署到服务结构群集。
在群集上部署Service Fabric应用程序后,我希望Windows Service应该在所有节点上自动安装并启动,但是应用程序随时都可以在任何单个节点上运行。我希望Windows服务一次只能在一个节点上运行。
请帮助实现这一目标。
您当然可以将其服务作为来宾可执行文件运行。通过将清单中的实例计数设置为1,可以确保仅在一个节点上运行,如下所示:
...
或者,您实际上可以迁移它,而不仅仅是在SF环境中重新托管它...
如果您的Windows服务是用.NET编写的,而您又不想从Service Fabric中受益,那么将代码从Windows服务迁移到Service Fabric中的可靠服务的工作就不会太大。
基本服务示例:如果从在Service Fabric应用程序中创建无状态服务开始,那么最终将得到如下服务实现(已删除注释):
internal sealed class MigratedService : StatelessService { public MigratedService(StatelessServiceContext context) : base(context) { } protected override IEnumerableCreateServiceInstanceListeners() { 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/zh-cn/azure/log-analytics/log-analytics-service-fabric)。
您可能还需要迁移的其他事情是,如果在关闭,继续时运行特定的代码,并且在启动时将任何参数发送给服务(例如,数据库的连接字符串)。那些需要转换为该服务的配置设置,请参阅SO 33928204作为起点。