咱们为何从Python转到go?

说完了python,如今来讲说为何咱们选择go。其实除了Python,咱们也有其余的选择,Java、PHP、Lua(openresty),但最终咱们选择了go。java

虽然Java和PHP都是最好的编程语言(你们都这么争的),但我更倾向一门更简单的语言。而openresty,虽然性能强悍,但lua仍然是动态语言,也会碰到前面说的动态语言一些问题。最后,前金山许式伟用的go,前快盘架构师葱头也用的go,因此咱们很天然地选择了go。python

go并非完美,一堆值得咱们吐槽的地方。mysql

  • error,好吧,若是有语言洁癖的同窗可能真的受不了go的语法,尤为是约定的最后一个返回值是error。项目里面常常会充斥这样的代码:c++

      if _, err := w.Write(data1); err != nil {
          returun err
      }
      if _, err := w.Write(data2); err != nil {
          returun err
      }

    难怪有个梗是对于一个需求,java的程序员在写配置的时候,go程序员已经写了大部分代码,可是当java的程序员写完的时候,go程序员还在写err != nil程序员

    这方面,errors-are-values却是推荐了一个不错的解决方案。golang

  • 包管理。go的包管理太弱了,只有一个go get,也就是若是不当心更新了一个外部库,颇有可能就致使现有的代码编译不过了。虽然已经有不少开源方案,譬如godep以及如今才出来的gb等,但毕竟不是官方的。貌似google也是经过vendor机制来管理第三方库的。但愿go 1.5或者以后的版本能好好处理下这个问题。sql

  • GC。java的GC发展20年了,go才这么点时间,gc铁定不完善。因此咱们仍然不能为所欲为的写代码,否则在大请求量下面gc可能会卡顿整个服务。因此有时候,该用对象池,内存池的必定要用,虽然代码丑了点,但好歹性能上去了。编程

  • 泛型,虽然go有inteface,但泛型的缺失会让咱们在实现一个功能的时候写大量的重复代码,譬如int32和int64类型的sort,咱们得为分别写两套代码,好冗余。go 1.4以后有了go generate的支持,但这种的仍然须要本身根据go的AST库来手动写相关的parser,难度也挺大的。虽然也有不少开源的generate实现,但毕竟不是官方的。服务器

固然还有不少值得吐槽的地方,就不一一列举了,可是go仍旧有它的优点。架构

  • 静态语言,强类型。静态编译能帮咱们检查出来大量的错误,go的强类型甚至变态到不支持隐式的类型转换。虽然写代码感受很别扭,但减小了犯错的可能。

  • gofmt,应该这是我知道的第一个官方提供统一格式化代码工具的语言了。有了gofmt,你们的代码长一个样了,也就没有花括号到底放到结尾仍是新开一行这种蛋疼的代码风格讨论了。由于你们的代码风格同样,因此看go的代码很容易。

  • 天生的并行支持,由于goroutine以及channel,用go写分布式应用,写并发程序异常的容易。没有了蛋疼的callback致使的代码逻辑割裂,代码逻辑都是顺序的。

  • 性能,go的性能可能赶不上c,c++以及openresty,但真的也挺强悍的。在咱们的项目中,如今单机就部署了一个go的进程,就彻底可以胜任之前200个python进程干的事情,并且CPU和MEM占用更低。

  • 运维部署,直接编译成二进制,扔到服务器上面就成,比python须要安装一堆的环境那是简单的太多了。固然,若是有cgo,咱们也须要将对应的动态库给扔过去。

  • 开发效率,虽然go是静态语言,但我我的感受开发效率真的挺高,直觉上面跟python不相上下。对于我我的来讲,最好的例子就是我用go快速开发了很是多的开源组件,譬如ledisdb,go-mysql等,而这些最开始的版本都是在很短的时间里面完成的。对于咱们项目来讲,咱们也是用go在一个月就重构完成了第一个版本,并发布。

实际项目中一些Go Tips

到如今为止,咱们几乎全部的服务端项目都已经转向go,固然在使用的时候也遇到了一些问题,列出来算是经验分享吧。

  • godep,咱们使用godep进行第三方库管理,可是godep我碰到的最大的坑就是build tag问题,若是一个文件有build tag,godep颇有可能就会忽略这个文件。

  • IO deadline,若是能本身在应用层处理的都本身处理,go的deadline内部是timer来控制,但timer内部采用一个array来实现的heap,全局共用一个锁,若是大并发量,而且timer数量过多,timeout变更太频繁,很容易就引发性能问题。

  • GC,这个前面也说了,多用内存池,对象池,另外,我还发现,若是对象的生命周期跟goroutine一致,对性能的提高也不错,也在go的group问过相关问题,你们猜想多是由于一些对象实际上是在goroutine的8k栈上面分配的,因此一块儿回收没有额外GC了。

  • Go gob,若是要作RPC服务,gob并非一个很好的选择,首先就跟python的pickle不通用,而后为了作不一样系统的数据传入,任何包都必须带上类型的详细信息,size太大。go里面如今还没一套官方的RPC方案,gRPC貌似有上位的可能。

总结

虽然我如今选择了go,可是并不表示我之后不会尝试其余的语言。语言没有好坏,能帮我解决问题的就是好语言。但至少在很长的一段时间,我都会用go来进行开发。Let’ go!(转载自http://siddontang.com/2015/05/16/why-python-to-go/)

相关文章
相关标签/搜索