谈一点对 go 和 erlang 两门语言的体会

jopen 11年前

项目原因用到过ejabberd,所以接触过erlang,但比较肤浅,无论是理解还是使用。go最近也被炒得比较火,号称要是一门取代c++和java 的语言。所以,也就顺便买了一本许式伟大牛的《go语言编程》,学习了一下。由于这两门语言,应用的比较多的领域都是网络编程方面,因此作为使用者,对这 两门语言写一点简单的小体会,做一下比较。

首先表明自己的一个观点,做为网络编程,还有构建大型分布式项目而言,如果在这两门语言之间做选择,我个人还是倾向于erlang,原因嘛,就目前go的版本和发展阶段来讲,包括go提供的各种包,都还无法达到otp的水准。后面会具体谈一下原因。

go给我印象比较深的几个特点:

1 对象的defer释放
2 channel的使用
3 提倡基于消息传递而非共享内存的并行编程
4 所谓的协程,当然这不是卖机票的那个携程

展开阐述一下,第一点,defer这种属于语法糖性质的小技巧,对于用惯了c或c++的程序员而言,确实是一个非常不错的体验,无论程序走什么路径,都不用担心资源的释放了,但这篇还是想从更粗一些的层面来谈,就不展开了。

第二点基于channel的读写,来控制多线程之间的同步(当然go中叫协程,叫什么不重要),确实很巧妙,其思想也是提倡使用消息传递而非使用共享内存 来进行并发编程,这一点和erlang的进程之间的消息传递思想是一致的,但感觉没有erlang用的巧妙,channel只是go中并发同步的一种,在 实际使用中,还是不可避免要用到锁,所以go还提供了语言包sync.而erlang在这方面而言,则做的比较完备,完全是基于进程间消息传递来避免同步 对锁的竞争。

关于协程的特点,go从几个方面进行了阐述,一种轻量级线程,系统开销小,被动式任务调度,不会主动抢时间片等等,其实,真正的实际应用中,令开发者最兴 奋的还是其可以无限制的创建上百万个,而不像操作系统层面的进程和线程那样,受制于系统资源,比如用c或c++来做并发编程,一般线程数最大也就开到几百 个,再多的话,受系统资源的限制会比较严重。在做性能测试时,我曾尝试着开过上千个线程,但调度效果,包括因为线程切换带来的系统开销非常不理想,除了性 能测试,其他场景不提倡这么干。关于协程的这个特点,我们很容易就会想到erlang中的进程,同样,erlang中的进程也可以开到上百万个,除了对 cpu的竞争方式,略有不同外,其实和协程差别不大,而且个人认为比协程用起来要更方便些。

判断一门语言的优劣,撇开语法不谈,人们最关心的还是其框架和库的强大与否,当然go最为一门新兴的语言,其完整的开发包已经达到了130几个,已经非常 强大,而且日后还会更加完善,这一点也是除了其简单优雅的语法之外,另一个令人兴奋的地方。但是使用下来,和erlang相比,和erlang的otp框 架,和在otp之上构建的各种开源工具比较而言,go在框架方面还是弱了一些。mnesia,rabbitmq等等应用都非常广,特别是 rabbbitmq已经在业界是公认的做的最完美的消息队列,可以说没有之一,只不过由于erlang相对来讲,还是小众了一些,影响了rabbitmq 的推广和使用。除此之外,erlang在分布式部署方面的优势是比较明显的,对常遇到的分布式部署的问题封装的比较好,节点之间的故障切换,代码热替换, 性能观察,degbug分析,erlang提供的工具相对更便利一些。当然还有其gen_server,gen_event,supervisor,有限 状态机等行为模式的提供,在快速构建分布式服务这方面,非常强大。

这么说,不是要说要黑哪种语言,而是个人在使用和实践过程中的一些小体会,同时个人也非常喜欢go。 相对于大家普遍吐槽的erlang函数式编程的语法,go的学习曲线还是比较平缓的,有过c,c++或java或python编程经验的,上手go会很快,语法都大同小异。而且对于构建大型系统而言,go确实有着相对于传统的c,c++及java更大的优势,毕竟可以随心所欲的创建协程,去干想干的活 儿,而不用考虑系统资源的限制,还是非常爽的。但是,我还是想保留我个人的如下观点,对于构建大型分布式系统而言,用erlang确实更方便些,这完全是 基于其强大otp框架而言的,开发者只要关心逻辑,实现逻辑即可,其他部署,容灾等方面,otp全部都干了,而且干的漂亮。当然go 也同样可以干的来,而且效率未必比erlang差,还可能更好,只是,需要开发者做的工作,和关心的事情,要更多一些。

来自:程序界