Golang 创建守护进程以及平滑重启

栏目: Go · 发布时间: 7年前

内容简介:作为一名 PHP 开发老兵。使用过命令行对 nginx、PHP-FPM 进行启动/重启/停止等操作。印象非常深刻。让我用 C/C++ 开发这样的系统肯定是没精力搞了。然而,自从 Golang 进入了我的视野之后。我发现这一切都变得非常的容易。直接上代码:对 Linux 系统熟悉的人应该知道:用户创建的守护进程会被 Linux 系统的 1 号进程接管。换句话说,上面的代码只能在 Linux 系统运行。Unix 系统我没有玩过。所以,也不能给出具体的建议。

作为一名 PHP 开发老兵。使用过命令行对 nginx、PHP-FPM 进行启动/重启/停止等操作。印象非常深刻。让我用 C/C++ 开发这样的系统肯定是没精力搞了。然而,自从 Golang 进入了我的视野之后。我发现这一切都变得非常的容易。

1)生成守护进程

直接上代码:

package main

import (
    "os"
    "os/exec"
    "path/filepath"
)

func main() {
    //判 断当其是否是子进程,当父进程return之后,子进程会被 系统1 号进程接管
    if os.Getppid() != 1 {
        // 将命令行参数中执行文件路径转换成可用路径
        filePath, _ := filepath.Abs(os.Args[0])
        cmd := exec.Command(filePath, os.Args[1:]...)
        // 将其他命令传入生成出的进程
        cmd.Stdin = os.Stdin // 给新进程设置文件描述符,可以重定向到文件中
        cmd.Stdout = os.Stdout
        cmd.Stderr = os.Stderr
        cmd.Start() // 开始执行新进程,不等待新进程退出
        return
    }
}

Linux 系统熟悉的人应该知道:用户创建的守护进程会被 Linux 系统的 1 号进程接管。换句话说,上面的代码只能在 Linux 系统运行。Unix 系统我没有玩过。所以,也不能给出具体的建议。

我在网上看到还有其他的方法实现守护进程的创建。但是,我觉得只有上面源码的方式我觉得不错。并且成功用于项目当中。

比如:

os.StartProcess() 创建守护进程。
syscall.RawSyscall() 创建守护进程。

唯独 exec.Command 创建守护进程的方式最高级。封装得最好。推荐使用这种试。

2) 守护进程启动/重启/停止

在第 1 点当中,我们已经成功启动了一个守护进程。但是,我们不可能使用 kill 命令去结束它。然后,再启动吧。所以,我们要用业界专业的手法:信号。

任何进程在运行中都能接收到我们发送给它的信号。关于 Linux 的信号有很多。大家可以自己 Google 搜索关键词:Linux 信号。

直接上源码:

package main

import "fmt"
import "os"
import "os/signal"
import "syscall"

func main() {

    // Go signal notification works by sending `os.Signal`
    // values on a channel. We'll create a channel to
    // receive these notifications (we'll also make one to
    // notify us when the program can exit).
    sigs := make(chan os.Signal, 1)
    done := make(chan bool, 1)

    // `signal.Notify` registers the given channel to
    // receive notifications of the specified signals.
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    // This goroutine executes a blocking receive for
    // signals. When it gets one it'll print it out
    // and then notify the program that it can finish.
    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        done <- true
    }()

    // The program will wait here until it gets the
    // expected signal (as indicated by the goroutine
    // above sending a value on `done`) and then exit.
    fmt.Println("awaiting signal")
    <-done
    fmt.Println("exiting")
}

有三个关键点:

1)注册信号

2)接收信号

3)处理信号。

只要把创建守护进程与信号量处理整合一起,就能实现命令去管理守护进程了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Bulletproof Web Design

Bulletproof Web Design

Dan Cederholm / New Riders Press / 28 July, 2005 / $39.99

No matter how visually appealing or packed with content a Web site is, it isn't succeeding if it's not reaching the widest possible audience. Designers who get this guide can be assured their Web site......一起来看看 《Bulletproof Web Design》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

MD5 加密
MD5 加密

MD5 加密工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试