从Python 2迁移到Go:虽然代码量多,但太香了
我第一次写Goliath项目是在2019年12月,当时,可汗学院(Khan Academy)把我们的后端从Python 2整体迁移到了用Go编写的服务上,还有一些必要的改变来实现这个过程。同时,我也写了一些关于我们是如何逐步实现这种变化的。
Goliath项目介绍:https://blog.khanacademy.org/go-services-one-goliath-project/?fileGuid=eQ1DBjkIh1Ef1HpE
在我们开始Goliath项目时,团队中并没有人知道Go语言,只是通过实验来验证Go比其他选择更好。现在,我们所有的后端和全栈工程师都在编写Go代码,对Goliath的增量交付让我们跨过了重要的里程碑。目前,已有50多万行的Go代码投入生产。看来现在正是对Go自身进行反思的好时机。
我们的工程师喜爱Go语言
我咨询了工程师们对Go语言的一些开放式回答,得到的反馈是:“Go语言很容易读写”,“Go语言,我越用越喜欢!”
一位在.NET领域工作多年的工程师,重视异常风格的错误处理,这与Go的错误处理非常不同。如果你不熟悉这个主题,那么Go的错误是指从可能存在错误条件的函数中返回的值。我们以前的.NET工程师现在说,“能够调用一个没有返回错误的函数,并且确信它一定会成功,这是非常棒的。”
另一位工程师引用了Go的标准库文档。他喜欢“通过例如Go文档的io.Writer进行无网络浏览。满分的最佳文档,将会再次阅读”。
总的说来,Go的工具非常出色。编译速度很快,格式化也是标准工具链的一部分,可以帮助消除大多数关于格式化的讨论。尽管我在网上还看到一些关于Go模块的抱怨,但是它们比Go之前的软件包管理方法更好,而且从我们的经验来看,在这方面是非常好的。我们在为需要完成的事情寻找工具和库时也没有遇到任何麻烦,比如gqlgen。
我们想要泛型,否则Go有点冗长
多数情况下,不使用泛型来编写Go代码不会有问题。大部分时候,当我们编写内部库代码,甚至仅仅是处理slice时,我们都会感到它们并不存在。
缺少泛型是人们对Go的最大抱怨。Go团队花时间制作适合Go的泛型,我所调查的工程师们都对此表示赞赏,并对这项工作的进展感到兴奋。至少我们在使用Go的几年后才会发布它们。
当移植Python代码时,一位工程师注意到,Go中的某些语言结构需要更多的努力才能写出代码,但是Go相对较少的语言特性使得代码更加一致,读取速度更快。在系统的某一部分中,我们需要2.7倍的Go语言代码来处理与Python代码相同的特性,尽管其中一部分是由于某些函数调用被跨服务查询所替代。
另一位工程师希望能够更好地使用高阶函数,而所提出的slice包似乎就是对这些思路的很好补充。归根结底,我们希望能少写一些代码,而我们通过泛型所获得的选择将有助于实现这一目标。
性能和并发性
通过Python(Python 2,也不少),我们发现Go的性能非常出色。在最终实现与Go相似的功能时,我们将尽可能地从Python向Go进行复刻级的移植,而不是看起来像Python-in-Go的代码。除了真正的回归外,在这个过程中,我们并没有对性能工作确定优先级。
一位工程师指出,在Python版本中,某些大量的数据变化曾经每小时产生约100个谷歌云数据存储(Google Cloud Datastore)争用警告,而在Go版本中几乎没有发生这种情况,因为它在处理数据方面要快得多。我们有一个包含1000名学生的类的异常案例,在Python中可能需要28秒的时间来加载,但在Go中只需要4秒。
尽管我们是从大多数单线程Python中直接移植过来的,但是我们确实使用了Go的并发特性。一位工程师指出,虽然通道是Go最引人注目的特性之一,但是我们使用同步包的特性比通道更多。
编写50万行Go代码后的感想
总结一下:
Go通常比Python更冗长。
但我们很喜欢!它的速度很快,工具很可靠,并且在生产上运行良好。
我们的工程师有着不同的编程背景,因此对于Go和其他编程语言,我们的观点肯定是不一样的。这就是说,Go做的是我们在创建Goliath项目时“雇用”它所做的事情,我们感谢推动Go持续发展的团队以及围绕它建立的社区!
作者介绍:
Kevin Dangoor,可汗学院(Khan Academy)软件工程师。可汗学院是由孟加拉裔美国人萨尔曼・可汗创立的一家教育性非营利组织,主旨在于利用网络影片进行免费授课,现有关于数学、历史、金融、物理、化学、生物、天文学等科目的内容,教学影片超过2000段,机构的使命是让所有人享有免费的世界一流教育。
原文链接: