如何配置多个Windows Service 解决启动后互相关停运行异常问题
Windows 多服务启动互斥、自动停止问题排查
我此前参照视频教程创建Windows Service,业务逻辑为:定义Model后在Controller中获取Model构造待发送数据,再在Service中调用该Controller。
之后我创建了安装程序,一共部署3个服务,通过在每个服务开头添加[RunInstaller(true)]完成创建,我将服务设置为非手动启动、做了异常预处理后尝试启动服务。但出现了启动其中一个服务后另一个就会关停的问题,偶尔能成功启动3个服务,但很快所有服务又会全部停止运行。
相关代码
ProjectInstaller 截图

ProjectInstaller.Designer.cs
partial class ProjectInstaller { /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region Component Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { this.serviceProcessInstaller1 = new System.ServiceProcess.ServiceProcessInstaller(); this.AccountService = new System.ServiceProcess.ServiceInstaller(); this.FinInfoPrevYearService = new System.ServiceProcess.ServiceInstaller(); this.GetFinancialInfoService = new System.ServiceProcess.ServiceInstaller(); // // serviceProcessInstaller1 // this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalService; this.serviceProcessInstaller1.Password = null; this.serviceProcessInstaller1.Username = null; this.serviceProcessInstaller1.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.serviceProcessInstaller1_AfterInstall); // // AccountService // this.AccountService.ServiceName = "AccountService"; this.AccountService.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.AccountService_AfterInstall); // // FinInfoPrevYearService // this.FinInfoPrevYearService.ServiceName = "FinInfoPrevYearService"; this.FinInfoPrevYearService.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.FinInfoPrevYearService_AfterInstall); // // GetFinancialInfoService // this.GetFinancialInfoService.ServiceName = "GetFinancialInfoService"; this.GetFinancialInfoService.AfterInstall += new System.Configuration.Install.InstallEventHandler(this.GetFinancialInfoService_AfterInstall); // // ProjectInstaller // this.Installers.AddRange(new System.Configuration.Install.Installer[] { this.serviceProcessInstaller1, this.AccountService, this.FinInfoPrevYearService, this.GetFinancialInfoService}); } #endregion private System.ServiceProcess.ServiceProcessInstaller serviceProcessInstaller1; private System.ServiceProcess.ServiceInstaller AccountService; private System.ServiceProcess.ServiceInstaller FinInfoPrevYearService; private System.ServiceProcess.ServiceInstaller GetFinancialInfoService; }
ProjectInstaller.cs
[RunInstaller(true)] public partial class ProjectInstaller : System.Configuration.Install.Installer { public ProjectInstaller() { InitializeComponent(); } private void serviceProcessInstaller1_AfterInstall(object sender, InstallEventArgs e) { } private void AccountService_AfterInstall(object sender, InstallEventArgs e) { } private void GetFinancialInfoService_AfterInstall(object sender, InstallEventArgs e) { } private void FinInfoPrevYearService_AfterInstall(object sender, InstallEventArgs e) { } }
单服务示例截图

排查与修复方案
- 配置维度:确认三个服务没有占用同一个端口、独占文件、全局互斥锁等互斥系统资源;显式给每个服务的
StartType属性设置为Automatic或AutomaticDelayedStart,不要留默认配置。 - 逻辑维度:每个服务的
OnStart方法中必须启动独立的后台常驻线程保活,不要让OnStart主线程执行完直接退出,也不要阻塞OnStart主线程超过30秒(Windows服务启动超时阈值)。 - 异常排查:给每个服务单独配置独立的日志输出,捕获服务退出前的异常堆栈,确认是否是多个服务共用静态资源、数据库连接池出现竞争冲突导致崩溃;排查是否所有服务都注册了同一个全局命名互斥体(Mutex),导致实例互斥启动失败。
内容的提问来源于stack exchange,提问作者Gonçalo Nogueira
相关产品推荐
相关产品推荐

