当前位置: 首页 > news >正文

Go, Jocko, Kafka


本篇内容是根据2016年8月份# 31. Go, Jocko, Kafka 音频录制内容的整理与翻译


Travis Jeffery 参加了节目,谈论 Go、Jocko、Kafka、Kafka 的存储内部结构如何工作,以及有趣的 Go 项目和新闻。


Erik St. Martin: 大家好,欢迎回到《GoTime》的另一期节目。今天是第31期。我们的赞助商是 StackImpact 和 Backtrace。

今天的节目中有我自己,Erik St. Martin,还有 Carlisia Pinto……

Carlisia Thompson: 很高兴来到这里。

Erik St. Martin: 还有 Brian Ketelsen。

Brian Ketelsen: 大家好!

Erik St. Martin: Brian 和我之前在几期节目中谈过 Kafka,以及我们对它的喜爱。我想我们甚至提到过一个项目,所以今天我们特别邀请到了 Travis Jeffery 来和我们聊聊 Jocko,这是用 Go 实现的 Kafka (译者注: 不过已经久不更新)……结合了我们热爱的两个世界!

Brian Ketelsen: 是的,这就像两种美味结合在一起……当你把花生酱放进我的 Kafka 时,我简直不能更开心了。

Erik St. Martin: 你可以先和我们聊聊这个项目以及你背后的动机吗?

Travis Jeffery: 当然可以。

Erik St. Martin: 先简单介绍一下你自己吧,这样可能会更有帮助。

Brian Ketelsen: 是的,介绍一下自己总是好的。

Travis Jeffery: 好的……但这个问题总是有点难回答。我是在加拿大安大略省多伦多以北两个小时车程外的一个农场长大的,那是一个偏僻的地方。我父母都是企业家,所以我有很多时间看电影、玩电子游戏和读书。他们把我送到一个叫 “Teddy Bear” 的日托中心。我从小睡眠时间就不多,所以日托中心的人会让我玩电脑,那是一个 Mac 3,我就这样度过了其他孩子午睡的时间。

大概12岁时,我拿起了一本书---我记得那本书是《The Pro Book》,第二本是《C Primer》,然后我还看了《Hacking: The Art of Exploitation》,因为我那时觉得自己会成为一名黑客。

Erik St. Martin: 我好像也有那本书的第一版。

Brian Ketelsen: 还是签名版的……

Travis Jeffery: 是的。不久之后,DHH(David Heinemeier Hansson)发布了一个名为《How To Build A Blog In 10 Or 15 Minutes》的教程,我当时想,“天啊,这太酷了!” 从那时起,我就开始制作 Web 软件。

在大学之前,我开始为开源项目做贡献;一开始是 Emacs 和 Vim,然后是 Django,后来是 Rails。在大学一年级和二年级之间,我就开始收到一些大科技公司的招聘邮件,比如 Google。那时候我刚进大学,原本以为自己会成为一名数学教授。后来我逐渐接受了自己会成为一名程序员的想法,因为我把所有时间都花在了开源编程上。

当我开始收到那些招聘邮件时,我问其中一个公司,“如果我不完成学位,你们能让我进入美国工作吗?” 他们回答说,“可以。” 然后我就想,“好吧,那我不读了。” 所以我辍学了,和一些朋友一起创办了一家初创公司,后来我们把公司卖给了 Shopify。

之后我去了 Basecamp(以前叫 37Signals)工作,那是一段很棒的经历。后来我又想再做一次初创公司,于是找了一位朋友 TJ Holowaychuk 聊了聊,问他在哪里工作。他告诉我他在 Segment IO,这是一家关于数据分析的初创公司。

我最终加入了那里,也因此接触到了 Go。最初 Segment IO 是用 NodeJS 构建的,随着我们的规模扩大,Node 的事件循环经常因为处理 JSON 而被阻塞。这就是我开始引入 Go 的原因,最终我们基于 Go 构建了几十个微服务。

现在我在另一家数据分析公司 Taplytics 担任架构负责人。这是我现在的工作状态。未来我希望能够自己创办一家公司,也许写些剧本……我有一天想拍电影,那会非常酷,还有很多写作的计划。这就是我的故事。

Erik St. Martin: 不错。那么用 Go 实现 Kafka 的主要动机是什么?

Travis Jeffery: 我已经使用 Kafka 有几年了,我非常喜欢 Kafka。尽管如此,也有一些让我觉得烦的地方……比如,它有一些负担,比如 JVM 和 Zookeeper。你知道的,这些并不是特别友好,因为你需要维护 Zookeeper,还有其他的相关工作……另外一点是,我不太喜欢 Kafka 的配置方式,这是我想改进的一个地方。

比如说,你可以为一个主题(topic)配置在某个 broker 上保留一定量的数据。如果你再添加一个主题,而这个主题被分配到同一个 broker 上,可能会超出你预设的数据量。基本上,你希望能够设置一个百分比,比如说“某个主题占用磁盘的 10%”,但 Kafka 不支持这样的功能,这是我想改进的地方。

不过,总体来说,Jocko 的想法是打造一个非常容易设置的 Kafka。我会发布一个单一的二进制文件,不依赖 Zookeeper,同时保持协议兼容性,这样目前使用 Kafka 的人可以直接切换到 Jocko,而不会有任何问题,并且能够兼容 Kafka 的客户端和所有相关工具。这就是这个项目的基本理念。

Erik St. Martin: 我觉得我们可以稍微回头讲一下 Kafka 是什么,以及它的用途。

Travis Jeffery: 好的,Kafka 是一个分布式、可复制的提交日志服务。基本上它保存了一系列的记录,然后这些记录可以被 worker 消费。你可以把它用作消息队列,或者任何你需要流数据的场景,这就是它的主要用途。比如说,在 Taplytics,我们处理的是分析事件。这些事件会进入我们的 API,然后被发送到 Kafka,接着 worker 会读取这些事件,处理它们并执行后续操作。

Brian Ketelsen: 我觉得 Kafka 最神奇的地方在于你可以把它用作你的“系统记录(system of record)”。对我来说,这就是 Kafka 的强大之处---这个看起来有点像 Git,又像队列,甚至像数据库的东西,能成为你所有其他应用程序的系统记录。我最喜欢用 Kafka 的方式就是将所有的变更推送到 Kafka,然后其他系统从 Kafka 读取这些变更,并进行复制。

Erik St. Martin: 是的,这种方式非常棒……Brian 和我一起做过一些项目,有时候你需要在多个数据存储中使用相同的数据,Kafka 就是一个很棒的系统记录工具,它可以让所有的数据存储自己填充数据,以便你在不同的场景中访问它们。

Travis Jeffery: 是的,你可以把它看作是一个所有数据的中心。在 Segment,我们经常的做法是,某些数据会进入 Kafka,一个 worker 会从 Kafka 中读取这些数据,进行一些处理后再将它们放回另一个 Kafka 主题中,然后如此循环,直到最终数据被写入数据库或其他存储。

Brian Ketelsen: 是的,这是一个非常常见的模式。

Erik St. Martin: 这种流数据工作流的一个好处是,无论服务上线还是下线都不会有问题。比如,如果一个服务崩溃了,或者你需要升级并临时关闭服务,数据仍然会被推送到 Kafka 中,队列会稍微积压一些,直到消费者重新上线,这非常棒。

Travis Jeffery: 是的,没错。对于扩展来说,它也非常厉害,因为数据会被排队,你可以通过增加 worker 来更快地处理它们。

另一个很棒的地方是它能够管理你的依赖关系图。你不需要让服务之间直接通信,你只需要 worker,它们彼此之间不知道对方的存在---它们只需要从 Kafka 中读取数据,然后将处理后的结果重新写入 Kafka。这种方式非常方便,你可以随时添加更多的 worker。

Erik St. Martin: 是的,这基本上和使用 goroutines 和 channels 的方式类似。比如,你并不关心那些从你的 channel 中消费数据的东西,你只负责将数据推送到你负责的 channel,或者从 channel 中接收数据并处理它们。你并不需要了解系统中的其他组件。

Travis Jeffery: 是的,同一个主题也可以被多个消费者组消费。比如,一个消费者组可以读取数据并立即将其提供出来,比如放入缓存中,另一个消费者组可以对数据进行处理,使其适合长期存储。

Erik St. Martin: 那么,Jocko 的开发进展如何?性能表现如何?功能是否已经完整?目前是只有你一个人在做这个项目吗?

Travis Jeffery: 是的,目前基本上只有我一个人在做这个项目。我收到了一些别人的提交……现在已经快要完成所有功能了。我目前正在做的是复制功能,这部分我觉得已经基本实现了……接下来我只需要做更多的测试,然后就是消费者组的支持。这些完成后,功能就算基本完整了,我觉得目前离完成已经很接近了。

我还没有开始性能测试,所以具体表现还需要等等看。从理论上来说,性能应该会很接近,因为限制性能的主要因素是磁盘,而 Jocko 使用的算法和设计与 Kafka 是一样的。

Go 相比 Java 缺少的一个功能是所谓的零拷贝网络(zero-copy networking)。零拷贝网络是指网络套接字可以直接连接到磁盘套接字,中间绕过内核。这是 Java 相比 Go 的一个优势。有些人已经开始实现一些支持零拷贝的库,但我觉得这些库目前还没有完全准备好。

Erik St. Martin: 哦,挺有意思的。这些问题其实是随着具体需求的出现才暴露出来的,大多数人写的代码都不需要类似的功能。

Brian Ketelsen: 最近 Kafka 的协议不是改了,不再需要 Zookeeper 了吗?这应该会让你轻松不少吧?

Travis Jeffery: 是的,确实如此。这也是为什么我可以做这个项目,因为我不需要依赖 Zookeeper。所有的消费者信息都会内置在 Kafka 中,状态数据会用共识协议在 broker 之间传播和存储,状态会直接保存在 broker 上。

Brian Ketelsen: 太棒了。我读了你关于存储层实现的博客文章,觉得很有意思,真的很酷。你能再多讲讲存储的内部实现,以及你是如何将它从 Java 映射到 Go 上的吗?

Travis Jeffery: 基本上,我的做法是先克隆了 Kafka 的代码库,然后从整体上了解它的结构。我查看了它的目录和文件,然后深入研究它们……比如它有一个日志目录,我查看了里面的文件,弄清了它们的工作原理。我非常喜欢他们的实现方式。我还买了一本书,叫《Kafka: The Definitive Guide》,我读了这本书。

这本书从高层次描述了它的工作原理,然后我就基于这些信息开始实现它。所以基本上,我学了足够的 Scala,只是为了理解发生了什么,然后用 Go 实现了它。

Brian Ketelsen: 很不错啊。所以你没有用任何中间存储机制,比如 BoltDB 或 LevelDB,而是完全自己实现了存储?

Travis Jeffery: 是的,存储内部完全是自己实现的……因为如果使用 BoltDB 的话,速度会慢得多。

Erik St. Martin: Kafka 使用的是日志结构合并树(log-structured merge tree)和像 Cassandra 那样的 SSTables 吗?还是它的底层存储层有不同?我没读过 Brian 读的那篇文章。

Travis Jeffery: Kafka 的一个特点是它在客户端上做了很多工作,这也是它性能优秀的原因之一。基本上,Kafka 的客户端会按照 Kafka 的协议对数据进行编码,然后这些数据会以相同的格式直接写入 Kafka 服务器的磁盘。这种方式让 Kafka 的性能非常高,因为服务器在数据处理方面几乎没有额外的工作量,只是将数据写入磁盘。

Kafka 的做法是将数据写入日志文件,并将其追加到日志文件中。它会维护一个偏移量---Jocko 也是一样的……我会维护一个偏移量和日志文件中下一个字节的位置。这些日志的偏移量通过索引文件进行映射,索引文件将日志的偏移量映射到日志文件中的字节位置。所以当 Kafka 需要查找日志条目时,它会通过偏移量在内存映射的索引文件中进行二分查找,然后从索引文件中获取日志文件中的具体位置。这就是它的工作原理。

Brian Ketelsen: 它的架构设计得如此高效,真的很令人印象深刻。

Travis Jeffery: 是的,这也是我想做这个项目的另一个原因……因为我知道这是 Kafka 能够如此特别的一个关键部分,我想通过实现它来彻底理解它。所以这也是我开发 Jocko 的一个原因。

Brian Ketelsen: 你那篇关于存储引擎的博客文章真的很棒,我们会把它的链接放在节目笔记中。我很喜欢读那篇文章。

Erik St. Martin: 在开发过程中,除了你之前提到的内核级问题之外,你还遇到过其他什么困难吗?还是说在 Go 中实现这个总体来说比较顺利?

Travis Jeffery: 总体来说还不错……我最喜欢 Go 的一点是它的字节处理非常方便。比如 io.Writer 和 io.Reader……所以在开发过程中感觉很棒。Kafka 的网络传输方式是直接发送字节数据,而你只需要将它写入磁盘---这和 Go 的方式非常契合。

总的来说没有太多麻烦……另外,Kafka 客户端需要做很多工作,这也减少了我在实现 Kafka 时的工作量。所以大部分的工作都是围绕共识协议和服务发现展开的。

Erik St. Martin: 对,对。

Brian Ketelsen: 我注意到你用了 HashiCorp 的 Raft 和 Serf 来做服务发现和共识协议……你在选择之前有对不同的 Raft 实现做过基准测试吗?你选择它的原因是什么?还是说你只是随机选了一个?

Travis Jeffery: 我研究了 HashiCorp 的 Raft,也看了 Etcd 的 Raft。我觉得 HashiCorp 的实现更适合我的思维方式,显得更简单一些。另外,我也喜欢它在一个独立的代码库中。因为当我想查看项目的相关问题时,我只需要看到 Raft 的问题就可以了。

而 Etcd 的 Raft 库是整个项目的一部分,它是一个巨大的项目和代码库的一小部分。在 GitHub 上找到与 Raft 相关的问题特别困难,而 HashiCorp 的 Raft 就没有这个问题。所以这是让我觉得烦的一点。总的来说,HashiCorp 的 Raft 更符合我的思路。

另外一个好处是,我读了 Consul 和 Nomad 的源码,了解了它们的实现方式,所以看到它们也使用了相同的库,这对我来说很有参考价值。

Brian Ketelsen: 这很不错。

Travis Jeffery: 是的,Consul 和 Nomad 非常有用,因为它们都在库中使用了 Serf 和 Raft,所以是很好的例子。

Erik St. Martin: 好吧,我觉得是时候进入我们第一个赞助商广告环节了。

广告时间:

Erik St. Martin: 我们回来了。我们正在与 Travis Jeffery 聊 Jocko,现在我们来聊聊有趣的 Go 项目和新闻。大家最近有没有发现什么有趣的东西?

Brian Ketelsen: 这个星期发生了很多事,我不骗你。这个星期真的很热闹。

Erik St. Martin: 有多热闹?

Brian Ketelsen: 非常热闹,超级大。我是说,YUUGE(译者注: 特指巨大)!比我那双小橙色的手还大,就这么大。[笑声] YUUGE。今天 Google 发布了一个叫 Shenzhen Go 的应用(译者注: 目前已不维护;取这个名字也是有点意思),它可以通过图形化的方式连接 goroutines 和 channels,让你可以可视化设计并构建并发和数据流,然后它会根据你的设计生成实现这些 goroutines 和 channels 的 Go 代码。

这个工具还处于非常早期的 alpha 阶段,我觉得它目前还不支持双向同步,所以你只能从图形生成代码,不能反向修改图形。但这个工具看起来很有前途。我还没试过,但它能从一个可视化图生成 Go 代码,这真的很酷。

Erik St. Martin: 我还没玩过那个。

Travis Jeffery: 是啊,那挺酷的,看起来非常棒。其实很有意思的是,我刚发现了另一个项目,叫 Go-Call-Vis,它可以用 dot 格式来可视化你的 Go 程序的调用图。

Brian Ketelsen: 我昨天也看到了。

Travis Jeffery: 是啊,很有趣,它们的发布时间居然这么接近。不过这个看起来也很不错。它可以为你的程序提供一个函数调用的可视化概览,以及函数之间的关系之类的东西。

Erik St. Martin: 你看,现在有太多新的酷项目出来了,根本没有足够的时间去发现它们,更别提去玩这些东西了。我最近看到一个项目,也在 Go Weekly Newsletter 上提到过,这有点抢了我的风头,它叫 Subgraph,据说是一个新的操作系统,内置了沙盒和安全控制。

我看过某些地方提到他们用了很多 Go 语言,我在他们网站上也看到他们说使用 Go 是因为它的内存安全特性。我想深入了解一下,看看他们具体在哪些组件中使用了 Go。我也想联系一下他们,看看这些是应用层的东西,还是核心组件是用 Go 实现的。不过有意思的是,现在居然有操作系统试图用 Go 来做。

Brian Ketelsen: 对,我们得邀请他们来节目聊聊。

Erik St. Martin: 是啊,我们得记得把他们加到名单上。

Brian Ketelsen: 名单越来越长了。

Erik St. Martin: 每次节目中我们都会说,“我们一定要请这个人上节目”,结果后来就忘了。Carlisia,你这周有没有发现什么有趣的东西?

Carlisia Thompson: 有,我跟我的同事 Joshua 聊过,问他有没有用过什么队列系统。因为在 Rails 世界里有两个非常成熟的库---哦,我应该说是 Gem……但我还没在 Go 里用过类似的东西,不过可能很快就要用了。他提到了 Uber 上个月开源的一个库,我想是上个月开源的,叫 Cherami。其实我也挺想知道这些库和 Jocko 的相似之处,以及它们各自能做什么,或者不能做什么,不过可能得改天再聊了。

Brian Ketelsen: 我看过 Cherami,但还没在节目里提起,因为它的文档目前是空的。尽管他们在 12 月 6 日写了一篇大篇幅的博客来宣布它,但到现在还没有发布任何实用的文档。让人这么期待一个项目却没有文档支持感觉有点不太厚道,所以……它确实看起来很有意思,但在我读了博客和看了一些代码之后,感觉它更接近 NSQ,而不是 Kafka。让我感到惊讶的是,他们为什么要写一个新东西,因为它看起来和 NSQ 非常相似。我想我们可以找 Uber 的人聊聊,问问他们为什么选择写一个新的,以及 NSQ 哪些地方不适合他们。

Erik St. Martin: 不过很有意思的是,从 Carlisia 提供的页面来看,从高层设计上看,它很像 Kafka。有生产者向某个主题(这里他们叫队列)进行生产,然后有消费者组订阅消费。从一个非常高的层面来说,它确实有点像 Kafka 的工作流程。

Brian Ketelsen: 是啊,而且它用 RocksDB 做持久化存储,所以也许这就是最大的差异点。

Erik St. Martin: 我喜欢 Rocks!

Brian Ketelsen: 是啊,超快!这可能是它和 NSQ 最大的区别,因为如果我记得没错的话,NSQ 没有持久化功能。

Travis Jeffery: 关于 NSQ,我们在 Segment IO 用过 NSQ,但有一个问题困扰了我们,就是它没有顺序保证;而 Kafka 是有的。在 Segment IO,我们进行基准流量测试时遇到了这个问题,比如你有一些事件,它们属于一个会话,而你需要先创建会话,然后后续事件才能关联到这个会话上。这种情况下,Kafka 就解决了这个问题,因为它有顺序保证。

Brian Ketelsen: 是啊,这很合理。

Erik St. Martin: 现在我开始好奇这到底是好是坏了……[笑声] Kyle 在 GoTimeFM 频道说,如果我们要聊 NSQ,他有很多话要说。

Brian Ketelsen: 是啊,我们完全可以为 NSQ 做一期节目。我超爱 NSQ。我得去看看 Cherami,它看起来挺有意思的,但我们得弄清楚他们什么时候会把文档补全。

我还发现了另一个有趣的项目,叫 Ponzu。这其实是我一直想写但一直没时间做的东西。它是一个 CMS(类似 WordPress),但只有 API。它是为需要访问内容的客户端设计的,客户端通过 API 层访问内容,而不是像 WordPress 那样。

我很多次都需要类似的东西,所以看到有人写了这个项目我很兴奋。它看起来很有趣。项目地址是 GitHub 上的 Ponzu-cms/ponzu。挺让人期待的。

Erik St. Martin: 我喜欢它的 logo。最酷的不只是人们创造的软件,还有那些 logo。[笑声]

Brian Ketelsen: 反正这是音频节目,所以我来描述一下:logo 是一只拿着寿司盘子的 gopher,还戴着一条日式头带。挺厉害的。

Erik St. Martin: 不错。我还有一个觉得很酷的项目,我本来打算周末玩一下,但最后没玩上。它叫 Ebiten,是个 2D 游戏库,可以用来打造老式游戏。

Brian Ketelsen: 像 8-bit 那种?

Erik St. Martin: 对。我会把它发到频道里。

Brian Ketelsen: 听起来挺有趣的。

Erik St. Martin: 就用我那点空闲时间……

Brian Ketelsen: 就是,总有一天……

Erik St. Martin: 这就像 Travis 说的入门问题一样,对吧?我们大多数人小时候(比如十几岁的时候)都有两个梦想:想做黑客和想做电子游戏。这是大多数人的梦想……所以我心里仍然有个声音在说,“我想做一个电子游戏。”当然,我也仍然想成为一个黑客。

Brian Ketelsen: 总有一天……

Travis Jeffery: 我不知道我有没有公开说过,但《黄金眼》里的 Boris 对我小时候的影响很大。

Brian Ketelsen: 不错!

Travis Jeffery: 我是无敌的,你知道的……

Brian Ketelsen: 哈哈,太棒了!

Erik St. Martin: 好了,说个更大的话题---有没有人看到 Russ Cox 发布的 2017 年 Go 的新年计划?

Brian Ketelsen: 看了,你知道我读完的感觉是什么吗?我看完整篇文章,最后脑子里只剩下一句话---Go 2.0。

Erik St. Martin: 我不太确定是不是 2.0。你觉得……?

Brian Ketelsen: 是的,我觉得是。文中有些内容……如果你仔细读的话,会发现其中一些是破坏性改动,我觉得未来某个时候会有 Go 2。你可以叫我疯子……

Erik St. Martin: 我觉得包管理可能不需要做到那一步。比如一些东西可以直接加入,比如自动检查,甚至错误处理的改进,也不一定是核心的东西;这些可能通过标准库的增强来解决。我挺喜欢他们提到的一些关于最佳实践和示例代码库的内容,因为这通常是新手遇到最大问题的地方。他们会觉得,“好吧,我理解了语法,但文件该放哪里?我该怎么组织?怎么设计结构?一个典型的 web 应用该是什么样的?”

Brian Ketelsen: 你有没有注意到错误处理和最佳实践部分的某些细节?我觉得他们更认真地考虑采用 Dave Cheney 的 package errors,如果真是这样我会非常兴奋,因为那个库实在太棒了。

Travis Jeffery: 哦,天哪……太棒了。

Brian Ketelsen: 我们需要发起一个---白宫网站上那种请愿活动叫什么来着?我们需要搞一个那个。[笑声]

Erik St. Martin: Carlisia,你这周有机会看过那些东西吗?或者说那篇文章就刚刚发布了一两天。

Carlisia Thompson: 没有……我在 Twitter 上看到过,但还没读。我今天晚点会读一下。

Erik St. Martin: 我喜欢他最后提到的泛型那段。[听不清] “这是最后一件事。”

Travis Jeffery: 是啊,挺有趣的是那是最后提到的内容。如果有哪件事真的需要 Go 2.0,那可能就是它了,对吗?

Brian Ketelsen: 直接收尾。

Erik St. Martin: 我喜欢他能静下心来,把所有想法写成长文。也许其中有些目标很高,可能很难融入 Go 1 的承诺中,但至少有一个负责语言方向的人能坐下来写下这些东西,说“这些问题没有被忽视。它们是我们脑海中优先级很高的事情,也是我们想解决的。”像包管理这样的东西已经走了很长一段路了,找团队成员聊聊他们的进展会很有意思。

Brian Ketelsen: 是啊,包管理让我很痛苦。每次我以为已经理解了某个工具,结果就会被坑一次,这让我很抓狂。

Erik St. Martin: 我也是一样……就像,“好吧,我已经接受了现在的状况”,然后又觉得,“为什么它们不同步?为什么我的包不是最新的?为什么我不能直接更新这些包?我以为这些是可以的!”

Brian Ketelsen: 是啊,这让我有点疯,真不骗你。

Erik St. Martin: 我是编译 Kubernetes 的---为什么不能有一个命令直接获取最新的 Kubernetes 库让我重新编译?不过我还没试过 Glide,我得承认。我不知道其他人对 Glide 的体验如何,但这是我还没用过的一个工具。

Brian Ketelsen: 我现在用的是 Glide,但它让我想砸东西。可能是因为我之前用过其他的工具,而直到现在才开始用 Glide,但没有一个让我满意。

Erik St. Martin: 快速调查一下,我想知道---

Brian Ketelsen: 记住,这是音频节目啊……

Erik St. Martin: 我很好奇,做个小调查……你们平时最常用的 Go vendoring 工具是什么?我知道有时候因为项目需要不得不用其他工具,但大概来说呢?

Travis Jeffery: 我现在用的是 Go Vendor……

Erik St. Martin: 我也是用 Go Vendor,主要是因为在我加入团队之前,团队已经选择了这个工具。

Brian Ketelsen: 对,那也是我最喜欢的工具。

Erik St. Martin: Carlisia 你呢?你们团队用的是什么 vendoring 工具?

Carlisia Thompson: 我觉得我们在 Fastly 用的是 Go Vendor,至少我是用这个工具的。

Erik St. Martin: 看看这个……四个人里有四个都用 Go Vendor。这还不错……我本来还以为会有更大的差异呢。

Brian Ketelsen: 我们马上就达成了一致。这是个关于 Kafka 的小笑话,抱歉……

Travis Jeffery: 啊,再加点 Raft 的梗?

Carlisia Thompson: 哦,抱歉,其实是 godeps。

Brian Ketelsen: 哦,godeps……你是老派玩家啊!

Travis Jeffery: 我在用 Go Vendor 之前也是用 godeps。说实话,我也不太清楚……我换成 Go Vendor 后到底得到了什么?我也不太明白……不过它能完成任务就行了。

Erik St. Martin: 是的……我早期也用过 godeps,但我不知道它现在有哪些功能。不过我喜欢 Go Vendor 的地方在于它提供了一些小功能,比如可以标记“告诉我哪些依赖缺失了”,或者“告诉我哪些依赖在我的 GOPATH 里但不在 vendor 目录里”,通过一个 golist plus external 就能做到这些。所以我觉得这些功能还不错,但我仍然期待能有更好的工具……一直在寻找更好的选择。所以,是的,这里有很多不错的工具。

频道里有人提到了一位 Brian 最喜欢(讽刺语气)的人的话题,就是 Go 和 Rust 的对比---ESR 的文章。

Brian Ketelsen: 哦,别让我开始说 ESR。我看过他的博客文章,老实说,那篇文章其实写得相当好,很有逻辑性,但我还是无法忍受这个人。我们必须讨论这个话题吗?

Carlisia Thompson: 你在说什么?

Brian Ketelsen: ESR,也就是 Erik S. Raymond,他是……怎么说呢?Linux 世界里一位相对受尊敬的人物。他是长期的内核维护者,一直在 Linux 圈子里活跃。他认为自己是程序员的榜样,而我觉得他应该离开这个圈子。他最近写了一篇博客,基本上建议如果你在会议上遭遇性骚扰,唯一可以提出指控的办法就是你得有一个非常出色的 GitHub 仓库。也就是说,你能否为自己辩护或指控别人,完全取决于你是否有足够的“街头信用”,因为你写了足够好的代码。

Carlisia Thompson: 这完全没有道理啊。

Brian Ketelsen: 那跟是否真的发生了性骚扰完全没有关系。这让我非常愤怒,真的非常愤怒。他那篇关于 Go 的文章写得不错;他很好地阐述了 Go 和 Rust 在他们用例中的优缺点,内容还算客观,也写得挺好。

Erik St. Martin: 其实有趣的是,他在评论区和一些 Rust 用户来回辩论。从这篇文章中最有意思的点是---我们稍微偏题了,聊到了其他一些典型的 Hacker News 风格的帖子……但这篇文章特别有意思的地方在于,他作为一个传统的 C 程序员、内核维护者之类的人物,他提到自己在几天内上手了 Go,并感觉很熟练;但当他尝试用 Rust 做类似的事情时,却觉得非常痛苦,连基本的操作都很难搞清楚。这挺有意思的。

我喜欢看不同人的观点,因为 Go 刚推出时,本来是针对系统级开发者的:C、C++ 开发者。而我们这些动态语言的开发者却蜂拥而至。我们像是说,“太好了!再见了 Ruby!” 很多人都是从这个世界转过来的。所以我很喜欢看到来自那些长期从事 C 和汇编世界的人的看法。

Brian Ketelsen: 我刚在 Slack 频道里贴了那篇让我愤怒的文章链接。满满的愤怒。

Carlisia Thompson: 我还没读过;也许晚点会读……不过我甚至生不起气,因为你刚刚描述的内容完全没有道理。

Brian Ketelsen: 是啊,确实没道理。而且这个节目不应该讨论这个话题,所以我们应该赶紧换个话题,免得我说出让我后悔的话。

Erik St. Martin: 是的,这其实可以作为一个独立讨论的主题,或者我们可以聊聊他到底想表达什么……很难说,但从文章内容来看,这绝对没有表达好。他的表述很糟糕。

Brian Ketelsen: 我觉得我们确实应该做那期节目,真的。我觉得是时候让我们在 GoTime 上讨论一下行业中的性骚扰问题了,谈谈什么是可以接受的,什么是不可以接受的,以及这些标准在我们的行业中是如何变化的。我觉得邀请嘉宾可能会有些困难,因为那些经历过性骚扰的人---看起来几乎每位女性都以某种形式经历过---通常不愿意在播客上谈论这个问题。但如果能做一期这样的节目会很好…… 毕竟我们是 GopherCon 的组织者。

Erik St. Martin: 我们还有明确的行为准则 (COC) 来支持这一点。

Brian Ketelsen: 是的,去年我们使用了这个准则,而且非常有效,非常有效。

Travis Jeffery: 你们遇到过违反 COC 的情况吗?

Erik St. Martin: 有。

Travis Jeffery: 你知道有多少次吗?发生了什么?

Erik St. Martin: 困难在于,事情没有被报告并不意味着它没有发生。我们确实遇到过一些情况,但幸运的是都不算严重,敲敲木头…… 我真的希望永远不要发生严重的事情。但我们尽力设立了规范,告诉人们应该如何行为举止。比如我们的派对活动,我们会安排巴士把人从酒店接送到活动场地,这样大家就不用走路,尤其是喝酒的人。而且,这也很难避免,因为在会议场景中,喝酒会增加类似事情发生的概率。

我们很幸运到目前为止还没有发生过特别严重的事情,但这种情况的存在不仅仅关乎实际事件,还关乎人们的感知。比如听到某些女性在会议上被问到 “你在哪个赞助商的展位工作?” 这让我很抓狂。她们为什么不能是工程师?我搞不懂。难道第一反应不是这些人是参会者吗?

Brian Ketelsen: 对了,我现在就去安排这期节目。我正在 Trello 上记录下来。

Carlisia Thompson: 那就做吧。

Brian Ketelsen: 所以,如果你想参与这期节目,可以通过 Twitter 或邮件联系我,@bketelson 或 bketelson@gopheracademy.com。

Erik St. Martin: 很棒。接下来,我想是时候进入今天的第二个赞助广告了。今天的第二个赞助商是 Backtrace。

**广告暂停:

Erik St. Martin: 好了,我们回来了。我们正在和 Travis Jeffery 聊天…… 刚刚我们讨论了一些 Go 的项目和新闻。有没有其他有趣的文章或项目是你们最近遇到的?或者我们要聊一下 #FreeSoftwareFriday 的内容?

Brian Ketelsen: 哦,天哪…… 让我看看我的 GitHub 星标项目。我好像漏掉了一个很重要的东西,我忘记了。

Erik St. Martin: 我感觉这周早些时候我在我们的频道里发过什么东西,但现在完全想不起来了。

Travis Jeffery: 不知道你们有没有提到这个项目,叫做 gops,这是 Google 的另一个项目。它是一个命令行工具,用于列出并诊断当前系统中运行的 Go 进程。

Erik St. Martin: 对,JBD 在开发这个项目,是吧?

Brian Ketelsen: 是的。

Erik St. Martin: 这很酷…… 我们似乎确定了一点,你需要把它编译进你的项目中,才能检查项目中的运行情况,但确实是个很不错的工具。

Brian Ketelsen: 还有一点需要提及,我们正在录制这期节目,现在是 1 月 19 日。GopherCon 的 CFP(Call for Proposals,提案征集)将在 1 月 31 日截止。如果你想为 GopherCon 提交演讲提案,时间快到了。相信我,你一定要提交提案。亲爱的 GoTime FM 听众,你一定有一些值得和 Go 社区分享的内容,而我们也很想听到。

Carlisia Thompson: 绝对的。

Erik St. Martin: 顺便说一下,大家总是拖到最后再提交提案。这真的很疯狂---我们大概有三分之二的提案都是在最后 48 小时提交的。所以,如果你早点提交,审稿人会有时间去审阅你的提案。如果需要反馈,比如我们不理解你的提案,或者你没有提供足够的细节帮助我们判断,我们会回复你,要求补充更多细节,或者重新组织表达方式。

但如果你拖到最后 48 小时再提交,就没有时间收到反馈来改进提案了。另外,Dave Cheney 在 Gopher Academy 的博客上写了一篇文章,提供了一些关于如何写好提案的建议。

我觉得这部分内容可能容易被误解。大家可能觉得提案必须非常复杂、技术性极高。我记不清具体的表述了,但大致意思是我们收到很多只有一两句话的提案。审稿人不知道你是谁,他们只能根据你在提案中写的内容来判断。所以我们建议你写得尽可能详细,让我们能判断你的专业水平,或者你是否能够在规定时间内条理清晰地展示你的内容,而不是东一榔头西一棒槌。

如果你写的是“我想讨论 Go 的日志功能”,然后这就是你的整个提案,那审稿人会很难下决定。日志可能是一个大家非常感兴趣的主题,但我们无法判断你对这个话题的了解程度,也不知道你打算如何展开讨论。听众会带着问题离开,还是会有所收获?这是关键。而我们收到太多只有一两句话的提案了。

Carlisia Thompson: 我打算比 Dave Cheney 更进一步,写一篇关于“不要怎么做”的博客文章。 [笑声]

Brian Ketelsen: 这是个好主意。

Carlisia Thompson: 也许会更有效。另外,如果你的提案中连 Go 都没有提到,即使它非常详细,我们也不知道是不是应该接受它,因为我们不知道你是否会讨论 Go。所以至少在提案中应该提到 Go。

Brian Ketelsen: 对了,澄清一点…… 审稿人看不到你的身份信息,所以在你的提案中也不要提到你是谁。但同时,你需要让我们能够判断你对这个主题的了解程度。这是一个微妙的平衡---我们不能知道你是谁,这确保了审稿过程的匿名性,但你仍然需要通过提案让我们相信你对主题很熟悉。

Erik St. Martin: 是的,我觉得可能这也是让大家困惑的地方---如何在不透露身份的情况下证明自己的能力?其实我们并不是看你的资历…… 如果你的提案构思清晰,有一个好的前提,明确说明听众能从中学到什么以及你计划如何展开讨论,比如你会讨论这个话题,那些内容…… 如果你能估计每个子主题的时间分配,那就更好了。这种提案分解得越详细,就越能看出你对主题的理解和你的演讲计划。

这才是我们判断一个提案是否合格的标准,而不是“我在这个会议、那个会议上演讲过,这里有相关链接。” 我们并不是关注这些,因为如果你对内容非常熟悉,给出一个优秀且吸引人的演讲是相对容易的。

Brian Ketelsen: 在换话题之前再补充一点:所有被接受的演讲者都会分配一位导师。所以即使你从未演讲过,但觉得是时候站上舞台展示自己了,我们会为你安排一位有经验的演讲者,全程指导你,确保你在登台时充满信心,并呈现出你能做到的最好演讲。所以不要害羞,也不要害怕。

Erik St. Martin: 我、Brian 和 Dave 经常在会议期间熬夜,在酒店房间里听大家的试讲。我们致力于帮助演讲者准备好演讲并在舞台上感到舒适。还有一点需要提到的是,很多人不提交提案是因为担心费用问题,比如怎么支付差旅费。很多会议可能只提供门票,参会者需要依靠雇主赞助。但我们会为演讲者支付酒店、机票和所有费用,所以不要因为无法承担差旅费用而放弃提交提案,我们会为你解决这部分问题。

Brian Ketelsen: 刚刚那段简直像是 GopherCon 的宣传片。

Erik St. Martin: 是的,对吧?

Brian Ketelsen: 我们最好赶紧进入 #FreeSoftwareFriday 环节了。

Erik St. Martin: 这是一个很重要的活动,真的很棒能看到人们站上舞台。我希望尽可能多的人能抓住这个机会。我觉得这不会让任何人吃亏。

Carlisia Thompson: 还有一件事,GopherCon 不仅接受主题演讲和普通的技术演讲,也接受教程和工作坊的提案。如果你觉得自己不能做一个技术演讲,也许可以通过工作坊来教授一些东西。可能会更轻松些。

Brian Ketelsen: 是的,我们接受三种不同类型的提案。我们有全体会议的演讲,时长是 25 分钟,在主要舞台上进行;我们有教程,时长是 45 分钟,安排在下午的分会场;还有工作坊,是整个一天的课程,在大会前一天举办。所以无论你想教授什么内容,都有机会参与到 GopherCon 中来。

Erik St. Martin: 很棒。Casey,我们应该在 GoTime FM 的 Slack 频道里发一条消息,类似“想参加 GopherCon却没钱?提交一个演讲提案吧!” [笑声]

Carlisia Thompson: 完全可以,为什么不呢?

Erik St. Martin: 根据以往的经验,我觉得你会更紧张,因为你会花更多时间担忧自己的演讲,而不是享受会议本身。

Carlisia Thompson: 但我觉得这总是这样的,对吧?至少对我来说,如果我要演讲的话。

Erik St. Martin: 如果你是 Brandon Philips(来自 CoreOS),你会一直待着工作,直到有人拍你的肩膀告诉你该上台了为止。 [笑] 我从没见过有人在演讲前如此冷静。

好了,进入 #FreeSoftwareFriday 环节…… 我知道我们时间紧张,因为 Carlisia 有个硬性的结束时间。

Brian Ketelsen: 那你先来吧,Carlisia?

Carlisia Thompson: 好,那我先来。我想向 Peter Bourgon 和他的 oklog 库 致敬---这是一个分布式且无需协调的日志管理系统。看起来这个项目投入了大量工作。如果你需要一个日志管理系统,我觉得这个项目很值得试用。

Brian Ketelsen: 看起来很厉害。

Carlisia Thompson: 确实非常厉害。

Brian Ketelsen: 他写的博客文章也很棒,宣布这个项目时写得很好。

Carlisia Thompson: 而且它有非常详尽的设计文档。

Erik St. Martin: 我有点失望…… Brian,你总是为我收集一堆很酷的东西,但这次你没发给我。

Brian Ketelsen: 哦,是我的错。我最近太忙了。

Erik St. Martin: 忙?那是什么东西?

Brian Ketelsen: 对吧?

Carlisia Thompson: 还有件有趣的事,我记得大概三个月前(最多四个月),他在 Twitter 上问是否有类似 Prometheus 的日志工具。也就是说,他是在那之后才开发的这个项目。所以…… 我完全不明白他怎么能在这么短的时间里搞定这么复杂的东西。

Brian Ketelsen: 他得到了些帮助。他们从 GoKit 的一些概念入手,所以这肯定不是 Peter 一个星期就搞定的。我觉得 Chris Heinz 和其他几个人也深度参与了。不过它看起来确实很棒,我绝对不是在贬低他们为此付出的努力。

Erik,你这周有没有找到什么不错的东西,适合 #FreeSoftwareFriday 分享的?

Erik St. Martin: 有的。这是一个和硬件有关的项目,叫做 OpenOCD(Open On-Chip Debugger),它是一个开源软件,用于 SWD 和 JTAG 调试芯片。

Brian Ketelsen: 我只听懂了“blah-blah-blah…” [笑声] “JTAG-什么什么特种部队…”,我听不懂。

Erik St. Martin: 想象一下硬件版的 GDB(调试工具)。它可以让你将 GDB 连接到一个微控制器上,调试正在运行的代码。JTAG 的工作原理稍微复杂些,但它也能完成类似的事情。

Brian Ketelsen: 很棒,很酷。Travis,你有没有什么想分享的东西,适合 #FreeSoftwareFriday?

Travis Jeffery: 有,我想分享 Redis 和 Salvatore Sanfilippo---一个已经存在很久的项目。我记得它是在 2009 年发布的,到现在还和刚发布时一样有用且让人耳目一新。我用它已经很久了,它有非常多的使用场景…… 有时候人们认为它只是一个键值存储,但它其实是一个数据结构服务。如果你有多个服务需要使用同一个集合之类的东西,它可以处理很多事情。我甚至用它做过一个时间序列数据库,真的很酷。

他最近还写了我最喜欢的一篇关于版本发布的博客文章。我念一段:“Redis 4.0 第一个候选版本发布了。虽然它还不稳定,但很快就会稳定,并带来一长串能让 Redis 对我们用户更有用的功能。终于,Redis 4.0 候选版来了,而且敢于自称 4.0 而不是 3.4。对我来说,语义化版本控制并不重要。我更喜欢用版本号变化来传递新版本的信息。在这个具体案例中,4.0 意味着这是最棒的版本。”

Brian Ketelsen: [笑] 最棒的?

Travis Jeffery: 是的,没错。我就是喜欢这个表达,Redis 太棒了。

Brian Ketelsen: 太棒了。我无法想象没有 Redis 的世界。它已经存在很久了,但依然快得让人惊叹。真的很棒的东西。

Travis Jeffery: 最近他们还新增了模块支持。我觉得 Salvatore 甚至创建了一个模块,在 Redis 中实现了一个神经网络。

Brian Ketelsen: 哇哦…

Travis Jeffery: 太酷了。我觉得模块支持会催生出更多很酷的东西。

Brian Ketelsen: 整个项目是一个优秀的 C 代码学习案例。我不是一个 C 开发者,但这是写得很好的 C 代码,也是经过良好测试的 C 代码。如果你想学 C,这绝对是一个好地方。

Erik St. Martin: 是的,我有几年没用 Redis 了。很有趣,因为我们以前一直用它,但后来就不怎么用了。

Brian Ketelsen: 是啊,因为我们找到了 Kafka。 [笑声] 为那个螺丝找到了更大的锤子。[笑声] 好了,我这周的 #FreeSoftwareFriday 是一个我之前提到过的项目,但我这周用得特别多,再次让我感到开心,那就是 goa/gorma。它允许你用 DSL 设计 API,然后生成 API 和数据存储层。今天它让我感到很愉快…… 谢谢你,goa。

Erik St. Martin: 它和 Buffalo 如何结合使用?你是把它们结合起来,还是分别用于不同的部分?

Brian Ketelsen: 我还没有把它们结合起来,不过这周做 goa 项目时,我确实想过它们如何能很好地结合在一起。所以也许将来会有这样的东西。Goa 非常专注于 API 层,而 Buffalo 非常专注于网站,虽然它也可以做不错的 API。但 Buffalo 没有设计优先的概念,所以我觉得它们是可以结合的,只是需要一些时间来思考如何实现。

Erik St. Martin: Todd 在叫我,他说我一边回复 Twitter 一边聊天。我就这么厉害。 [笑声]

Carlisia Thompson: 我得先告辞了。Travis,非常感谢你。

Travis Jeffery: 谢谢,很高兴和你们聊天。

Erik St. Martin: 再见,Carlisia。

Carlisia Thompson: 回头聊,再见。

Brian Ketelsen: 谢谢你,Carlisia。

Erik St. Martin: 我只差两分钟就赶上了。我心想,“就差一点!”

Brian Ketelsen: 不过我们的时间安排还不错。

Erik St. Martin: 是的,我其实在看我的计时器…… 可能是我比整点晚了两分钟开始计时…… 不过这还挺有趣的。他(Todd)说我让我的兄弟来管 Twitter 账号。 [笑]

Brian Ketelsen: 很可能是真的。很少有人会发现区别。

Erik St. Martin: 不…… 就连在会议上,也很少有人能看出区别。

Travis Jeffery: 其实我很好奇…… 你们有多少人会在做 Web 的时候用 Go 的框架,而不是直接用标准库?

Erik St. Martin: 这取决于我在做什么。Brian 最近用框架和代码生成的东西比我多。我最近写了很多出站服务相关的东西,所以还没太需要用到框架。最近我主要在做的两个组件是与 Kubernetes 集群交互的东西和一个 Docker socket 的中间件。

Brian Ketelsen: 从我的角度来看,我从纯粹的 NET HTTP 到 Revel(我最初学 Go 时用过的框架)再到中间的各种方案都用过。对我来说,我一直在寻找一种 Rails 的开发体验,但又没有 Rails 的那种“魔法”。Go Buffalo 绝对让我重新找回了这种感觉,我对 Buffalo 超级兴奋。它在一组小型库(比如 Gorilla Mux 和 Gorilla Sessions)上套了一层很薄的封装。代码量不大,但它有生成器(generators),有类似 Rake 的概念(在 Buffalo 中叫 Grift)…… 它让写 Web 应用变得更简单、更快。

新的 Gopher Academy 网站是用 Buffalo 写的,新的 GopherCon 网站也是,我还用它做了其他几个项目。它非常快,而且每天都在变得更好。

Travis Jeffery: 听起来不错,我得去看看。我一直是标准库的支持者;Gorilla 的库真的很棒。基本上,我会根据需要加入这些库或其他工具。

Erik St. Martin: 我也喜欢用标准库,但当有很多端点需要处理时…… 比如你要为一个完整的管理界面构建很多端点,这种时候会感觉有点重复,而且会有一些共享逻辑,比如认证和授权…… 这些时候就会觉得,如果有一种更好的方法来把所有东西串起来会很好。但过去一年里我没怎么写 API 代码,所以没有遇到这些问题。

Brian Ketelsen: 我想说,那是因为所有的 API 和 Web 开发都是我写的,Kubernetes 小子。

Erik St. Martin: [笑声] 我这边也有自己的痛点。

Brian Ketelsen: 绝对会有。

Erik St. Martin: 你有没有听说过我必须对 Docker 进行中间人攻击?

Brian Ketelsen: 我听到了,我感到你的痛苦,这听起来太糟糕了。

Erik St. Martin: 其实还挺有趣的。麻烦的部分是它会升级 socket。我当时想着,“太棒了,我可以直接用 HTTP 反向代理,然后给它一些 socket 的知识。”但是完全没用,因为它在升级后会直接通过 TCP 通信,而不再使用 HTTP,尤其是像交互式终端这样的功能。不过,我拼凑了一些东西……它现在可以用了,很酷。

Brian Ketelsen: 我很想看看那段代码,因为不久前我在做基于 Docker 的网页终端时,也遇到了类似的 websocket 升级问题。当时我试图将网页终端的 STDIN 和 STDOUT 直接连接到运行 shell 的 Docker 容器,但当中有一个升级阶段,我当时就想,“哦,真是糟心!”

Erik St. Martin: 是啊…… 其实还挺酷的,因为你可以基本上把两个连接直接管道化。但没关系,我可以帮你搞定。

Brian Ketelsen: 我请你喝杯啤酒。

Erik St. Martin: 看来我也欠 Brian Downes 一杯啤酒。还记得我们开玩笑说如果有人 cosplay 成戴帽子的 Bill Kennedy 会怎么样吗?

Brian Ketelsen: 当然记得!

Erik St. Martin: ……但我竟然没看到那张照片---他确实穿戴得像 Bill Kennedy 的帽子,还留了 Dave Cheney 那样的胡子,而我错过了。

Brian Ketelsen: 天啊,不会吧!

Erik St. Martin: 所以我欠别人一杯啤酒。希望他们能出现在下次 GopherCon 上。

Brian Ketelsen: 太棒了。

Erik St. Martin: 或许我们可以邀请他一起吃晚餐。

Brian Ketelsen: 这是个好主意。

Erik St. Martin: 我们其实有个传统…… 现在有点晚了,大部分人可能不知道---每年 GopherCon,我们都会请第一个购票的人去吃一顿非常棒的晚餐。所以明年你也许可以试试抢第一张票。

Brian Ketelsen: 是的,这一直都挺有趣的。我们甚至有些人会守在购票页面上,就为了获得这个荣誉。

Erik St. Martin: 是挺有意思的。好吧…… 在结束节目之前,有人还有什么想聊的吗?虽然我们已经进入“节目后环节”了……

Brian Ketelsen: 是啊,自从 Carlisia 离开后,节目就变得随意多了。 [笑声]

Travis Jeffery: 你们想聊聊 Go 开发者讨论的标准日志接口吗?

Brian Ketelsen: 你是说那个我发起的讨论吗?

Travis Jeffery: 应该是吧…… 好像是别人发起的,但他们是因为看到你的推文才开始的。

Brian Ketelsen: 是的,Peter 因为我的推文开始了这个讨论。几天前,我在 Twitter 上建议,如果我们能有一个统一的日志接口会很好。

Travis Jeffery: 是的…… 是的!!!

Brian Ketelsen: 我认为 Go 中的最大错误之一---其实也没多少错误,因为 Go 是一个非常优秀的语言---但我觉得日志包是一个具体实现而不是接口,这是个错误。

Travis Jeffery: 没错,这样就太棒了…… 因为每个人都有自己的日志实现,这就变得一团糟了……

Brian Ketelsen: 是啊,真的很混乱。

Travis Jeffery: 我喜欢这个想法。

Brian Ketelsen: 所以,不管你是否认为库应该负责日志记录---这是另一个话题---许多 Go 库确实在记录日志,尤其是任何与 Kubernetes 相关的库,它们使用 glog(Google 的日志库),当你混合使用这些不同的库时就会很疯狂。如果我在使用一个库,我只是想传入一个我实例化的日志记录器,然后它能正常工作,这就太好了。

Erik St. Martin: 嗯,其实你可以通过全局变量设置日志记录器的位置。

Brian Ketelsen: 但前提是他们没有用一些奇怪的东西……

Erik St. Martin: 是的,没错。

Brian Ketelsen: 有些日志包不允许你覆盖日志输出,这真的很令人沮丧。有一次我还 fork 了一个包---我甚至不记得是哪一个了---只是为了添加获取日志记录器的能力,这样你可以将输出更改为标准日志记录器。简直荒谬。

所以我在 Twitter 上建议我们需要一个日志包的标准接口,显然,我们有这么多日志包的原因是 Go 的日志实现没有日志级别,也没有结构化日志。我想几乎每个人都会同意这两点---其他日志包基本都有这些功能的某种组合。

一个能够涵盖日志级别和结构化日志的接口,如果能放进标准库(这是我最大的主张),就不会浪费时间了---它会让我们可以插入任何我们喜欢的日志库,比如 Logrus、Log15 或 Go kit,它们都能正常工作。这就是我想要的---让一切都能正常运行。

Travis Jeffery: 是的,那会太棒了。

Brian Ketelsen: Java 早就有了,比如 Log4j。

Travis Jeffery: 啊,Java……

Brian Ketelsen: 所以我们开始了这个讨论,很多人参与了进来,但我们还要看看它会发展到什么程度。甚至有很多 Google 内部的人对这个话题感兴趣,所以我希望我们能取得一些进展,达成一个最小化的接口,让大多数人满意,并且可以推广为一个大家都能遵守的标准。这样一来,Logrus 和 Log15 就可以实现这个接口,然后我们就可以开始向我们喜欢的库发送 pull request,让它们支持这个日志接口。这会让我很开心。

Erik St. Martin: 我觉得这也是一种依赖性的问题,这种事情有一个缺点,就是某些东西是由所谓的“仁慈的独裁者”来引导的。虽然这带来了很多好处,但也会有一些局限性。关于日志记录---谁知道他们内部用的是什么日志?要考虑所有人对日志的不同需求是很难的。

在 Google 的规模下,日志可能没那么重要;可能更多的是指标数据,以及异常检测之类的东西。日志可能只是调试阶段才会打开的东西,仅此而已…… 因为我不想知道 Google 网站生成了多少日志数据。那一定会多到让整个互联网瘫痪。

Brian Ketelsen: 是啊。不过关于这个话题很棒的一点是,Google 的人甚至在讨论一些潜在的编译器改进,以降低日志操作的分配成本和类似问题。

Erik St. Martin: 很棒。

Brian Ketelsen: ……所以这方面确实有很好的参与,让日志记录变得快速且无痛。我很期待它取得一些实质性的进展。

Erik St. Martin: 我觉得很多人没有意识到 Go 团队在很多事情上对社区的参与程度;他们会帮助 Go 的大用户,或者在某些方面做出改变,让他们的软件运行得更好。

Travis Jeffery: 最酷的事情之一是,当他们讨论 Go 的依赖问题时,他们邀请了那些在做 Go Vendor 和 godeps 的人来参与讨论---这真的很酷。

Erik St. Martin: 是的,绝对是。所以我觉得我们已经超时 15 分钟左右了,可能该结束节目了,否则 Adam 会因为等我们而抓狂。

Brian Ketelsen: 不过我们今天确实聊遍了互联网的各个角落,挺不错的。

Erik St. Martin: 如果我们都关掉 Slack,不看他的信息,然后继续聊下去,你觉得他会等多久才挂断电话? [笑声]

Brian Ketelsen: 因为我们看不到他在说“停!停!停!我们已经超时了!” “哦,抱歉,我没看到。这是广播节目。” [笑声]

Erik St. Martin: 好吧,最后,我想感谢今天参加节目的每一位,尤其是你,Travis,还有已经提前告别的 Carlisia。

感谢所有正在收听直播的听众,以及之后会听录音的听众。特别感谢我们的赞助商 StackImpact 和 Backtrace。

如果你还没有关注我们,我们是 GoTime.fm,你可以注册;我们迟早会开始发送我们的每周邮件。我们在 Twitter 上是 @GoTimeFM。如果你想上节目、对节目主题有建议或者想推荐嘉宾,可以访问 github.com/GoTimeFM/ping。就这样,再见啦,大家!我们下周见。

Brian Ketelsen: 再见!谢谢你,Travis。

Travis Jeffery: 谢谢邀请我来。

相关文章:

Go, Jocko, Kafka

本篇内容是根据2016年8月份# 31. Go, Jocko, Kafka 音频录制内容的整理与翻译 Travis Jeffery 参加了节目,谈论 Go、Jocko、Kafka、Kafka 的存储内部结构如何工作,以及有趣的 Go 项目和新闻。 Erik St. Martin: 大家好,欢迎回到《GoTime》的另…...

CANoe 报文仿真

文章目录 一、单个/少数报文仿真1、Canoe 发送报文2、可以自定义该报文发送节点3、添加报文4、触发方式 二、ECU节点仿真1、导入DBC,添加节点2. 选择节点中的哪些报文可以发送3. 更新ECU 节点发送的报文数据 三、开始仿真激活/失效该 ECU节点 一、单个/少数报文仿真…...

升级thinkphp8最新版本,升级后发现版本不变

升级thinkphp8.0.3最新版本8.1.1,升级后发现版本不变, 更新TP有两个方法 1 全部更新(所有插件都一起更新) composer update 2 只更新TP框架核心 composer update topthink/framework 造成可能有两个原因,一是缓存问题,二是更新…...

工业大数据分析算法实战-day07

文章目录 day07概率图模型朴素贝叶斯(Naive Bayes)贝叶斯网络(Bayesian Network)一般图模型生成式和判别式模型图模型结构与模型推理 集成学习Boosting算法Stacking算法 day07 今天是第七天,昨日主要针对是第三章节中…...

六、nginx负载均衡

负载均衡:将四层或者七层的请求分配到多台后端的服务器上。 从而分担整个业务的负载。提高系统的稳定性,也可以提高高可用(备灾,其中一台后端服务器如果发生故障不影响整体业务). 负载均衡的算法 round robin 轮询 r…...

鸿蒙项目云捐助第十一讲鸿蒙App应用的捐助成功自定义对话框组件实现

在生活中,用户做了一个好事后,很多场合都会收到一份感谢。在捐助的行业也是一样的,用户捐出了一片爱心,就会收获一份温情。这里的温情是通过自定义对话框实现的。 一、通过自定义对话框组件实现捐款成功的信息页 这里用户捐款成…...

华为云联合中国信通院发布首个云计算智能化可观测性能力成熟度模型标准

2024年12月3日,由全球数字经济大会组委会主办,中国信息通信研究院(以下简称“中国信通院”)、中国通信企业协会承办的2024全球数字经济大会云AI计算国际合作论坛在北京成功召开。本次会议中,华为云联合中国信通院等单位…...

如何评估呼叫中心大模型呼出机器人的使用效果?

如何评估呼叫中心大模型呼出机器人的使用效果? 原作者:开源呼叫中心FreeIPCC,其Github:https://github.com/lihaiya/freeipcc 评估呼叫中心大模型呼出机器人的使用效果是一个复杂而多维的过程,需要综合考虑多个方面&…...

ARM/Linux嵌入式面经(六一):联合汽车电子

1、自我介绍 2、介绍一下 ARM与RISCV的差异 在嵌入式系统领域,ARM与RISC-V是两种重要的指令集架构(ISA),它们各自具有独特的特点和优势。以下是对两者差异的详细介绍: ARM与RISC-V的差异 开源性与专有性: ARM:ARM架构是商业化的,任何想要使用ARM指令集或相关技术的设…...

unity 雷达

unity 雷达 首先去商店下载TouchScript插件 导入的时候勾选Enable TUIO 然后把预制体Cursors和TouchManager拖上 最后把TuioInput这个脚本挂上 脚本上的端口号尽量不改...

单元测试知识总结

我们希望每段代码都是自测试的,每次改动之后,都能自动发现对现有功能的影响。 1 测试要求 在对软件单元进行动态测试之前,应对软件单元的源代码进行静态测试; 应建立测试软件单元的环境,如数据准备、桩模块、模拟器…...

Android:使用Service处理息屏后的WebSocket的服务端推送消息并传递给前端

前言 之前我们在使 RESTful 访问服务端时,一般都是客户端请求服务端应答的方式,这种通讯方式,对于需要持续获取数据的情形都是采用轮询的方式,但是这种方式对两边的性能消耗很大,特别是服务端的压力很大。现在当我们使…...

Git Bash Here 中文显示乱码的处理方法

在使用"open Git Bash Here"时,遇到中文显示乱码问题。 原因:通常是由于编码设置不正确导致的。 open Git Bash Here —>鼠标右击空白处,点击「选项」|或「Options」 在「文本」或 「Text」选项卡中,找到"local…...

FreeBSD安装教程

FreeBSD 是一个功能强大且可靠的开源 UNIX 操作系统,适合服务器和桌面环境。本文将介绍如何安装 FreeBSD,从系统准备到基础设置,为你快速上手提供帮助。 一、准备工作 1. 硬件要求 CPU:支持 x86 或 AMD64 架构的处理器。 内存&a…...

Loki 各模式简介

目录 Loki 部署模式 单片模式 简单可扩展 微服务模式 Loki 部署模式 Loki 是一个由许多微服务组成的分布式系统。它还具有独特的构建模型,其中所有这些微服务都存在于同一个二进制文件中。 您可以使用命令行标志配置单个二进制文件的行为-target,以指…...

MySQL八股-全局锁,表级锁,表锁,元数据锁,意向锁,行级锁,行锁,间隙锁,临键

文章目录 全局锁表级锁表锁(表级锁)元数据锁(MDL,Meta Data Lock,表级锁)元数据锁演示元数据锁兼容的情况元数据锁互相阻塞的情况 意向锁(Intention lock,表级锁)意向锁分类意向锁演示:意向共享锁(**IS**)与…...

(四)Spring Cloud Alibaba 2023.x:高效构建 Gateway 网关服务

目录 前言 准备 项目集成 pom.xml引入依赖 启动类 yml文件添加网关配置 修改消费者FeignService类 结果验证 前言 Spring cloud alibaba 体系中构建微服务,我们使用Spring Cloud Gateway 作为服务网关, Gateway是Spring 官方推出的一款基于 Web…...

Android XR 是什么?解释它的功能、设备、开发工具等

什么是“Android XR”? Android XR是最新配备AI的OS(操作系统),兼容耳机和眼镜(AR眼镜)。 沉浸式剧场 从视频列表中选择... 您可以体验完全身临其境的视频观看体验。 无限工作空间 您的现实世界将成为您…...

【算法】实体关系抽取

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...

Codeforces Round 993 (Div. 4)题解

A. Easy Problem 思路&#xff1a;经过看了一眼&#xff0c;我们发现&#xff0c;ab的和一定是n&#xff0c;且两个都是正整数&#xff0c; 所以a的范围就是从1~n-1 所以输出n-1即可 #include<bits/stdc.h> using namespace std; #define int long long int t; int n…...

【计算机网络】期末考试预习复习|中

作业讲解 转发器、网桥、路由器和网关(4-6) 作为中间设备&#xff0c;转发器、网桥、路由器和网关有何区别&#xff1f; (1) 物理层使用的中间设备叫做转发器(repeater)。 (2) 数据链路层使用的中间设备叫做网桥或桥接器(bridge)。 (3) 网络层使用的中间设备叫做路…...

从零用java实现 小红书 springboot vue uniapp (4)个人主页优化

前言 移动端演示 http://8.146.211.120:8081/#/ 前面的文章我们基本完成了详情页开发 今天我们具体的去进行实现个人中心 并且分享我开发时遇到的问题 首先先看效果 我们对布局整体规划一下 个人名片 半透明背景 刚开始我用的是 <view style"background-image: ur…...

为“行车大脑”降温:Simdroid-EC助力汽车ECU设计研发

ECU&#xff08;Electronic Control Unit&#xff0c;电子控制单元&#xff09;被誉为汽车的行车大脑&#xff0c;在工作时会产生大量的热量&#xff0c;而其散热存在以下难题&#xff1a;一是工作环境恶劣&#xff0c;ECU常处于高温环境中&#xff1b;二是ECU所处的空间较为狭…...

视频汇聚平台:Liveweb视频流媒体平台视频监控系统解决方案

数字化技术在安防领域的广泛应用已经成为公安等重要执法部门的重要趋势&#xff0c;主要得益于无线网络通信技术和计算机技术的快速进步。传统的视频监控系统存在诸多局限&#xff0c;例如只能进行现场监视&#xff0c;报警信息传输简单&#xff0c;无法远距离传输视频信号&…...

通过解调使用正则化相位跟踪技术进行相位解包裹

1. 绪论 光学计量学通常使用光学干涉仪来测量各种物理量。1,2 根据应用的不同&#xff0c;可以使用多种类型的干涉仪&#xff0c;但它们的共同目标是产生一个由被测物理量调制的条纹图案。使用这种光束编码程序可以检测到的物理量范围非常广&#xff1a;深度测量、应变分析、温…...

VMware替代 | 双一流大学采用ZStack ZSphere虚拟化平台加速医学应用算法分析

某双一流大学医学部在面对日益增长的医学应用算法分析需求时&#xff0c;选择采用ZStack ZSphere虚拟化平台&#xff0c;以满足其高性能计算和GPU业务应用的迫切需求。该平台凭借其轻量化、卓越性能及易用性&#xff0c;成功解决了医学部在虚拟化及GPU应用场景中的挑战。随着平…...

UNIAPP框架uView初步集成与开发设计

uView UI&#xff0c;是uni-app生态最优秀的UI框架&#xff0c;全面的组件和便捷的工具会让您信手拈来&#xff0c;如鱼得水。本文章分享UNIAPP集成使用uView页面动态开发设计。 一、使用HBuilder X 直接导入插件&#xff0c;下载后重启 uView - DCloud 插件市场 二、配置样…...

C05S08-LVS负载均衡

一、LVS 1. LVS概述 LVS&#xff08;Linux Virtual Server、Linux虚拟服务&#xff09;是一种基于Linux系统集群的负载均衡方案&#xff0c;属于四层的负载均衡。 集群&#xff1a;将相同组件部署在不同的服务器上&#xff0c;提供统一的服务&#xff0c;以及同样的功能&…...

C 语言代码诗韵:数字功能的雅集华章

函数基本操作练习 主要内容&#xff1a; 本任务主要练习函数的申请、定义、调用等&#xff0c;主要包含以下功能&#xff1a; 1&#xff09;编写函数&#xff0c;输入一个整数&#xff0c;求各个数字之和&#xff1b; 2&#xff09;编写函数&#xff0c;计算1&#xff01;2&…...

ps案例制作

宣传海报 暖色调海报商品展示图...