许式伟:我与Go语言的这十年[转]

简介: 2017-12-18 许式伟 Go中国 2007 年 9 月 20 日,关于设计一门全新语言的讨论正式开始,这门全新的语言,就是后来的 Go。时至今日,Go 语言已经发布到 1.9 版本,走过了整整十年的历程。

2017-12-18 许式伟 Go中国

2007 年 9 月 20 日,关于设计一门全新语言的讨论正式开始,这门全新的语言,就是后来的 Go。时至今日,Go 语言已经发布到 1.9 版本,走过了整整十年的历程。在这十年间,Go 语言两夺 TIOBE 年度语言大奖(2009/2016),许多初创公司在早期使用 Go 进行开发,包括现在的云计算巨头 Docker,也由此催生出了 Kubernetes 这样的项目。在大洋彼岸的中国,Google Trends 显示 Go 的异常火爆更让 Go 语言之父感到震惊。而这一切,跟一位名叫许式伟的技术人密不可分。

Go 语言刚刚度过了它的十周年纪念日。而要说我与 Go 的缘分,也同样始于十年前(2007 年)。这十年,是 Go 成长的十年,同样也是我成长的十年。

2007 年 2 月,我建立了金山实验室,主攻分布式存储方向。这是我职业生涯至关重要的一个转折点。此前我已经做了 7 年的 WPS Office 办公套件的研发。这对我有两个重要的挑战:一个是角色转换上的,从做软件研发的架构师到做业务的产品经理;一个是技术领域变化上的,从单机的桌面软件开发到分布式的后端服务器开发。

我第一个面临的问题是技术选型。几乎没有作任何纠结,我们选择了 Java 作为主体的开发语言。作为初入后端开发领域的团队来说,这只是一个从务实角度出发的选择。但 TrustNo1 在程序员杂志发表的《一场茶杯里的风暴》一文让我认识了 Erlang 语言,并深深被 Erlang 的编程思想所打动。我意识到这种编程思想将会极大释放服务端编程的生产力。为了推动服务端最佳实践的探索,也为了进一步推动更多人了解和研究 Erlang,我发起了 ECUG 社区。ECUG 到现在已经十年。这十年我们风雨无阻,每年年底都会举行一场 ECUG Con 大会,和来自各行各业的技术大拿们齐聚一堂,大家一起分享这一年来服务端开发的实践心得。

尽管我们选择了 Java,但是随后我们也做了小范围使用 Erlang 进行开发的尝试。在 2008 年我们启动了一个用 Erlang 来编写存储系统(极简版)的业余项目。这次的尝试让我对 Erlang 有了进一步的判断:尽管 Erlang 的编程思想很好,但是 Erlang 语言本身并不适合大型的工程项目。

到了 2009 年 3 月,也就是我加入盛大创新院重启分布式存储项目时,我面临了第二次技术选型。这一次我选了最难的一条路:用 C++ 来开发。这是一条艰苦的路。促使我做出这一选择的最大原因是,我很希望能够制造一个新轮子,它应该既有 Erlang 编程思想的优势,又可以克服 Erlang 语言的劣势。如果这事能够干成,它将是一件伟大的创举,所有的服务端开发人员都将受益于此。于是,在心怀满腔热血之下,一个名为 CERL 的项目诞生了。在我们存储的第一个版本期间,实际上我们花费在 CERL 库的时间远超过了做存储本身,无论从代码量还是花费的精力来说都是如此。

CERL 项目经历了 2 个大的版本。CERL 1.0 完全遵循 Erlang 的编程思想,主要编程范式如下:

  • 可以启动任意多的进程(这里进程是抽象的概念,实现上是纤程 / 协程),进程数上限只受限于内存大小。

  • 每个进程有进程邮箱,相互发消息通过进程邮箱。

  • 消息分同步消息和异步消息,同步消息会阻塞等待对方返回消息。

  • 网络服务器是单进程模型(就是大家理解的单线程模型),一次只处理一个消息。

  • 没有锁。

基于 CERL 1.0 的编程模型,我们实践中发现了这样一些问题:

  • 在网络服务器 A、B 相互给对方发送同步消息时会发生“死锁”。因为双方可能都正在处理消息中而无法及时响应,这种“死锁”最终表现为超时(但是实际上超时更可怕,是服务器性能的杀手)。

  • 解决“死锁”的方法是把同步消息改为异步,但是这对编程复杂性带来很大的影响,程序语义变得晦涩。本质上,这是回到了传统的异步编程模型,放弃了 Erlang 编程模型最大的优势。

  • “没有锁”的假设代价过高:在网络服务器的单个处理响应时间较长(存储服务必然如此)时,必然希望启动独立的进程来响应单个请求。但是各个处理请求的进程之间需要共享网络服务器的状态,这就意味着需要有锁(除非网络服务器是无状态的,但是很不幸存储服务器必然是带状态的)。要么放弃性能串行化地处理请求,要么有锁 —“没有锁”,想说爱你不容易。

在发现“死锁”问题后,我们立刻对我们整个编程模型进行了反思,决定重构整个编程模型,修改后的 CERL2.0 要点如下:

  • 可以启动任意多的进程(这里进程是抽象的概念,实现上是纤程 / 协程),进程数上限只受限于内存大小。

  • 没有进程邮箱。

  • 进程之间只有同步消息(要发送异步消息,用启动一个新的进程并发送同步消息来达到同样的效果)。

  • 网络服务器是多进程模型,每个请求都由一个独立的进程来处理。

  • 有锁。

两个版本的编程模型的关键差异在于拒绝锁还是拒绝异步消息。CERL 1.0(也就是 Erlang 编程模型)中拒绝锁,而 CERL 2.0 拒绝异步消息。基于 CERL 2.0 我们实现了分布式存储的第二版、第三版。事实证明,完全杜绝了异步消息这个概念后,这个版本的服务器编程模型心智负担小了很多。

然后,如大家所知,后来 Go 语言就发布了。我们团队一看,在服务器编程模型这一点上,CERL 2.0 和 Go 语言居然一模一样(包括所有细节上的决策)。有一次团队聚餐谈起这事时,道哥(李道兵)说了一句:我们赶紧把 CERL 开源吧,不然等 Go 流行起来它就没机会了。我还真和创新院院长陈大年谈了 CERL 开源的事情,大年说:没问题,你发个邮件申请吧,留个凭证。然而我最终没有发出这封邮件。在尝试用 Go 写了一周的代码后,我心里已经有了结论:我并不打算让 CERL 面世。因为有人已经把它的目标完成了,而且远超预期。

于是,2011 年 6 月,我们离开盛大创新院创办七牛云的时候,我面临了第三次技术选型。这一次,我很坚决地选择了 Go 语言。为此我还专门给团队发了一封邮件,邮件中有一段是这么说的:

在创业过程中我们会面临很多选择,也会有很多选择后来会被证明是错的,但是今天我可以确定的是,选择 Go 将会成为我们最正确的选择。

在选择了 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 已经不再是一门小众语言。越来越多人在用 Go,喜欢上 Go。不记得是什么时候了,但是某一天通过 Google Trends 搜索 golang 发现全世界 Go 最火的地区是在中国时,那一刻真的很开心。

下一个十年会怎样?我知道有一些人很期望 Go 语言特性的迭代。但是如果你抱有这种想法可能会失望,因为下一个十年 Go 不会发生太大的变化。对远期需求变化的预测和把控能力,是 Go 的最大魅力之一。这一点上能够和 Go 相比的是 C 语言(C 语言不同版本的规范差异极少),但因为 Go 要解决的问题更多,做到这一点实际上也更难。下一个十年 Go 仍然会继续深耕服务端开发的生态,同时积极探索其他潜在的应用市场。

 

 
谋胆并重
相关实践学习
简单用户画像分析
本场景主要介绍基于海量日志数据进行简单用户画像分析为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps 
目录
相关文章
|
8天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
40 0
|
1天前
|
存储 编译器 Go
Go语言学习12-数据的使用
【5月更文挑战第5天】本篇 Huazie 向大家介绍 Go 语言数据的使用,包含赋值语句、常量与变量、可比性与有序性
35 6
Go语言学习12-数据的使用
|
3天前
|
Java Go
一文带你速通go语言指针
Go语言指针入门指南:简述指针用于提升效率,通过地址操作变量。文章作者sharkChili是Java/CSDN专家,维护Java Guide项目。文中介绍指针声明、取值,展示如何通过指针修改变量值及在函数中的应用。通过实例解析如何使用指针优化函数,以实现对原变量的直接修改。作者还邀请读者加入交流群深入探讨,并鼓励关注其公众号“写代码的SharkChili”。
9 0
|
3天前
|
存储 缓存 Java
来聊聊go语言的hashMap
本文介绍了Go语言中的`map`与Java的不同设计思想。作者`sharkChili`是一名Java和Go开发者,同时也是CSDN博客专家及JavaGuide项目的维护者。文章探讨了Go语言`map`的数据结构,包括`count`、`buckets指针`和`bmap`,解释了键值对的存储方式,如何利用内存对齐优化空间使用,并展示了`map`的初始化、插入键值对以及查找数据的源码过程。此外,作者还分享了如何通过汇编查看`map`操作,并鼓励读者深入研究Go的哈希冲突解决和源码。最后,作者提供了一个交流群,供读者讨论相关话题。
14 0
|
4天前
|
Java Go
Go语言学习11-数据初始化
【5月更文挑战第3天】本篇带大家通过内建函数 new 和 make 了解Go语言的数据初始化过程
17 1
Go语言学习11-数据初始化
|
4天前
|
自然语言处理 安全 Java
速通Go语言编译过程
Go语言编译过程详解:从词法分析(生成token)到句法分析(构建语法树),再到语义分析(类型检查、推断、匹配及函数内联)、生成中间码(SSA)和汇编码。最后,通过链接生成可执行文件。作者sharkchili,CSDN Java博客专家,分享技术细节,邀请读者加入交流群。
22 2
|
4天前
|
Java Linux Go
一文带你速通Go语言基础语法
本文是关于Go语言的入门介绍,作者因其简洁高效的特性对Go语言情有独钟。文章首先概述了Go语言的优势,包括快速上手、并发编程简单、设计简洁且功能强大,以及丰富的标准库。接着,文章通过示例展示了如何编写和运行Go代码,包括声明包、导入包和输出语句。此外,还介绍了Go的语法基础,如变量类型(数字、字符串、布尔和复数)、变量赋值、类型转换和默认值。文章还涉及条件分支(if和switch)和循环结构(for)。最后,简要提到了Go函数的定义和多返回值特性,以及一些常见的Go命令。作者计划在后续文章中进一步探讨Go语言的其他方面。
10 0
|
5天前
|
JavaScript 前端开发 Go
Go语言的入门学习
【4月更文挑战第7天】Go语言,通常称为Golang,是由Google设计并开发的一种编程语言,它于2009年公开发布。Go的设计团队主要包括Robert Griesemer、Rob Pike和Ken Thompson,这三位都是计算机科学和软件工程领域的杰出人物。
14 1
|
6天前
|
Go
|
6天前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
135 1