如何在 Azure 服务结构中迁移 Windows 服务
Posted
技术标签:
【中文标题】如何在 Azure 服务结构中迁移 Windows 服务【英文标题】:How To migrate windows service in Azure service fabric 【发布时间】:2017-05-24 22:54:21 【问题描述】:我想使用 Service Fabric 将使用 .net 编写的典型 Windows 服务迁移到 Azure。
为了实现这一点,我正在创建一个服务结构应用程序,其中包含一个微服务作为来宾可执行文件,它使用 Windows 服务的 .exe 并将应用程序包部署到服务结构集群。
在集群上部署服务结构应用程序后,我希望 Windows 服务应该在所有节点上自动安装和启动,但是任何时候应用程序都在任何单个节点上运行。我希望 Windows 服务一次只能在一个节点上运行。
请帮助实现这一点。
【问题讨论】:
您可以为您的服务指定实例计数为 1。另请阅读:***.com/a/39786939/5946937 【参考方案1】:您当然可以将您的服务作为来宾可执行文件运行。确保它只在一个节点上运行可以通过在清单中将实例计数设置为 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 以了解其起点。
【讨论】:
我知道这是一个有点老的问题,但我在迁移时遇到了同样的问题。缺少的一件事是如何从on shutdown
迁移代码。现在,当我优雅地停止我的服务时,它首先在关闭之前结束它的工作(我打电话给RequestAdditionalTime
)。同样的事情适用于面料吗?例如,我希望我的 PDF 在我的服务停止之前完成生成。
SF 不一样。该服务将连续循环运行,直到取消。取消可能有多种原因(SF 正在更改您的副本角色、代码升级、节点崩溃等)。上面代码中的cancellationToken.ThrowIfCancellationRequested() 点是您可以尝试打包并完成正在进行的工作负载(例如PDF 生成)的点。【参考方案2】:
服务结构背后的理念是,它可以管理您的服务,从部署到运行。将服务/应用程序部署到服务结构实例后,它就像运行 Windows 服务(有点),因此您不需要安装 Windows 服务。如果您使用的是 TopShelf 之类的东西,您只需运行 exe,一切都会在服务结构中运行良好。
【讨论】:
以上是关于如何在 Azure 服务结构中迁移 Windows 服务的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Azure Devops 服务器迁移到 Azure Devops 服务中的现有组织
为 CakePHP Web 应用程序将 phpMyAdmin 数据库迁移到 Windows Azure
如何在 Azure 的 ConfigurationManager.ConnectionStrings 上使用 ConnectionStrings 创建 EF 迁移?
如何将 TFVC 项目从 Azure DevOps 服务器迁移到新的 Azure DevOps 帐户作为 Git 存储库