- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
在实际开发过程中,有时候会遇到如何编写Go开机自启服务的需求,在linux中我们可以使用 systemd 来进行托管,windows下可以通过 注册表 来实现,mac下可以通过 launchd 来实现,上面的方式对于开发者来说,并不是什么困难的事情,但是对于使用者而言,是并不希望通过这么复杂的方式来达到开机自启的功能的。这个时候,作为开发者,就需要使用其他的方式来实现开机自启的功能,下面讲一个Go中,借助这个库 github.com/kardianos/service 来简化如何实现开机自启功能.
我们先来看一看 github.com/kardianos/service 上面的自我介绍: Run go programs as a service on major platforms. 。
如何理解上面这句话呢,上面这句话翻译出来的意思是:"在主要平台上将Go程序作为服务运行".
这意味着我们可以将Go编写的程序以 服务 的形式在主要操作系统上运行,例如Windows、Linux、macOS等。这意味着程序可以在后台持续运行,而不需要用户手动启动或停止它们。这种方式可以提高程序的可靠性和稳定性,同时也方便了程序的管理和监控.
那该如何理解 服务 呢?
服务 (Service)是指在计算机系统中,为用户或其他程序提供某种功能的程序或进程。服务通常在 后台运行 ,可以长时间运行,不需要用户交互,可以 自动启动和停止 。服务可以提供各种功能,如网络服务、数据库服务、文件共享服务等。在操作系统中,服务通常以服务进程的形式运行,可以通过系统管理工具进行管理和配置.
有了上面的了解过后,再来看看官方自己的描述。 service will install / un-install, start / stop, and run a program as a service (daemon). Currently supports Windows XP+, Linux/(systemd | Upstart | SysV), and OSX/Launchd. 如何理解上面这句话呢,我说说自己的理解.
我们可以将编写好的代码打包成二进制文件后,通过 二进制文件名 + install / un-install, start / stop 来运行我们的服务,程序将作为服务(守护进程)运行。目前支持Windows XP+、Linux/(systemd|Upstart|SysV)和OSX/Launchd.
Windows controls services by setting up callbacks that is non-trivial. This is very different then other systems. This package provides the same API despite the substantial differences. It also can be used to detect how a program is called, from an interactive terminal or from a service manager. 下面是我的理解:
Windows 通过设置回调来控制服务,这与其他系统非常不同。这个包提供了相同的API,尽管存在很大差异。它还可以用于检测程序是从交互式终端还是从服务管理器调用的.
看到这里的时候,我其他不太理解最后一句话,什么叫从 服务管理器 调用。将在 2.2 章节中介绍.
安装 github.com/kardianos/service 的方式和其他方式一样.
go get github.com/kardianos/service
指定版本方式
go get github.com/kardianos/service@v1.2.2
以下介绍都是基于 github.com/kardianos/service@v1.2.2 进行讲解的.
我们先来看一个简单的例子,代码如下:
package main
import (
"fmt"
"github.com/kardianos/service"
"os"
)
type SystemService struct {}
func (ss *SystemService) Start(s service.Service) error {
fmt.Println("coming Start.......")
go ss.run()
return nil
}
func (ss *SystemService) run() {
fmt.Println("coming run.......")
}
func (ss *SystemService) Stop(s service.Service) error {
fmt.Println("coming Stop.......")
return nil
}
func main() {
fmt.Println("service.Interactive()---->", service.Interactive())
svcConfig := &service.Config{
Name: "custom-service",
DisplayName: "custom service",
Description: "this is github.com/kardianos/service test case",
}
ss := &SystemService{}
s, err := service.New(ss, svcConfig)
if err != nil {
fmt.Printf("service New failed, err: %v\n", err)
os.Exit(1)
}
if len(os.Args) > 1 {
err = service.Control(s, os.Args[1])
if err != nil {
fmt.Printf("service Control 111 failed, err: %v\n", err)
os.Exit(1)
}
return
}
// 默认 运行 Run
err = s.Run()
if err != nil {
fmt.Printf("service Control 222 failed, err: %v\n", err)
os.Exit(1)
}
}
通过 go run main.go 得到如下结果,注意: 程序并不会终止,而是阻塞住了 .
service.Interactive()----> true
coming Start.......
coming run.......
实际上, kardianos/service 为我们提供了下面的参数使用,我们可以通过 go build -o main main.go 编译得到二进制文件,然后使用下面的命令来运行服务.
# 生成开机自启服务所需要的文件,文件位置根据操作系统的不同而不用,linux在 /etc/systemd/system 或者 /lib/systemd/system 下
./main install
# 删除上面生成的文件
./main uninstall
# 开启服务
./main start
# 重启服务
./main restart
# 停止服务
./main stop
接下来以 Linux 为例,进行讲解。其他系统大家可自行尝试.
具体的步骤如下:
1、第一步是编写代码,编写完成后,编译成二进制文件.
代码就以 2.1 中的为例。首先编译成二进制文件.
go build -o main main.go
2、运行 可执行文件.
# 这将在 /etc/systemd/system 或者 /lib/systemd/system 中生成 custom-service.service 文件
# 我这里测试的时候是在 /etc/systemd/system 中生成的
./main install
看到这里,用过systemd的朋友应该可以猜到 kardianos/service 背后是通过什么来实现开机自启的。就是通过 systemd 来管理的.
3、将 custom-service.service 服务设置为开机自启. 。
运行下面命令将我们编写的程序设置为开机自启服务.
# 设置服务开机自启动
systemctl enable test-service.service
# 启动
systemctl start test-service.service
下面是 systemctl 常用的命令.
# 启动
systemctl start test-service.service
# 停止
systemctl stop test-service.service
# 设置服务开机自启动
systemctl enable test-service.service
# 查询是否自启动服务
systemctl is-enabled test-service.service
# 取消服务器开机自启动
systemctl disable test-service.service
# 列出正在运行的服务
systemctl list-units --type=service
接下来我们看看 服务管理器 是什么意思? 1、 ./main install 2、查看 custom-service.service 文件 。
3、执行 systemctl start custom-service.service 后,查看服务运行过程 。
这里就是上面 服务管理器 的作用,也就是说,如何服务是手动运行的,那么 service.Interactive() 返回 true,比如:./main start。如何是系统管理器运行的,则返回 false,比如:systemctl start custom-service.service.
通过上面的例子,我们大概知道了如何使用 github.com/kardianos/service 。实际使用中,一般的服务都可以通过 -h 来查看帮助文档,但是我们我们通过 ./main -h 会报错,所以需要完善下代码,使我们的程序更容易使用。下面,我们一起看看,借助 github.com/urfave/cli/v2 来完成上面的需求.
package main
import (
"fmt"
"github.com/kardianos/service"
"github.com/urfave/cli/v2"
"os"
)
type SystemService struct {}
func (ss *SystemService) Start(s service.Service) error {
fmt.Println("coming Start.......")
go ss.run()
return nil
}
func (ss *SystemService) run() {
fmt.Println("coming run.......")
}
func (ss *SystemService) Stop(s service.Service) error {
fmt.Println("coming Stop.......")
return nil
}
func main() {
app := cli.NewApp()
app.Name = "custom-service"
app.Usage = "how to use custom service"
app.Commands = []*cli.Command{
{
Name: "install",
Action: ctrlAction,
},
{
Name: "uninstall",
Action: ctrlAction,
},
{
Name: "start",
Action: ctrlAction,
},
{
Name: "restart",
Action: ctrlAction,
},
{
Name: "stop",
Action: ctrlAction,
},
}
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "install",
Value: "install",
Usage: "Write the files required for startup",
},
&cli.StringFlag{
Name: "uninstall",
Value: "uninstall",
Usage: "Delete startup files",
},
&cli.StringFlag{
Name: "start",
Value: "start",
Usage: "start the service",
},
&cli.StringFlag{
Name: "stop",
Value: "stop",
Usage: "stop the service",
},
&cli.StringFlag{
Name: "restart",
Value: "restart",
Usage: "restart the service",
},
}
app.Action = startAction
app.Run(os.Args)
}
func createSystemService() (service.Service, error) {
fmt.Println("service.Interactive()---->", service.Interactive())
svcConfig := &service.Config{
Name: "custom-service",
DisplayName: "custom service",
Description: "this is github.com/kardianos/service test case",
}
ss := &SystemService{}
s, err := service.New(ss, svcConfig)
if err != nil {
return nil, fmt.Errorf("service New failed, err: %v\n", err)
}
return s, nil
}
func ctrlAction(c *cli.Context) error {
s, err := createSystemService()
if err != nil {
fmt.Printf("createSystemService failed, err: %v\n", err)
return err
}
err = service.Control(s, c.Command.Name)
if err != nil {
fmt.Printf("service Run 222 failed, err: %v\n", err)
return err
}
return nil
}
func startAction(c *cli.Context) error {
s, err := createSystemService()
if err != nil {
fmt.Printf("createSystemService failed, err: %v\n", err)
return err
}
// 默认 运行 Run
err = s.Run()
if err != nil {
fmt.Printf("service Run failed, err: %v\n", err)
return err
}
return nil
}
大家可以根据自己的需求进行开发,这里只是讲一个简单的案例而已.
编译:
go build -o main main.go
运行:
./main -h
NAME:
custom-service - how to use custom service
USAGE:
custom-service [global options] command [command options] [arguments...]
COMMANDS:
install
uninstall
start
restart
stop
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--install value Write the files required for startup (default: "install")
--uninstall value Delete startup files (default: "uninstall")
--start value start the service (default: "start")
--stop value stop the service (default: "stop")
--restart value restart the service (default: "restart")
--help, -h show help
最后此篇关于浅谈如何使用github.com/kardianos/service的文章就讲到这里了,如果你想了解更多关于浅谈如何使用github.com/kardianos/service的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
你好 StackOverflow。 我在 Github 上遇到了一个奇怪的错误。 存储库 Link 我在 4 个月前创建了一个存储库。并且只向该存储库添加了 2 个贡献者。 • 我没有再添加贡献者但是
我已经配置了 Jenkins Github 拉取请求构建器插件来构建我机构成员提出的每个拉取请求。它就像一个魅力。 但是,构建并没有像在这个不错的 post 中显示的那样将构建状态报告回 github
我只是想知道在任何 GitHub 源代码查看页面上可以查看多少个字符而不会溢出(水平滚动)。 最佳答案 在 OS X v10.9 (小牛队): 谷歌浏览器:125 火狐:122 Safari :121
我一直在寻找可以进入 .github 的事物的零碎示例。 GitHub 存储库上的目录。 我可以看到它用于 GitHub 操作和工作流以及拉取请求和问题模板,但我看不到一个页面,其中概述了您可以在理想
尝试运行 --is-bare-repository 命令,但意识到在我的克隆副本上运行它是不正确的。有没有办法在实际的 GitHub 存储库上使用相同的命令?存储库也没有显示 .git 文件。请原谅我
我正在使用 github 页面和 jekyll 创建一个博客。我想知道是否有一种方法可以将 github 文件(即存储库中的文件)中的代码片段嵌入到博客文章中。我可以在此页面上找到有关嵌入要点的解决方
我在 GitHub 存储库中有一个文件,需要通过运行命令偶尔更新。 作为 GitHub Workflows 的一部分,我想让一个机器人运行一个命令,并查看它是否在 repo 上创建了一个差异,如果是,
尝试从 Github 桌面应用程序发布到 github.com 时出现以下错误。 GitHub Desktop was unable to store the account token in the
类似于Desktop notifications from GitHub (从 10 年前开始)但提出了一个稍微不同的问题 - GitHub 是否支持 web notifications ?我想知道关
我想使用 semantic-release 在 Github 版本上发布整个目录(构建目录),但不幸的是它将每个构建文件作为单个 Assets 发布。 用于复制: 我正在使用 Vue CLI 生成一个
这让我发疯,我知道这听起来像是一个愚蠢的问题,但我已经为此苦苦挣扎了 2 天。我刚刚完成了 Visual Code 的编码,我想将它推送到 github 上。所以我创建了一个名为 mern-maps
在 GitHub 上,一个用户可以属于多个组织。一个存储库是否也可以成为多个组织的一部分? 最佳答案 根据 this blog post by GitHub , 一个仓库只能属于一个组织。 Creat
在 GitHub 操作中,我使用脚本创建了一个文件。然后我可以使用 git 创建一个分支,添加文件,提交文件并将分支推送到 repo。全部使用 git。 然后我想从我的操作中创建一个 PR,所以我使用
在 GitHub 中,当我转到:[Insights] - [Networks] 时,我看到我的分支有不同的颜色。有些在 blue , 其他人在 green .我找不到解释。 有谁知道不同颜色是什么意思
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我只是在尝试 GitHub。 为什么有些提交显示为“一天前在 GitHub 上提交”而其他提交显示为“一天前提交”? 例如这里: https://github.com/apple/swift/comm
有没有办法更改 Github 上的配色方案以进行语法高亮显示?我已经进行了基本搜索,但找不到答案。 最佳答案 目前没有办法改变服务器端的配色方案。 github.com 的几个用户已经要求 自定义语法
Github 上关闭的拉取请求是否意味着拉取请求未合并? 如果没有,有没有办法确定已关闭的拉取请求是否已合并? 谢谢。 最佳答案 If no, is there a way I can determi
不确定这是否与主题无关,但我真的很好奇这种类型的图表是否有名称以及如何创建。 像这样:https://help.github.com/articles/viewing-contributions-on
GitHub 中合作者和贡献者的拉取请求有什么区别?我没有发现合作者有任何特殊特权。 最佳答案 合作者对贡献者的一项特权是......他们(合作者)可以直接推送到您的存储库(因为您拥有 added t
我是一名优秀的程序员,十分优秀!