已经将一个Service改成用Golang实现,效果非常好!这个Service的代码已经开源,GoTasks。
Golang是我目前接触过的语言中,并发编程效率最高。node.js虽然也高,但是时间精准度上,就远远不如Golang了。
一开始看了很多网上的教程,搞得乱七八糟的,后来重新整理一下思路,才发现他的go关键字的奥妙(网友能再坑爹一点不?)。
为什么说他的开发效率高呢,一个主要的原因是,你完全可以用阻塞的方式去封装一个函数,然后通过go关键字调用,使他在运行时并发,这点真的太恐怖了,闭包什么的弱爆了。
举个实际点的例子吧:
func HttpGet(url string) (string, error) { resp, err := http.Get(url) if err != nil { logger.Debug("HttpGet", "请求错误:", err) return "", err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { logger.Debug("HttpGet", "IO/Read错误:", err) return "", err } return string(body), err } func HttpPost(reqUrl string, post string) (string, error) { resp, err := http.PostForm(reqUrl, url.Values{"data": {post}}) if err != nil { logger.Debug("HttpPost", "请求错误:", err) return "", err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { logger.Debug("HttpPost", "IO/Read错误:", err) return "", err } return string(body), err }
假定我有这2个函数,HttpGet、HttpPost,执行肯定会造成阻塞,为了调试方便,阻塞的方式对单个函数的检测,肯定更加容易调试,更加容易监控函数是不是有bug。
但是到了实际执行层面,我们就肯定希望他不要有任何阻塞:
func (task *Task) start() { ch := make(chan int) go task.request() go task.startTicker() <-ch } func (task *Task) request() { logger.Log(task.Name, "开始") start := time.Now() resp, _ := HttpGet(task.Url) complete := time.Now() if globalConfig.ShowComplete > 0 { logger.Log(task.Name, "完成:", complete.Sub(start), "响应内容长度:", len(resp)) } if len(task.PostUrl) > 0 { HttpPost(task.PostUrl, resp) } }
这个代码取自GoTasks的task_service.go,request函数,包装了一个task的任务,先发起一个Get请求,等请求返回以后,将Get的内容发起一个Post请求将内容发送到指定的Url上。request本身是阻塞执行的,而在start中,调用他的方法时候,只要使用go,即可让他并发执行(实际上是发起了go内部调度的子线程之类的东西)。然后在通过channel对这个资源进行回收。
就如朋友所说,恭喜你,终于获得件橙色装备了!
有疑问加站长微信联系(非本文作者)