百科问答小站 logo
百科问答小站 font logo



为啥 Erlang 没有像 Go、Scala 语言那样崛起? 第1页

  

user avatar   yuhengk 网友的相关建议: 
      

Worse is Better (

dreamsongs.com/RiseOfWo

) 能比较好地解释题主的「为什么」。注意这篇文章的写作背景,这是一位 LISP 大佬在九十年代初反思为什么 LISP 这么牛的语言日渐式微,C 和 UNIX 这么烂的东西却起来了。概括下来大概是这样的:

软件设计有以下四大目标:简单、正确、一致、完整,但两大流派 MIT Style (MIT AI Lab 是 LISP 重镇) 和 New Jersey Style (C 和 UNIX 的老家贝尔实验室所在地) 对这些目标的优先级排序不同。MIT Style 认为软件正确性要绝对保证,然后优先级 正确 ~= 一致 > 完整 > 简单,简单这一条还得分,为了接口简单,可以忍受实现复杂。而 New Jersey Style 是正好反过来:首先软件实现得简单,做不到宁愿让接口复杂点,为了简单显然可以牺牲完整性,而正确、一致,那就尽力吧…… 反正得简单。Worse is Better 前面的 Worse 指的就是像 UNIX 这样为简单甚至能放弃「正确」这种有绝对标准的好的东西,后面的 Better, 指的是更好的生存适应性,这里面不带价值判断,文章作者也为 "Worse Is Better Is Worse" or "Worse is Better is Still Better" 一直在纠结,但这是一个能解释很多现象的准确观察。

没错,Erlang 就是 MIT Style, do the right thing 那个。它跟 LISP 一样产生深远的影响,会被无数后世语言技术借鉴 —— 即使不用 Erlang 开发我还是会对每个新人都会高度推荐 Erlang paper (

erlang.org/download/arm

) —— 可是能火起来的,还会是那帮新泽西佬做出来的敢连 generics 都没有的烂货。

一个东西火起来的关键在于传播。文章把 C 和 UNIX 比作病毒:它实现(而不是接口)很简单,所以能很容易移植(感染)到别的平台,迅速跟原有平台的东西整合,因为它东西少,不拘泥于「正确」、「本质」之类的东西,能根据平台和需求快速演化,也能不断吸(chao)收(xi) 别人的东西让自己变得更强大。

但是 Erlang 不行,阻碍 Erlang 传播的除了爱立信作死,还有它自己的特性。A History of Erlang 里数次提到,Erlang 很难移植到别的语言/运行平台,因为 Erlang 的运行模型太特别了(真可惜只有Erlang是对的),所以一切都只能自己搞,同样原因要调用宿主平台的原有模块也很困难。Erlang 有一个简单、正确、不妥协的接口,但是底层实现就不得不非常复杂精巧,当底层实现的优化都不能满足你的特定需求时,你很难绕过统一美好的模型做case by case, quick and dirty的优化。某个算法 Erlang 跑太慢了你要引入 C 模块,难(望向 PHP & Python),复制消息传递通常不是瓶颈但如果变成瓶颈能传指针么?NO, YOU'RE DOING IT WRONG! 当然实际上 Erlang 内部对这个是有优化的,大的 binary 会自动变一个引用计数 buffer 放共享堆然后就只用传引用啦,但是这马上导致一个问题,因为 Erlang 没有(不需要有)全局 GC, 如果有进程已经不引用这个 binary, 但因为各种原因触发 GC 迟了,共享 heap 里引用计数一直不清零这段 binary 就僵在那流量冲击大你就等OOM吧,这是实际线上系统会碰到的问题,Binary是不是refc又不是你说了算,所以还是时不时自己强行 GC 一下…… 这其实就是一个接口简单导致实现复杂优化困难并且难以做对结果还是要用户自己动手的例子。Go 的 STW GC 虽然简陋,但它不限模型,鼓励复制但不禁止传指针,对这种少数的 case 很容易解决,再拿个 pool 来对付一下蠢萌的 GC 就可以了。模型不纯粹,实现极简陋,但解决问题。

Worse is Better 也能解释别的语言或技术的崛起。你不用很优秀但要有一个点做得好打到痛点,你不用设计完美但至少别犯大错,然后保持简单,保证好上手易移植易与现有系统整合,就可以了。包括 PHP(别打我),它架构上首先基于 CGI: 每个请求一个独立进程,share nothing,只用管道跟 httpd 通信,这天然保证错误隔离,也让 CGI 应用完全不需要管网络交互问题,短连接模型处理完请求就进程结束所以 PHP 甚至不需要 GC, memory pool 就行,更重要的是它也天然支持了热替换。你可以说这些全部是 Erlang 的设计点,也完全符合 Erlang paper 提倡的把困难问题(HTTP server)做成框架让业务写得简单轻松的思路,同时这也是传统的 UNIX 编程方式 —— 这就是所谓设计上别犯大错。然后再做一个亮点:直接 HTML 代码里嵌入脚本,现在你觉得这很傻,但当时互联网刚起来,HTML 还是新鲜事物,更没有什么 AJAX, 不用你自己组装字符串直接把代码嵌到 HTML 里太打动人心了。是,这没什么难的,但别人没有,PHP 有。至于一台机撑多少连接?速度怎么样?当时有个人访问你网页你都兴奋半天了,谁跟你研究这种吃撑了怎么办的问题?

如果 Worse is Better 作为一个定律是正确的,这听起来很可悲,我们就活该没有好东西用了。我感觉可以稍微修正一下:对于开发技术这种存在网络效应的东西,除非一个方案有革命性的优势,否则都会服从 worse is better 定律。

在电信行业,Erlang 可能真的拥有革命性的优势,我不熟悉的领域不评论,可惜电信行业本身相对狭窄封闭再加上爱立信作死,没网络效应可言。而在其他地方,革命性的优势,它没有。

开发效率方面,

@bhuztez

提到的好 8 倍,我记忆中来自 A History of Erlang 描述一个早期项目,对比对象是一个没什么公开信息的内部语言 PLEX,而且 Joe 说了原始文件从未公开,且当时内部争议就很大;Erlang 标志性项目 AXD 301 的报告结论 (

erlang.se/publications/

) 是 4 倍,对比对象是 C/C++,方法是对比代码长度(所有动态脚本语言都能赢好吗)和bug密度(相同),更重要的是,它并没有分析 Erlang 的语言特性在开发效率提高中的必然作用,甚至没有代码对比样例(报告里倒是有一堆组织架构管理方法内容),也没说明有 C++ 使用什么能跟 OTP 对应的框架,这种论据拿到知乎上是会被喷死的。

运行时方面,Erlang 的高并发只能说它是生不逢时。90年代,除了电信领域,这种高并发需求实在没有,要真有,QQ算?人家用 UDP 木有连接保持问题。当时的硬件情况,机械硬盘、网络带宽、CPU 内存逐个撑死了都还没轮到并发。Telnet-based BBS 是 TCP 长链接模型,用最基本的 UNIX fork 进程模型(操作系统级进程隔离,要不是这样那十几二十万行sh*t还真跑不起来),中山大学逸仙时空用一台 98 年的 HP Alpha(以前的DEC)机器 2G 内存好像?能撑 3000 在线,水木PTT等大站有好硬盘好CPU 4G乃至8G内存20000在线不在话下,注意是在线,发呆会被踢的,所以这些连接的活动率很高(作为对比 AXD 301 用的是 Sparc Ultra 2 跑 Solaris 活跃进程有200-4000)。系统的瓶颈一是硬盘二是内存,远远没轮到模型问题。到编程模型真有问题的时候,Worse is Better 已经发挥作用,各种现有开发平台借鉴 Erlang 模型可以搞出很好的东西 —— 为什么是借鉴而不是直接用 Erlang? 答案 Joe 自己已经说了,他在 erlang paper 里鼓励separate of concern, 框架模型这么复杂的东西应该由专业人士一次过搞定,模型之上的应用就很轻松而且根本不用关注并发问题;在 A History of Erlang 中,他提到一个想法,Erlang 是一个运行平台,进程里跑的是什么语言并没有太大关系。那也就是说,虽然用别的语言山寨一个并发运行环境很难(而且很难做对),但是这只是一个一次性的工作而且可以根据业务特性定制,框架完成后,你还是可以用熟悉的语言写业务,完全不用管并发问题,但同样能达到好很多的并行度(所谓Actor / Reactor模型blah blah blah, 或者像MapReduce这种特定框架),而且只需要对少数关键模块动手而不是全局替换,性价比高很多吧。

分布式支持的故事也一样,Erlang 从原理上天然支持分布式,也很早就有了内置分布式支持。然而,这个支持所基于的假设也一样老:几个到十几个节点,均质且可靠全互联的网络,单一的全 Erlang 系统。Joe 怎么也不会想到有人要用几万台破 PC 做集群还妄想跨洲跨机房热备。到我们真的需要分布处理能力的时候,你会发现实现的设计假设限制了它的扩展性(

release-project.softlab.ntua.gr

),CAP 的基本限制在,不可能有一致、透明的分布式通信和状态管理方案(

[erlang-questions] State Management Problem

这个 thread 可以看到最后 Robert Virding 的总结陈词),你还得去连不按 Erlang 规则来的别的服务,你也没法把 mnesia 扩展到 GFS 的规模,因为它根本不是为这个设计的,Erlang 的这些先发优势没有变成劣势已经很不错了。现在回去看 GFS 和 MapReduce 的论文,你会觉得他们简陋得可笑,里面大篇幅的 fault tolerence 的东西,都是 Erlang 设计原则的特化和简化,可是至少在那时,Erlang 没有发挥它的威力,而 New Jersey guys 蛮干硬上把东西做出来了。你甚至可以认为整个 Google 集群管理系统 Borg 就是一个大号 Erlang 平台,一堆 supervisor 在管着一堆 share nothing RPC 消息通信随时会挂的服务(流行用语叫 micro service),绝大部分服务无状态可以随时挂,Goolge C++ 不允许抛异常但是规定你如果发现完全没预料到的东西你应该直接打log crash掉等重启处理,自动均衡部署容灾一应俱全,几乎无限扩展,处处闪耀着 Erlang 的思想光芒,但它们都是用 C++ 写的。开源版 Kubernets 就是 Go 了,Go 没有内置分布式支持,因为整个体系在,它自己已经不需要了。

这完全就是 Worse is Better 的原文:“The good news is that in 1995 we will have a good operating system and programming language; the bad news is that they will be Unix and C++.”

Google Trends, 全球数据,erlang vs. golang



最后还是多嘴一句,这不是说我们就不应该用 Erlang. Paul Graham 在

Beating the Averages

里提到,Common Lisp 是他当年创业的秘密武器,让他们获得了比用 C++ 或 Java 的竞争对手高的多的开发效率。没人用又怎样?你就是要用普通人不用的东西才能战胜普通人。同样的,如果你相信 Erlang 是你能打败庸众的秘密武器,Go for it (pun NOT intended).


user avatar   CMGS 网友的相关建议: 
      

erlang 如果是自由精英主义的话,go 就是新生代的实用主义……

erlang 不是不屌,是无论从招人还是项目维护上成本太高了,10个应聘的6个PHP3个JAVA1个其他,这个其他估计只有10%不到的几率是个会 erlang 的,注意我说的是会,不是熟练or精通,面个试连 Actor 模型都说不清楚的那种,你是老板你不心疼钱?加上没有「一定无法替代」的理由,成为冷门语言就正常咯。

go 呢,首先他有个爹,然后他有个爹,最后他有个爹,没了,就这样粗暴。gc 怎么了,stw 怎么了,又不是人人做端游,又不是人人做高频交易,连不是人人都用的模板都被干走了 go 爹真心不会在意这些小问题的。

go 最大的优势就是没特点,没所谓的「magic」,这对于工程来说简直是完美。甚至 gmt 都让工程师争大括号要不要新开一行的争论都省了,没模板编译时中规中矩各种没性格,直接拉低的是什么,是人力成本啊。想想看一门语言,能 cover 90%以上的用况,还一次编译到处可以跑,没依赖,没内存泄露,有并发模型,新人接手分分钟,最重要的是它爹还特牛逼,怎么可能不火。


user avatar   bhuztez 网友的相关建议: 
      

这个4年前的问题选择在这个时间点突然出现在我今天的时间线上显得非常 亦可赛艇

Android是2008年初才发布,而Oracle在2009年就以7.4B$收购了Sun,是Google不够睿智吗?

非也!

1)如果Android没有如此成功,Java对于Google而言就是一坨shit,Google从来没有想到自己会站在一坨翔上面取得空前的成功,如果有算命的告诉Google的命中贵人是阿翔,它就是穿越回去吃也要把它吃下去,可惜历史不能假设!


2)Google一直有python基因,很多系统都是基于python的,你知道工程师主导文化的可怕性吗?这帮pythonic的nerd出于情怀或者节操或者叫清高或者叫偏执或者叫真爱,它说什么都不会去买Java的,“老子看不上”!谁知造化弄人,09年你对我爱答不理,18年老子叫你高攀不起88亿!(注:今天的Google在各种收购之后,Java服务的比重占的也非常大了,变成了一个杂合的技术栈,而官司也很可能打到高院,尚未定论)


3)Google一直有跟开源保持共存共荣共襄盛举的传统,它跟Mozilla做生意,赞助开源项目,捐赠Wiki,主张“不作恶”,简直就是一副乌托邦理想主义者的化身,圈粉无数(包含答主),像Java这种项目,它更可能的方式是烧一笔钱给它花,然后来几句“希望Java明天会更好”之类的废话,它根本就不曾想过有一个家伙抄底了,因为那时候Android根本就没有火,Google从来就没有想过Java也T-M-D算哪门子“底”?


4)Sun的主手人也是个技术型的,就是技术牛掰业务做的稀烂,当时怎么看Sun都处在夕阳,SPARC也是逼格满满业务下滑被Intel捣的稀烂,那个价格没有几家觉得划算的,幸好是Oracle这种剑走偏锋的收购了它,要是换一家公司收购多半就把Sun雪藏甚至捣腾碎了,Java也就没有今日风光了,而Google在坊间也有创业公司杀手的美称,也许这就已经是历史发展的最好结果了。


什么,你问我对于Oracle收购Sun和MySQL怎么看?

还能怎么看?好白菜都让猪给拱呢呗!

但是作为吃瓜群众,我最喜欢看大佬们掐架,Google与Oracle的这场官司绝对酸爽,大家保持关注,各家都有千百号律师,吵起架来想想都 亦可赛艇!学知识产权法/专利法/法理学的同学们千万不要错过,说不定两年后就能进教材作案例呢!


什么,你又问我Google应该怎么做?

靠,我有不是劈柴!按我的观点,Google这次是违反了Java的使用协议的(无意引战,定论的事情留给专业法官),不能因为体量大就以为能压死人,那可是在美帝,万事全靠律师一张嘴,怎么讲都有理!


大家还记得微软以前有个skydrive吗?在英国被判败诉了,最后也得改名叫OneDrive呢!Google有钱了不起啊,过来领罚单!


而Java的坑早早就埋在那里了,所以苹果直接一刀切:老子不支持,免得搞一嘴毛!Flash一身毛病,一刀切,老子不支持!


所以,我对Google的建议是:

从Android 10开始,一刀切:老纸永生永世不再支持Java!

名字我都起好了: Badroid!


这TM不是关乎技术,不是关乎信仰,不是关乎生态,不是关乎用户体验!

这TM关系到命!


什么?要我预测结果?

法官中间调停,你们俩和解,google把赚的钱按每部手机给Oracle付钱?什么你说太扯了?你每买一部Android,都要给微软钱,你造吗?Oracle就想躺着就把钱收了!




  

相关话题

  如何看待GO语言的新GC(TOC)? 
  Go1.6中的gc pause已经完全超越JVM了吗? 
  关于go语言协程调度的一个问题(具体请看问题描述)? 
  编程语言中类型前置和类型后置的优缺点各是什么? 
  Node.js、Scala、Clojure 等声称适合高并发的语言,分别具体适用于什么情景,何种任务? 
  怎样用简单的语言解释 monad? 
  golang,告警业务,每个告警源都有不同的分发频率,告警源可能新增or删除,该如何设计? 
  第三届 Gopher China 大会值得参加吗? 
  Python 在大部分领域都能胜任,为什么很多企业转向了 Golang? 
  go mutex阻塞线程吗,如果不阻塞,为什么呢? 

前一个讨论
谁能最简单的详解椭圆曲线算法,secp256k1 是如何生成公钥和私钥的?
下一个讨论
上coursera坚持不下去怎么办?





© 2024-11-27 - tinynew.org. All Rights Reserved.
© 2024-11-27 - tinynew.org. 保留所有权利