2007年9月起步:一门语言与一个人的十年交集
关于打造一门崭新编程语言的讨论,最早可以追溯到2007年9月20日——那正是Go语言的前身。许式伟回忆,自己与Go的缘分同样起于2007年,恰好是Go成长的十年,也是他个人成长的十年。截至当时,Go已迭代到1.9版本,期间两度拿下TIOBE年度语言奖(2009年与2016年)。Docker等早期创业公司靠Go起家,如今的云计算巨头也由此催生出Kubernetes等关键项目。Google Trends数据表明,中国地区Go的热度异常突出,令Go语言之父本人也感到意外。
从WPS到分布式存储:许式伟的第一次技术选型
2007年2月,许式伟创建金山实验室,方向锁定分布式存储。对他而言,这是职业生涯的关键转折:此前七年他都在WPS Office办公套件研发一线,转型后既要完成从软件架构师到业务产品经理的角色切换,又要从单机桌面软件跨入分布式后端服务器领域。
摆在面前的第一道门槛是选什么语言开发。团队几乎没有犹豫就定了Java,理由很务实——对刚涉足后端的新团队来说便于上手。不过,程序员杂志上一篇署名TrustNo1的《一场茶杯里的风暴》让他第一次接触到Erlang,Erlang背后的编程思想令他深受触动。他判断这套思路会极大地释放服务端编程生产力。为了推动服务端最佳实践的探索,也让更多人研究Erlang,他发起成立了ECUG社区。该社区坚持十年,每逢年底举办ECUG Con大会,邀请各界技术专家分享服务端开发实践心得。
虽然主力仍是Java,团队随后也做了小范围Erlang开发的试探。2008年他们上马一个业余项目,用Erlang撰写存储系统的极简版本。这次试水让许式伟形成进一步判断:Erlang的思想值得借鉴,但语言本身并不适合承载大型工程项目。

CERL项目的两次版本迭代:死锁与锁的抉择
2009年3月,许式伟加入盛大创新院并重启分布式存储项目,迎来第二次技术选型。他走了最难的一条路:用C++开发。做出这一决定的核心动机,是希望打造一个「新轮子」——既保留Erlang编程思想的优势,又能绕开其语言层面的短板。若真能做成,将是服务端开发者的普遍福音。于是CERL项目诞生了。在存储第一版开发期间,团队在CERL库上投入的时间、代码量与精力,都远超存储本身。
CERL经历两个大版本。CERL 1.0全面沿用Erlang的编程思路,主要范式包括:可以启动任意数量的进程(进程为抽象概念,实现上是纤程或协程),数量上限仅由内存大小决定;每个进程独享邮箱,消息通过邮箱互发;消息分同步与异步两类,同步消息会阻塞等待对端返回;网络服务器采用单进程(即单线程)模型,一次仅处理一条消息。
但在真实场景中,基于CERL 1.0的模型暴露出若干问题。其一,当网络服务器A、B互相发送同步消息时会产生「死锁」,因为双方可能正忙于处理消息而无法及时应答,最终表现为超时;而超时比死锁更棘手,是服务器性能的杀手。其二,应对办法是把同步消息改成异步,但这会显著拉升编程复杂度,程序语义晦涩,实质上退回了传统异步编程模型,丢掉了Erlang模型的最大优势。其三,「无锁」假设代价太高:当网络服务器单次处理响应耗时较长(存储服务必然如此)时,自然期望起独立进程响应单个请求;而各处理进程间需要共享服务器状态,这就离不开锁——除非服务器无状态,但存储服务器恰恰必然有状态。团队只能在牺牲性能串行处理与引入锁之间二选一,「没有锁」远没有想象中美好。
发现死锁问题后,团队立即反思整个编程模型,决定重建,CERL 2.0的要点由此确立:进程之间只保留同步消息,如需异步效果,就启动一个新进程发送同步消息;网络服务器改为多进程模型,每个请求由独立进程处理。两个版本的关键分歧落在拒绝锁还是拒绝异步消息上:CERL 1.0(即Erlang编程模型)拒绝锁,CERL 2.0则拒绝异步消息。基于CERL 2.0,团队完成了分布式存储的第二版和第三版。事实证明,彻底去掉异步消息概念后,这一版服务器编程模型的心智负担大幅下降。
Go发布后的意外对照与CERL的放弃
Go语言问世后,团队发现一个惊人的巧合:在服务器编程模型这一层面,CERL 2.0与Go几乎完全一致,连细节决策都如出一辙。一次聚餐聊起此事,道哥(李道兵)提议赶紧把CERL开源,否则等Go流行就没机会了。许式伟确实就此与创新院院长陈大年沟通过开源一事,对方答复「没问题,你发个邮件申请吧,留个凭证」,但那封邮件他始终没有发出。原因是他花一周时间用Go写了些代码后已有结论:不打算再让CERL面世,因为已有人把CERL的目标实现了,且远超出预期。

2011年创办七牛云:第三次选型坚决押注Go
2011年6月,许式伟离开盛大创新院创办七牛云,面临第三次技术选型,这一次他果断选了Go,还专门给团队写了一封邮件。邮件里有这样一段话:
在创业过程中我们会面临很多选择,也会有很多选择后来会被证明是错的,但是今天我可以确定的是,选择 Go 将会成为我们最正确的选择。
彼时Go仍属小众,团队因此有意识地培育Go中国社区。为让更多人认识并加入Go阵营,他们启动了《Go语言编程》一书的编写,最终与Go 1.0版本同步面世。2012年2月,许式伟首次在公开场合预言:Go会超过C、Java,成为最流行的语言。那一年他四处宣讲,做了不下十场Go讲座,平均每月一场,其中讲得最多的PPT是《Go,Next C》,基本浓缩了他对Go革命性所在的判断。对一家初创公司而言,为一项与自身业务无直接关联的技术投入如此多宣传精力,旁人可能难以理解,背后有三个理由:Go确实是一门革命性语言,其流行对产业发展意义重大;Go仍小众,公司不仅要招Go程序员,更要说服他们相信Go是有远大前景的专业方向;七牛的用户就是程序员,需要在用户心中树立专家形象。
从云存储到大数据:一场倾向性为零的选型辩论
七牛云起步的第一个业务是云存储,整套存储系统完全用Go实现,是全球首个用Go编写的云存储,也是首个用Go编写的云服务。到2014年决定进入大数据领域时,选型问题再度浮现。从生态看,选Java或某种JVM平台语言(如Scala)优势明显——尤其大数据业务负责人陈超本身就是Scala狂热粉丝(网络id为CrazyJVM),选JVM平台似乎顺理成章。纠结的焦点在于:团队判断未来Go会占领整个基础设施领域,而大数据是其中极具关键意义的一块,所以是面向现在选型还是面向未来选型,成了一道难题。
许式伟透露一个细节:陈超刚加入时,他对陈超说「不管未来你会用什么语言,但是进入七牛必须要会写Go。」陈超因此被迫写了一个月Go代码。一个月后问他感受,他回答「能够理解为什么你推荐Go了,写了Go代码后不想回去写Scala代码。」不久后陈超启动Pandora大数据平台项目,正面碰上选型难题,深思熟虑后决定用Go来做Pandora——这个决策对许式伟来说是意料之外,因为他本人并无倾向性,本以为陈超很可能优先选Scala。国庆节前的一次聊天中,陈超回顾这段经历,把自己选择Go的原因概括为:极低的学习成本,极低的心智负担。若用Scala,新人入职要培训,还要担心写出糟糕的Scala代码;而用Go新人可以直接上岗,几轮Code Review后基本就能写出质量不错的Go代码。

十年之后的现状与下个十年的技术判断
十年过去,Go早已不再小众。使用者和爱好者都在增多。许式伟记不清具体哪一天,但通过Google Trends搜索golang时发现中国是全球Go热度最高的地区,那一刻他非常开心。
展望下一个十年,他认为期望Go语言特性大幅迭代的人可能会失望,因为Go不会发生太大变化。对远期需求变化的预测和把控能力,正是Go的最大魅力之一。能做到这一点的语言可与之类比的是C——C语言不同版本间的规范差异极少,但因为Go需要解决的问题更多,达成这一点的难度实际上更高。未来十年Go仍将深耕服务端开发生态,同时积极探索其他潜在应用市场。
在QCon 2015上海站上,许式伟曾以《Go语言发展状况》做过主题分享,并就Go提出三个预测。第一个预测最早见于他2012年的新浪微博:Go语言10年内一定会超过C和Java,变成排行榜第一的语言。他承认此事今天说出来仍然会被绝大部分人觉得太早,毕竟Go还没排进前五。第二个预测是Go将在两年内制霸云计算领域。第三个预测是Go将统治下一个10年,该观点来自Deferpanic创始人Lan Eyberg。
报道还提到,Google、Uber、Paypal、LinkedIn、Airbnb等顶尖技术专家会前来分享前沿实践经验,QCon上海2017大会报名进入最后一周。购票可联系购票经理Hanna,电话:15110019061,微信:qcon-0410。
小结:许式伟与Go的交集贯穿三次技术选型——2009年CERL 2.0与Go在服务器编程模型上的意外一致,直接导致他放弃开源CERL;2011年创办七牛云后果断押注Go并用其重写云存储;2014年他又说服原本偏爱Scala的陈超用Go做起Pandora。他判断Go未来十年不会大改且将继续深耕服务端、并重申10年内Go将超越C与Java的预测。
