我们SoundCloud是一个使用多种编程语言的公司,虽然我们的技术架构最外层一直使用的是Ruby on Rails,但是在后端,各种各样的编程语言都有涉及。在这里我想多讲一下为什么要使用和如何使用Go这样一种开源的、刚刚发布其1.0版本的编程语言的。
在我们的公司里,所有的技术人员都是全能选手,而不是专才,这是根植于公司基因文化里的特征。我们希望每个人都能对公司的基础架构中每一部分都至少有相当的了解。更进一步,我们鼓励技术人员在个开发团队间调换,甚至组成新的团队,使成员跟各团队的冲突和摩擦尽量减少。在这样一种代码共产共有的环境中,非常需要一种表达性强,效率高的语言来降低实施的困难,Go语言证明了它是一种非常适合的语言。
我们已经有好几个程序员都把Go语言描述为是一种所见即所得(WYSIWYG)的编程语言。这是说,代码要做的事和它在字面上表达的意思是完全一致的。这种特征对于使软件无歧义和可维护有着巨大的帮助。Go语言明确的拒绝“helper”习惯用法以及诸如统一访问原则(Uniform Access Principle)、操作符重载、缺省参数、甚至异常等特征,基本上,这些特征相较于能产生更丰富的表达,它们的歧义性会带来更大的问题。不否认,这样的策略会带来更多的键盘敲击——尤其是,正如大多数参与Go语言项目的新手程序员痛斥的,在异常处理时最麻烦——但是,换来的报答是,还是这些新手程序员,他们能轻易的、迅速的将应用在脑海里形成一个完整的模型。我可以很有信心的告诉大家,从项目开始到提交代码,Go是我们使用过的效率***的语言。
Go语言严格的结构原则和它的“一种事情有且只有一种方法完成”的思想意味着我们无需在风格问题上纠缠不休。在针对Go语言程序的代码审查上,审查会变得更针对问题,而不是针对语言上的错综复杂,这是每个人都愿意看到的。
更值得一提的是,一旦一个程序员对Effective Go有了一个基本掌握,你会发现他们的关注点能非常自然的从“应用目前应该怎样运行”过度到“应用在理想状况下应该如何的运行”。是否是后台的响应缓慢致使整个请求失败?是否应该只重试一次,不成功就只提供部分的结果?浏览器表现异常,我们是否要设置一个250毫秒的超时限制?系统中任何一个外层的行为场景都能用一种直接的、理想化的实现来表示,不需要类库或框架的支持。去掉抽象层降低了复杂性;直白陈述式、简单的代码是更好的代码。
Go语言还有其它一些非常好的特征,让我们受益不少。静态类型和快速编译使我们能够在开发过程中做几乎实时的静态检查和单元测试。这也意味我们开发的基于Go语言的系统中的编译,测试和发布几乎是一起完成的。
事实上,快速的编译,快速的测试,快速的相互审查和快速的部署意味着你的一些想法能在一个小时内从白板上的设计变成产品中可运行的程序。例如,Next软件中的搜索基本功能是由Elastic Search驱动的,但是它接受SoundCloud的管理和交换几乎全部是Go服务来完成。在验证过程中,我们认识的,我们需要一种能在某个特殊环境中把索引标志为只读状态的方法,需要索引系统能知道并顺从这种状态。在代码中加入抽象层,开发一个新的入口点正确的检测这种状态,修改跟索引相关的行为,为它们写测试代码,这一切只用了半个下午的时间。晚上时,这些修改已经部署并运行了好几个小时了。这样的速度,尤其是对一种静态类型的,本地编译的语言,简直没得说了。
我说到了我们的编译和部署系统。它叫Bazooka,它被设计成一个平台,用来管理内部服务的部署。(我们很快就会把它开源;关注我们,不要走开!)我们曾通过一个情况复杂的网络环境升级12-Factor应用,你可以把它当成一个巨大的、复杂的状态机,随时都有可能造成数据污染和相互竞争的状态。对于这种工作,Go语言是最自然的选择。Go语言很独特,它有天生的并行安全特征。Bazooka系统的开发人员能够分析出问题的复杂性而不需要使用那些复杂的辅助工具。Bazooka利用Doozer来协调它的共享状态,Doozer是世界上唯一一个Paxos开源实现软件(就我们所知)——它也是用Go语言开发的。
总之,我们在SoundCloud公司维护着都是用Go语言写成的十几种服务和十几种知识库。当有新的后台项目时,我慢慢的都会选择使用Go语言来完成。
你对使用Go语言解决真正问题和开发真正产品感兴趣吗?我们很乐意听到你的声音!
英文原文:Go at SoundCloud