Just For Fun

使用GO编写Linux运维工具

GO语言有着简洁的C系语法和基于消息传递的并发模型. 它具备脚本语言的开发效率的同时又拥有静态编译型语言的执行效率。编译出的ELF二进制执行文件在目标平台上部署非常方便,基本上简单的”拷贝,授权,运行”三步足矣 .在一些较老的系统环境下,不用像使用脚本语言那样担心解释器的版本兼容性问题. Google对GO的定位“新的系统编程语言”在这一点上稍有体现.

最近手头的一个Web系统莫名出现不定期的停止响应请求的情况,由于某些原因我不愿意花精力对该诡异事件进行深入分析。所以需要写一个简单的周期性运行程序检查该Web服务的运行状况,在发现问题时重启服务. 使用Python编写这个程序很方便,超时检查可以依赖urllib2.urlopen方法的timeout参数。程序快写完时发现timeout参数是python2.6中才新增的.而我们的部署环境上Python版本仅为2.3.以其把timeout参数实现的功能port到老版本的Python中,为什么不用GO呢?

这个程序需要检查指定的URL上的Web服务运行正常(在特定时间内响应;响应状态标示正常;返回文本的体积大于某一特定值),在发现事故时执行特定重启脚本.虽然GO的http库也没有提供内置的timeout,但使用GO风格的并发,实现超时检查很方便,关键代码片段如下:

    live_marker_ch := make(chan bool)                            // 创建go-channel用于不同go-routine中传递服务器正常表示消息
    go checkServerLive(monitor_url,liveCondition,live_marker_ch) // 使用一个go-routine判断请求返回的值在正常范围
    time_out_ch := make(chan bool)                               //创建go-channel用于不同go-routine中传递超时请求标示
    go func(ch chan bool){
        time.Sleep(REQUEST_TIME_OUT_VALUE)
        ch <- true      
    }(time_out_ch)                  //创建一个匿名函数并在一个go-routine中运行,在超时时通过上一步创建的go-channel对外进行通知
    select {
    case <- time_out_ch:           //超时情况发生时
        fmt.Println("server response timeout!!!")
        serverDeadAction()
    case is_live := <- live_marker_ch:   //请求返回分析完成时
        if is_live{
            fmt.Println("server live")
        }else{
            fmt.Println("server return value error!!!")
            serverDeadAction()
        }
    }

这个程序完整源码和使用帮助可以在 http://trac.lvscar.info/wiki/pacemaker 这里找到. 跑了一周下来,效果不错 ;-)