美文网首页运维部署
部署jar包windows服务工具

部署jar包windows服务工具

作者: code2roc | 来源:发表于2022-08-05 22:49 被阅读0次

    背景

    某个周末一个线上项目因为服务器自动重启导致了系统挂了,我们是通过jenkins部署的jar包所以需要手动重启项目,解决问题后准备调换部署方式让项目随系统自动启动,试用tomcat后发现启动慢,并且日常开发springboot都是使用内置tomcat启动,如果要保持和部署方式保持一致(避免本地代码执行和部署方式不一致导致的bug),需要配置外部tomcat比较麻烦,所以决定还是以java -jar命令方式启动并注册为window服务

    项目地址:https://gitee.com/code2roc/deploy-jar-util

    环境依赖

    • windows系统

    • 安装framework4.0

    • 安装jdk配置环境变量

      jdk可以使用免安装版本(1.8)点击bat文件快速一键配置,下载地址如下

      https://yunpan.360.cn/surl_y83kPfrK6n7 (提取码:c4f2)

    功能介绍

    工具包含【服务名称】【jar包路径】【部署端口】【执行结果】【操作按钮】五个部分

    • 服务名称

    对应的就是安装后windows服务的名字

    • jar包路径

    部署项目的jar文件物理路径

    • 部署端口

    默认为空不指定使用配置文件中端口,指定后使用自定义端口

    • 执行结果

    显示安装/卸载/启动/关闭服务适输出的操作日志

    • 操作按钮

    在进行服务操作前必须将所有配置确定输入后点击保存配置按钮

    安装/卸载/启动/停止四个按钮对应相关windows服务的操作

    服务安装后默认停止状态,需要手动启动,服务启动方式为自动

    点击启动服务后会自动弹出启动日志界面动态刷新日志内容,若关闭了日志窗口,则进入deploylog文件夹查看deploy.out.log文件,每次启动项目该文件内容自动重置清除


    Opearte1.png Opearte2.png Opearte3.png

    实现介绍

    window服务安装

    使用开源组件winsw(https://github.com/winsw/winsw/),获取编译好的exe运行文件和xml配置文件,调用cmd进行相关命令操作,例如安装操作如下所示,页面相关配置保存读取直接操作xml文件即可

      private void btn_InstallService_Click(object sender, EventArgs e)
            {
                string command = "deploy.exe install";
                StartCmd(AppDomain.CurrentDomain.BaseDirectory, command, FinishCommand);
            }
      public void StartCmd(String workingDirectory, String command, EventHandler FinsishEvent)
            {
                Process p = new Process();
                p.StartInfo.FileName = "cmd.exe";
                p.StartInfo.WorkingDirectory = workingDirectory;
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardInput = true;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.StartInfo.CreateNoWindow = true;
                p.EnableRaisingEvents = true;  // 启用Exited事件  
                p.Exited += FinsishEvent;   // 注册进程结束事件  
                p.Start();
                p.StandardInput.WriteLine(command);
                p.StandardInput.WriteLine("exit");
                p.StandardInput.AutoFlush = true;
                string strOuput = p.StandardOutput.ReadToEnd();
                txt_Result.Text = strOuput;
                //等待程序执行完退出进程
                p.WaitForExit();
                p.Close();
            }
    

    服务状态监控

    通过引入System.ServiceProcess程序集调用服务相关api

      public void InitOpStatus()
            {
                btn_InstallService.Enabled = false;
                btn_StartService.Enabled = false;
                btn_UnstallService.Enabled = false;
                btn_StopService.Enabled = false;
                var serviceControllers = ServiceController.GetServices();
                bool existservice = false;
                foreach (var service in serviceControllers)
                {
                    if (service.ServiceName == txt_ServerName.Text)
                    {
                        existservice = true;
                        break;
                    }
                }
                if (existservice)
                {
                    var server = serviceControllers.FirstOrDefault(service => service.ServiceName == txt_ServerName.Text);
                    if (server.Status == ServiceControllerStatus.Running)
                    {
                        //服务运行中允许停止
                        btn_StopService.Enabled = true;
                    }
                    else
                    {
                        //服务未运行允许卸载和启动
                        btn_UnstallService.Enabled = true;
                        btn_StartService.Enabled = true;
                    }
                }
                else
                {
                    //无此服务允许安装
                    btn_InstallService.Enabled = true;
                }
    
            }
    

    启动日志显示

    使用定时器,不断刷新deploylog\deploy.out.log日志文件

       System.Windows.Forms.Timer timer;
            public LogForm()
            {
                InitializeComponent();
            }
    
            private void LogForm_Load(object sender, EventArgs e)
            {
                timer = new System.Windows.Forms.Timer();
                //1秒间隔
                timer.Interval = 1000;
                //执行事件
                timer.Tick += (s, e1) =>
                {
                    RefreshLogContent();
                };
                //开始执行
                timer.Start();
            }
    
    
            public void RefreshLogContent()
            {
                string logPath = AppDomain.CurrentDomain.BaseDirectory + "deploylog\\deploy.out.log";
                string logContent = ReadFileContent(logPath);
                SetTextCallback d = new SetTextCallback(SetText);
                this.txt_Log.Invoke(d, new object[] { logContent });
            }
    
            public string ReadFileContent(string FileFullName)
            {
                if (File.Exists(FileFullName))
                {
                    System.IO.FileStream fs = new System.IO.FileStream(FileFullName, System.IO.FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    string FileContent = "";
                    try
                    {
                        int fsLen = Convert.ToInt32(fs.Length);
                        byte[] heByte = new byte[fsLen];
                        int r = fs.Read(heByte, 0, heByte.Length);
                        FileContent = System.Text.Encoding.Default.GetString(heByte);
                    }
                    catch (Exception e)
                    {
                        throw;
                    }
                    finally
                    {
                        fs.Close();
                        fs.Dispose();
                    }
                    return FileContent;
                }
                else
                {
                    return "";
                }
    
            }
    
            delegate void SetTextCallback(string text);
    
            private void SetText(string text)
            {
                txt_Log.Text = "";
                txt_Log.AppendText(text);
            }
    
            private void LogForm_FormClosed(object sender, FormClosedEventArgs e)
            {
                timer.Stop();
            }
    

    相关文章

      网友评论

        本文标题:部署jar包windows服务工具

        本文链接:https://www.haomeiwen.com/subject/vdnvwrtx.html