本月 17 日,Go 1.8 版本火热发布。相较于以往的版本,Go 1.8 具体有哪些新的特性呢?想必这是不少 Gopher 们热切关注和讨论的问题。作为著名的Golang 布道者,Gopher China 社区创始人,谢孟军早在今年一月的 ECUG Con 上就对 Golang 做出了历史版本的回顾和 1.8  版本的分析,本文就是对他的演讲实录。

谢孟军

 

Gopher China 社区创始人,著名开源框架 beego 开发者,畅销图书《Go Web 编程》作者,同时有 bat、bee 等开源软件。国内 Go 发展的主要推动者之一。


谢孟军:大家好,我是来自 Apple 的工程师,目前主要在从事工业自动化系统的架构和研发,今天很高兴来到这里跟大家分享一下关于 Go 的一些东西。Go 是 Google 的语言,Go 语言已经出来 6 年了,从 1.0 版本到 1.8 版本,今天最主要是跟大家分享一下 Go 在 1.8 版本中带来了哪些新特性。

Go 回顾

2012 年 3 月 Go 1.0 版本发布,这是一个标志性的事件。很多语言发布出来之后再次升级都会有或多或少不兼容的体验,但是 Go 官方团队在发布 1.0 的时候发布申明,后续的版本保证百分之百向前兼容,他们也遵守了当时的承诺。1.0、1.1、1.2、1.3 一直到 1.7,你的代码如果是 1.0 时候写的,现在升级到 1.7,都可以正常编译。其他语言里面我们可能都会有这样的体验,升级了一个新版本之后,需要花很多时间把代码兼容到新升级的版本中。所以对于一个语言来说,特性稳定是非常重要的。

Go 语言基本上保持了半年发布一个版本的节奏:

  • 2013年的 5 月份发了 1.1 版本;

  • 2013 年 12 月份发了 1.2 版本;

  • 2014 年 6 月份发布了 1.3 版本;

  • 2014 年 12 月份发布了 1.4 版本;

  • 2015 年8 月发布了 1.5 版本(这个版本拖延的时间有点长,官方规定此后半年出一个版本);

  • 2016年 2 月份发布了 1.6 版本;

  • 2016 年 8 月发布了 1.7 版本;

  • 2017年 2 月将会发布 1.8 版本。

Go  1.8 版本带来了哪些新特性

语言层面

几乎没有任何改变,有一个小小的改进是:

struct 里面的字段都是一样的,但是 struct tag 一个是 foo,一个是 bar,新版本现在可以这样赋值了:V1=T1(V2)//now  legal。

工具层面

  • 编译工具

首先是编译工具。大家知道,1.7 版本之后 Go 引入了 SSA,SSA 的引入把编译之后的二进制文件压缩小了,性能提升了。但是 1.7 版本中只针对了 64 位机器实现了 SSA,其他的全部还是用老的编译。但是在 1.8 版本中全部用 SSA 编译了,性能和大小基本上提升了 20% 到 30%。但是 Go 官方对所有的包测试下来,整体性能相对于 1.7 版本提升了将近 15% 。

  • Go Vet

go vet 大家写完代码之后可以用它检查一下是否符合标准,go  vet 在 1.8 版本中增加了一些更加严格的方式:

  1. copylocks  for  len&cap,当值传递到 len 函数的时候,锁拷贝进去之后很容易引起问题,这个时候,go  vet 之前是检测不出来这个错误的,但是 1.8 版本可以检测出来这行代码是有问题的,存在锁拷贝。

  2. JSON  tags,在 1.7 版本之前写完全没有问题,在 1.8 版本中当两个 tag 一模一样时,会检测出两个 tag 之间应该用空格隔出来,而不是用“,”,这个地方必须空格。你的代码编译度没有任何问题,只是运行的时候存在一些问题。所以,go vet 是在你代码编译之前帮你检测代码层面存在的问题,相当于静态文件分析法。

  3. Close  before  checking  errors,当有错误的时候,那么 res 就会返回 nil ,这时候程序就崩溃了,1.8 版本的 vet 可以检测出来。 error 检测必须在调用 res 之前,这样的话就可以避免出现 panic 的情况。

  • Default  GOPATH

Go 语言安装后之后需要设一个 GOPATH,但是在 Go  1.8 版本中实现了默认装后就会帮你设好一个 GOPATH 的环境变量。如果是在 Unix 环境下,就是在上图中 $HOME/go 那个目录下;如果是 Windows 环境下,就是在上图中 USERPROFILE 那个目录下。即目录已经帮你设好了,方便你装好 Go 就可以直接去用了。

  • plugins

在 Go  1.8 版本中支持动态加载 plugins,目前只支持 Linux 系统,Mac 和 Windows 都不支持。这里举个例子:首先我们定义一个函数,那么怎么把这个编译成插件呢?用一个参数 go  build -buildmode=plugin,编译出 SO 文件,SO 文件编译完成之后怎么调用呢?在 1.8 里面增加了标准库的包 plugins,所以你可以使用 plugin.Open 动态地打开 SO 文件,就会返回 p,然后查找里面的函数,这个时候会返回一个符号,首先进行类型转换(类型断言),最后调用它,最后就可以调用 plugins 的东西了。plugin 的引入可以把使得 Go 的程序变成很小的一部分,Go 程序里面又分了微服务的感觉,采用模块化设计。但是这种问题又带来依赖的问题,目前我是持怀疑态度看待 plugin 的引入,但是对于部分企业来说是有用的,因为它可以做到中间件的部分自己去升级。但是我现在测试下来,这个 plugins,刚才 10 行不到的函数编译下来就有 5M 多,而且性能也是一个问题。

  • go  bug

Go 里面新增加了一个命令叫 go  bug,当你发现一个 bug,它会自动搜集系统的信息,打开浏览器,只要你填发现的问题就好了,非常方便你提 bug 的一个工具。

  • go  pprof

Go 在 1.8 版本中开始支持 tts 的调试。

runtime 层面

第一个是 argument  liveness。在编写程序时,有些变量我们是希望它常驻内存的,在 1.7 的时候引入了一个函数 runtime.KeepAlive,这个变量保持在内存里面不要给 GC 干掉,它现在可以自己控制这个东西。1.8 版本针对它更加优化了一些。

第二个是 Concurrent  Map  Misuse。如果针对一个 Map 有并发的读和写是存在竞争的,1.6 版本之前不会把你的程序给崩溃掉,1.6 版本之后程序就会直接退出,这种情况怎么样避免呢?在编译的时候加 race,把代码竞争的情况全部检测出来。在 1.8 版本里面,针对这个东西就进行了更加严格的检测,当你在循环读这个 Map 的时候,Map 在其他地方写的时候会进行检测。

第三个是 memStats  Documentaition。Go 的文档大部分都是很好很详细,但是有些地方很简单、简略,1.8 版本中增加了更多的文档。

Performance 层面

Go 从 1.0 开始,一直在持续地改进它的 Performance。首先来看标准库包语言,官方数据说这些包都有做改进,最主要改进的是 runtime 和反射这两个包,反射包的性能提升 20% 到 30% 左右,这个提升比较重要。这个提升有一部分来自于新的编译器可以做到缩小、内存优化。

第二个是 Garbage Collector(简称 GC )。Go 的 GC 从 1.0 发布之后,一直有人说 Go 的 GC 不行。直到 1.5 版本之后,有一个大牛主导 GC 之后,现在没有人吐槽 Go 的 GC 了。 Go 的 GC 和 Java 的 GC 不一样,Java 的 GC 是几百个参数让你去搭配,让你配出来这个东西是最适合自己的场景。但是 Go 不一样,没有什么可以做,但是你可以通过一些其他的方式优化,比如减少对象的分配。但是好消息是 Go 官方一直在改进它,在 Go 1.4 版本的时候它的 GC 在 300 毫秒的时候,但是在 1.5 版本 GC 已经优化得非常好了,压缩到了40 毫秒。从 1.6 版本的 15 到 20 毫秒升级到 1.63 版本的 5 毫秒。又从 1.6.3 升级到 1. 7 版本的 3 毫秒以内,1.8 版本是 1 毫秒以内,基本上可以做到 1 毫秒以下的 GC 级别。

360 碰到 GC 问题最严重,360 整个消息推送系统是用 Go 语言写的,消息要及时送出去,GC 存在 30 毫秒卡住了,消息发送不出去。他们现在用 Go 1.8 测试,现在 GC 已经不是他们的问题了。当然,大家可能会说这有点不可信,GC 降下来了,CPU 使用率就上去了,1.7.3 和 1.8 版本中,CPU 肯定会多利用一些,CPU 的使用率相对上升了一点,但是 GC 有很大的提升。应该说,在 1.8 版本发布之后,1.9 版本现在引入了一个理念——goroutine 级别的GC,所以 1.9 版本可能还有更大的提升。

另一个是 Defer,Defer 在 1.8 版本中性能基本是提升了一半以上。

最后是 CGo,它的性能差不多提升了一半以上。代码等很多东西都是功能先实现,有了功能之后再提升它的。

New Features

  1. HTTP/2  Push。在 1.8 版本中支持了 HTTP/2  Push 的功能,即你不需要通过浏览器来主动地搭这个,在服务端的时候,当你访问这个东西的时候,我可以主动地把资源推给你,不用浏览器解析 HTML 的时候浏览器再来发请求。在 1.8 版本在 Go 里面有一个非常好的东西是,针对HTTP/S 和 HTTP/2 是最好的语言,在 Google 内部需要所有的服务接口都通过 HTTP/S,Google  HTTP 包非常稳定,因为它们用了大量的应用,同时内部要求全部用 HTTP/S,他们只能硬着头皮把它全部实现好。

  2. Graceful  Shutdown。很多人说热重启怎么办?这个问题在 1.7 版本之前有很多库,通过各种模拟,各种记录,怎么样实现平滑重启。在 Go  1.8 版本中内置了一个 graceful shutdown 的函数,访问的时候就可以很容易重启这个服务了。

  3. Mutex  Contention  Profiling。我们在写程序的时候会用很多锁,但是怎么样调试这个锁的力度?在 Go 的 1.8 版本中支持了 mutex 的 profile,通过 profile 可以看得到类似输出这样一个东西,可以看得到在哪里实现了有锁的东西,这个锁花了多少时间。

  4. database/sql。数据库用的是最多的,先前的 Go 数据库中要执行一个很长的 SQL 数据库,我碰到一些异常,我不要了,但是我不能取消掉它,它还在继续执行,等着它反馈。在 1.8 版本中增加了 Queries  Context,可以把它停止掉。Queries  Context 通过外部把它停掉,内部才会监听掉 Queries  Context 的信号,后面才会退出。

  5. New  slice  sorting  API。以前对一个 slice 排序,要把 slice 定义一个类型。在 1.8 版本中相对于增加了一个 sorting  slice 函数,可以很方便地匹配,slice 已经排序好了。

关于 Go  1.8 所有的信息就介绍到这里。Go 社区 4 月份即将在上海举办 Gopher  China 的大会,也会邀请 Go 领域的各大专家来参会。

在 Go 社区中,中国的用户群最多,为什么 Go 在中国这么红呢?PHP 在国内很红火,PHP 刚开始确实开发很快,但是稍微上一点规模就遇到很大的性能问题,PHP 开始转向 Go,Go 可以解决很多性能问题。Go 语言相对来说比较容易学,因为它还是 C 系列的,PHP 也是 C 系列,还有 Python,逻辑代码太多了,重新去写花的时间太多了,把它编译成 Go。也可以看得到,整个 Google 的态度。

同时,我们也可以看到,云计算其实最初是 Google 提出来的,亚马逊只是把它发扬光大了,提供了公有云,OpenStack 提供了私有云,实际上大家都在抄袭 Google,所有做的云计算的东西都是复制 Google 基础架构的东西。因为 Google 做得最大,整个云计算的基础架构,我们都在学习它的东西。Go 语言也是 Google 出来的,这和他们当初设计 Go 的理念是一致的,为什么会设计 Go?随着云计算的发展,我们的应用是分布式化了、我们的系统是多核了,现在所有的语言都是十几年、二十年之前的,语言层面没有办法解决充分利用多核,所以才会设计了 Go 语言。

再回到我们刚刚讲的,为什么 Go 在中国这么火爆?我们在中国的互联网,特别是移动互联网增长的时候,大家都遇到了性能问题、扩张问题。这个时候,大家开始回想,我们当初写的这个东西是不是正确?想要解决新的问题的话,就想要找 C+ +,这个时候又觉得很复杂。Go 相当于在一个中间的过程,并发快、性能高,它在中间的位置,所以中国有很多人用 Go 写基础架构。


Q:Java 和 Go 分别是什么定位?Go 会替换掉 Java 吗?

谢孟军:不太可能,Java 的体系太多,特别是金融领域,做金融的基本上都是用 Java,支付宝、银行那一套东西,替换比较困难。但是 Go 定位的是什么?定位的是两个东西:1.基础架构;2.云计算,这两方面是 Go 发力的地方。

补充:我觉得 Go 和 Java 更像是公有云和私有云,Java 在企业服务方面是 Go 最难替换的。

(注:本文内容整理自七牛云主办的 ECUG Con 十周年大会,转载请注明出处。)

谢孟军:The State of Go | ECUG Con 精粹系列的更多相关文章

  1. 【容器人必看】你一定要来 ECUG Con 2018 的三个理由!

    引领国内云领域风向的高端峰会 ECUG Con 2018,即将在 12 月 22-23 日 深圳南山 全新启程!如果你的工作和容器内容相关联,如果你的兴趣和容器技术有交集,如果你是「容器人」,那么这就 ...

  2. Go语言的9大优势和3大缺点, GO语言最初的定位就是互联网时代的C语言, 我为什么放弃Go语言

    Go语言的9大优势和3大缺点 转用一门新语言通常是一项大决策,尤其是当你的团队成员中只有一个使用过它时.今年 Stream 团队的主要编程语言从 Python 转向了 Go.本文解释了其背后的九大原因 ...

  3. 【GoLang】转载:我为什么放弃Go语言,哈哈

    我为什么放弃Go语言 作者:庄晓立(Liigo) 日期:2014年3月 原创链接:http://blog.csdn.NET/liigo/article/details/23699459 转载请注明出处 ...

  4. Golang哲学思想

    Golang是一门新语言,经过几年发展,慢慢地也已经被许多大公司认可.最大的特点是速度快,并发性好,与网络的功能结合好,是一门服务端语言,号称“网络时代的新语言”:另外还是一个编译型的Python.不 ...

  5. golang安装卸载 linux+windows+raspberryPI 平台

    参考  https://golang.org/doc/install 自ECUG2013洗脑回来,就渴望早点接触Go 听着许式伟和谢孟军的演讲 发现go的网络库的确很强大,高负载利器,语言的一些精简导 ...

  6. 3000本IT书籍下载地址

    http://www.shouce.ren/post/d/id/112300    黑客攻防实战入门与提高.pdfhttp://www.shouce.ren/post/d/id/112299    黑 ...

  7. 驳2B文 "我为什么放弃Go语言"

      此篇文章流传甚广, 其实里面没啥干货, 而且里面很多观点是有问题的. 这个文章在 golang-china 很早就讨论过了. 最近因为 Rust 1.0 和 1.1 的发布, 导致这个文章又出来毒 ...

  8. Go语言缺陷

    我为什么放弃Go语言 目录(?)[+] 我为什么放弃Go语言 有好几次,当我想起来的时候,总是会问自己:我为什么要放弃Go语言?这个决定是正确的吗?是明智和理性的吗?其实我一直在认真思考这个问题. 开 ...

  9. 【原】Go语言及Web框架Beego环境无脑搭建

    本文涉及软件均以截至到2013年10月12日的最新版本为准 1. 相关软件准备: 1) go1.2rc1.windows-386.msi,对应32位windows系统安装使用 下载地址: https: ...

随机推荐

  1. P2006 赵神牛的游戏

    题目描述 在DNF 中,赵神牛有一个缔造者,他一共有k点法力值,一共有m个技能,每个技能耗费的法力值为a[i],可以造成的伤害为b[i],而boss 的体力值为n,请你求出它放哪个技能,才可以打死bo ...

  2. 5款好用的mysql客户端

    1. EMS SQL Manager for MySQL 是一款高性能MySQL数据库服务器系统的管理和开发工具.它支持从MySQL 3.23到6.0的任一版本,并支持最新版本的MySQL的特点,包括 ...

  3. 在windows上安装Jenkins---tomcat流

    在windows上安装Jenkins有两种方式: (1)jar流 在命令行中运行:java -jar jenkins.war 浏览器访问 localhost:8080,创建初始管理员帐号即可. (2) ...

  4. P2257 YY的GCD (莫比乌斯反演)

    题意:求\[\sum_{i=1}^{n}\sum_{j=1}^{m}[gcd(i,j) = prim]\] 题解:那就开始化式子吧!! \[f(d) = \sum_{i=1}^{n}\sum_{j=1 ...

  5. ubuntu18.04server 真机无法自动获取IP解决方法

    输入命令ip a,查看自己网卡编号,比如我的就是ens33 因为此图为虚拟机搭建的,所以网卡名称为ens33,如果是真机的话则是enp0s**的名字 2.修改netwlpan文件 1 sudo vim ...

  6. 从零开始--系统深入学习Android

    http://www.cnblogs.com/tianjian/category/354587.html

  7. 模拟--P1328 生活大爆炸版石头剪刀布 题解

    P1328 生活大爆炸版石头剪刀布 这也是打表么?? #include <iostream> using namespace std; static const auto y = []() ...

  8. 洛谷P2802 回家

    贱呼呼的搜索题 这个最贱的还是在于路途的标记,大部分的题目路途的标记是直接标记即可也就是说我走过了这个点,那么这个点标记上以后不再走,这个题不是,我走过了,但是我可能回了血我又继续走 所以说我们标记的 ...

  9. [模板] 动态ST表

    ST表本身是不可修改的. 如果考虑增加一个数,可以把ST表反过来写,即f[i][j]表示i往前1<<j个数,一个数最多影响logn个数,常数非常小. #include<iostrea ...

  10. 13. OPTIMIZER_TRACE

    13. OPTIMIZER_TRACE OPTIMIZER_TRACE表提供由跟踪语句的优化程序跟踪功能生成的信息. 要启用跟踪,请使用optimizer_trace系统变量. 有关详细信息,请参阅M ...