在生成环境中使用 Go 语言两年的总结

iron.io的生产环境使用Go语言两年后,我想分享我们的经验和感受。我们是第一批在生产环境中使用Go(Go语言)的公司之一,长久以来我们不知道该有怎样的预期,但到目前为止,很棒。

在之前发表的一篇文章从Ruby切换到Go中我谈了一些,但这次将更具细节一些,我们喜欢这门语言以及一路上我们学到的东西。介绍没有特定顺序,按下面这样:

  • 性能表现(Performance)
  • 内存占用(Memory)
  • 并发性(Concurrency)
  • 可靠性(Reliability)
  • 部署(Deployment)
  • 天赋(Talent)

性能表现

当我们第一次决定要使用什么语言时我们做了一些调研,为我们的应用环境、消息队列创建了一些模拟。我用Go写了我偏爱的beanstalkd的一个副本实现,使用beanstalkd协议,这样我可以使用现有的客户端测试。Go的表现的很好,几乎和官方的C语言版本一样(而且令人惊讶的容易写)。

你可以在电脑语言基准测试游戏网站找到Go和其他语言基准测试的比较。下面的图是和Java(Java可能是Go语言不存在时我们应该使用的语言)比较的结果:

 

更多

这个基准测试表明,Go在一些例子下更快一些,但在其他例子中要比Java慢。然而,对于一个只有几岁的语言来说不是太差劲,毫无疑问我认为再给它一些时日它肯定会赶上的。其中你也可以看到,内存占用方面表现也很不错。

只是为了好玩,到底来说C与Go和Ruby之间还有区别,在性能和内存使用方面更让人疯狂。

 


更多 

两年以来,Go从来没成为我们的瓶颈,瓶颈总在数据库上。

内存占用

Go不需要加载虚拟机或解释程序,所以它启动快速和小巧。IronMQ启动时使用~ 6444 KB的内存,其中还包括加载配置、建立连接等。当它运行一段时间后,内存使用增加是因为它增加缓存等。现在,我们的生产服务器运行时内存占用在~400 MB(这个我认为无关紧要,这取决于你的应用程序)。

两年来,我们从来没遇到过内存泄漏或其他内存相关的问题。

并发性(Concurrency)

并发是Go很重要的一部分,但高层次的结构让使用起来很简单。我使用Java很多年了,使用java.util.concurrency包很舒服,这是一个很好的并发性的工具,但它在使用简易性和底层实现上不如Go。Go中使用Goroutines进行并发操作,使用channels在它们之间进行通信。Goroutines非常有趣:

"Goroutines are part of making concurrency easy to use. The idea, which has been around for a while, is to multiplex independently executing functions—coroutines—onto a set of threads. When a coroutine blocks, such as by calling a blocking system call, the run-time automatically moves other coroutines on the same operating system thread to a different, runnable thread so they won't be blocked. The programmer sees none of this, which is the point. The result, which we call goroutines, can be very cheap: unless they spend a lot of time in long-running system calls, they cost little more than the memory for the stack, which is just a few kilobytes. To make the stacks small, Go's run-time uses segmented stacks. A newly minted goroutine is given a few kilobytes, which is almost always enough. When it isn't, the run-time allocates (and frees) extension segments automatically. The overhead averages about three cheap instructions per function call. It is practical to create hundreds of thousands of goroutines in the same address space. If goroutines were just threads, system resources would run out at a much smaller number." Source

One thing we had to do here was limit concurrency to make sure we didn't overload our database or other services during spikes. We did this with a simple semaphore using Go channels.

可靠性

语言的可靠性是难以量化的,但我们发现我们的Go应用非常强大。我们碰到过一些失效/崩溃但是因为一些外部的问题(读:数据库或一些设计差的库)。一般说来,现在有很多高质量的Go开源库。我们还没有发现内存泄漏和重大核心库错误。

我甚至发现我们的代码质量高是由于它是用Go写的。我不知道这是为什么,但用Go时写东西时我感到温暖和柔顺。也许它是非常严格的编译器,甚至迫使我们删掉无用的引用和变量。也许它是用少量代码完成更多事的语言。今后我会找出类似的更多并把它们写出来。

部署

Go 将所有的源码编译成单个的静态链接的文件,所以部署很简单,只要上传文件然后启动就可以,没有任何的依赖。没有运行时的依赖。不需要在服务器上安装Go。并且编译完的二进制很小,IronMQ二进制文件大约6MB

回滚

如果你部署完成后运行有问题并且你需要回滚到先前的程序,只要关闭错误的程序,重新运行先前的程序.程序编译成单个二进制文件后,不需要担心升级之后的依赖问题。

天赋

在我们冒了很大的风险选择Go的时候,Go并没有被很多数人所了解,听说过它的都很少。我们是第一个在Go语言爱好者邮件列表上发出Go招聘职位的公司,我们对申请人的应用质量吃了一惊。我们收到的职位申请中国,有一些使具有非凡经验的顶尖科技公司的开发者,有工作在某些核心项目的博士。大多数都不是使用Go做全时段编程,但在熟练Go和传递他们的经验和知识方面都很努力。我不确定我们试图建立的是否重要,但他们想用Go去工作。

我们第一个Go雇用者是一个Go的核心开发者, Evan Shaw,他现在一直和我们在一起。

总结

经过两年使用Go工作后我可以自信地说,我们做了正确的选择。如果现在我们才开始iron.io的话,Go是想都不用想的选择。很多其他公司现在正在使用Go,包括Heroku,谷歌及和我说及过Go的人都有类似的意见。Rob Pike,一个Go的创造者的说:

我们意识到我们在Google构建的软件使用我们已有的语言并不能完全如设想的提供服务”Pike在2011说。“Robert Griesemer、Ken Thompson和我决定创建一门语言来写谷歌需要的那类程序。 
Derek Collison, Apcera的创立者,近期在 Wired的文章上说:
新技术的管理层和基础设施层提供了这种云交付模型?“他在Wired上这样说。“在两年之内,大部分将用Go来写。 

Go是我们一直在等待的下一代语言吗?这一个点言之过早,但无疑是一个好的开始。

本文来自:CSDN博客

感谢作者:zajin

查看原文:在生成环境中使用 Go 语言两年的总结

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。