您现在的位置是:首页 > 技术教程 正文

golang服务控制之go-svc

admin 阅读: 2024-03-19
后台-插件-广告管理-内容页头部广告(手机)

文章目录

  • 程序安全退出
  • 执行代码的基本:信号拦截
  • 执行代码的改进:信号拦截包装器
  • 实践
    • 捕获键盘输入
    • 示例代码
  • go-svc介绍

程序及服务的控制是指在计算机系统中对程序和服务进行管理、监控和调控的过程。这个过程可以涉及到多个方面,包括资源管理、运行状态监测、安全性控制等。本质上而言就是正确的启动,并可控的停止或退出。在go语言中,其实就是程序安全退出、服务控制两个方面。

程序安全退出

在代码部署后,我们可能因为服务配置发生变化或其他各种原因,需要将服务停止或者重启。通常就是for循环阻塞,运行代码,然后通过control+C或者kill来强制退出。代码如下:

//file svc1.go package main import ( "fmt" "time" ) //当接收到Control+c,kill -1,kill -2,kill -9 均无法正常执行defer函数 func main() { fmt.Println("application is begin.") //以下代码不会执行 defer fmt.Println("application is end.") for { time.Sleep(time.Second) fmt.Println("application is running.") } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

但这种情况下,程序是不会执行defer的代码的,因此无法正确处理结束操作,会丢失一些很关键的日志记录、消息通知,非常不安全的。这时,需要引入一个简单的框架,来执行退出。

执行代码的基本:信号拦截

//file svc2.go package main import ( "fmt" "time" "os/signal" "os" ) //当接收到Control+c,kill -1,kill -2 的时候,都可以执行执行defer函数 // kill -9依然不会正常退出。 func main() { fmt.Println("application is begin.") //当程序接受到退出信号的时候,将会执行 defer fmt.Println("application is end.") //协程启动的匿名函数,模拟业务代码 go func(){ for { time.Sleep(time.Second) fmt.Println("application is running.") } }() //捕获程序退出信号 msgChan:=make(chan os.Signal,1) signal.Notify(msgChan,os.Interrupt,os.Kill) <-msgChan }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

此时,我们实现了程序退出时的信号拦截,补充业务代码就可以了。但实际业务逻辑至少涉及到初始化、业务处理、退出三大块,代码量多了,会显得比较混乱,这就需要规范代码的结构。

执行代码的改进:信号拦截包装器

考虑上述情况,我们将正常的程序定义为:

Init: 系统初始化,比如识别操作系统、初始化服务发现Consul、Zookeper的agent、数据库连接池等。
Start:程序主要业务逻辑,包括但不限于数据加载、服务注册、具体业务响应。
Stop: 程序退出时的业务,主要包括内存数据存储、服务注销。

改写之前的代码

//file svc3.go package main import ( "fmt" "time" "study1/svc" ) type Program struct { } func (p *Program) Start()error { fmt.Println("application is begin.") //必须非阻塞,因此通过协程封装。 go func(){ for { time.Sleep(time.Second) fmt.Println("application is running.") } }() return nil } func (p *Program)Init()error{
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索