-Go生态系统18%
-Martini28%
-Gorm42%
-第三方服务54%
-开发者工具66%
-前往生产75%
-总结87%
我们公司MobileJazz[1]从一个内部试验性项目开始使用Go[2]。如公司名暗示的那样,我们是开发移动应用的。
在发布一个应用给公众后,我们很快意识到我们缺失一个工具来检查用户实际发生的情况以及他们是如何与应用交互的-如果有任何问题或者bug的报告,这将会相当方便。
现在有几款工具声称能在这个方面帮助开发者,但是没有一个能完全满足要求,因此我们决定自己构建一个。我们开始创建一组基础的脚本,如今它很快进化成了完整的工具,称为Bugfender[3]!
由于这最初是一个实验,我们决定使用一种新的趋势技术。对学习以及持续教育的热爱是MobileJazz的核心价值的之一,因此我们决定使用Go构建。这是一个由Google开发的相对较新的编程语言。它是编程世界的的新玩家,已经有许多受尊敬的开发者对它赞不绝口。
一年后,这个实验变成了一个初创项目,我们拥有了一个已经帮助了来自全世界的数以千计的开发者的令人难以置信的工具。我们的服务器每天处理来自万台设备的超过GB的数据。
在使用Go一年之后,我们想要分享我们将一个小小的实验变成处理百万日志的生产服务器的一些想法和经验。
Go生态系统
公司中没有人有使用Go的经验。Bugfender是我们第一次深入这个语言。
学习基本上相当直接的。我们之前在C/C++/Java/Objective-C/PHP的经验让我们学习Go相当快,并且在几天内就开始开发了。当然会有一些新的和不常见的东西需要学习,包括GOPATH还有如何处理包,但这在我们的预期之内。
几天之内,我们意识到即使是一个以简化为设计目的的语言,Go也是非常强大的。它能够做任何现代编程语言应该能做的事:能够处理JSON、服务器之间通讯甚至访问数据库也没问题(并且只需要几行代码)。
在构建一个服务器时,你应该首先决定是否使用任何第三方库或者框架。对于Bugfender,我们决定使用:
Martini
Martini[4]是一个强大的Go的web框架。我们开始这个实验时,它是一个很棒的解决方案,至今也是,我们还没遇到任何问题。然而如果我们今天再次开始这个实验的话,我们会选择一个不同的框架,因为Martini不在维护了。
我们还试验了Iris[5](我们目前的最爱)还有Gin[6]。Gin是Martini继任者,并且迁移到这上能让我们重用已有的代码。
在过去的一年中,我们意识到Go的标准库是非常强大的,你不必依靠一个臃肿的web框架来构建一个服务器。最好在特定任务上使用专门的高性能库。
Iris是我们目前最喜欢的,并且将来我们将使用它重写服务来替代Martini/Gin,但这目前并不是优先的。
修改:在讨论了Iris的各个方面之后,我们意识到Iris或许不是最好的选择。如果我们决定重写我们的web组件,我们或许会研究其他的选择,我们欢迎你的建议。
Gorm
有些人喜欢ORM,而有些人则不喜欢。我们决定使用ORM,更确切地说是GORM[7]。我们的实现只针对web前端,对于日志提取API仍然继续使用手工优化的SQL。在一开始,我们确实很喜欢它,但是随着时间的推移,我们开始发现问题,并且我们很快将它从代码中完全移除,并且使用sqlx[8]这个标准SQL库。
GORM的一个主要问题是Go的生态系统。作为一个新语言,自我们开始开发产品以来Go已经有很多新版本。在这些新版本中的一些改变并不向后兼容,因此要使用最新的库版本,我们要经常重写已有代码并检查我们为解决版本问题所做的hack。
上述这两个库是大多数web服务的主要组件,因此做一个好的选择很重要,因为将来更改会很困难,并且会影响你服务器的性能。
第三方服务
在创建一个实际使用的产品的另外一个重要方面是考虑库、第三方服务和工具的可用性。在这方面,Go还缺乏成熟度,大多数公司还没有提供Go库,因此你或许需要依赖其他人写的不能一直保证质量的库。
比如,对于使用Redis[9]和ElasticSearch[10]有很好的库,但是对于其他服务比如Mixpanel或者Stripe还没有好的。
我们建议在使用Go之前事先检查对于你需要的产品是否有好的库可用。
我们在Go的包管理系统上也遇到了很多问题。它处理版本的方式远没有达到最好,并且在过去的一年中,我们在不同的团队成员之间使用同一个库的不同版本上遇到了很多问题。然而,最近要归功于Go新支持的vendor包特性,除了gopkg.in[11]服务外,这个问题基本被解决了。
开发者工具
由于Go是一门相对新的语言,你或许发现相比其他成熟的语言像Java,它可用的开发工具并不很好。当我们开始Bugfender时,使用任何IDE都很困难,似乎没有IDE支持Go。但是在过去的一年中,随着IntelliJ[12]和VisualStudioCodeGo[13]插件的引入,这一切改善了很多。
最后看下其他的Go工具,调试器并不很好,而分析器甚至更糟,因此有时调试你的代码或者尝试优化它会很困难。
前往生产
这确实是Go最好的东西之一,如果你想要部署一些东西到生产环境中,你只需要构建你的二进制并发送到服务器中,没有依赖,不需要安装额外的软件,你只需要能在服务器中运行二进制文件就行。
如果你习惯于处理那些需要包管理器或者需要小心你使用的语言解释器的语言,用Go工作会感到很高兴。
我们对Go的稳定性也很满意,因为服务器似乎从没有崩溃过。我们在发送大量数据给GoRoutines时遇到过一个问题,但是我们几乎没见到任何崩溃。注意:如果你需要发送大量数据给GoRoutine,你需要小心堆溢出。
如果你对性能感兴趣,我们没法与其他语言相比较,因为我们从零开始使用Go,但是对于我们处理的数据量,我们感觉性能是非常好的,我们绝对不能如此轻松地使用PHP处理同等数量的请求。
总结
在过去的一年中,我们对Go的感觉起起伏伏。最初我们是兴奋的,但是在实验变成真实的产品后我们开始发现问题。我们几次考虑过用Java完全重写,但是目前为止,仍旧使用的是Go,并且过去的一年中,Go生态已经有了很大的提升,这简化了我们的工作。
如果你想要使用Go构建你的产品,你可以保证它可以工作,但是你确实需要小心一件事:可以雇佣的开发者。硅谷中只有很少的高级Go开发者,并且在其他地方寻找也是一件非常困难的任务。