从零到 Go:Google感恩节火鸡涂鸦开发纪实

来源:谷奥

本文是 Google 搜索团队软件工程师 Reinaldo Aguiar 发表在 Go 语言博客的客座文章,他分享了在一天之内完成首款 Go 程序的开发并发布给数百万受众的经历。

我最近有幸参与了一项虽小却曝光率极高的“20% 项目”——2011 年感恩节的 Google Doodle。这幅 doodle 中的火鸡由不同样式的头、翅膀、羽毛与爪子随机组合而成。用户可以通过点击火鸡的不同部位自定义组合。这种互动通过 JavaScript、CSS 实现,由浏览器实时渲染出各种火鸡。

用户制作出的个性化火鸡可以分享到 Google+ 上。点击“分享”按钮(图中未给出)即可在用户的 Google+ 流中生成一篇含有火鸡图片的帖子。要满足这种需求,图片必须是单独一张,且与用户所制作的火鸡完全相同。

由于火鸡的八个部位(头、双爪、几片羽毛等)各有 13 种样式,用户可能设计出八亿多种火鸡。预先制作好八亿多张图片显然行不通。因此,必须在服务端实时生成图片。出于即时扩展性与高度可用性的共同需求,合适的平台非常明显:Google App Engine!

从零到 Go:24 小时内登上 Google 主页的 Go 语言应用“火鸡”doodle 开发纪实

接下来要决定的就是选用哪款 App Engine runtime 了。图像处理任务极度依赖 CPU,所以这种情况下性能是决定性因素。

为确保可靠,我们首先进行了测试。我们为新版 Python 2.7 runtime(该版本提供基于 C 的图像处理库 PIL) 与 Go runtime 准备了一些等效的演示应用。各应用 分别合成几张小图片生成图像文件,编码为 JPEG,并将 JPEG 数据作为 HTTP 响应发回客户端。Python 2.7 应用处理请求的中位响应时间为 65 毫秒,而 Go 应用的中位延时仅为 32 毫秒。

因此这成为了试用 Go runtime 的大好机会。

此前我对 Go 语言毫无经验,而时间又很紧:两天内达到生产需求。虽然紧张,我还是将它视作从另一常被忽略的方面——开发速度——测试 Go 的机会。完全没有 Go 语言开发经验的人能在多快的时间内掌握并开发出高性能高扩展性的应用?

设计

基本步骤是在 URL 中编码火鸡各态、实时绘制并编码图像。

各 doodle 的基础是背景图画:

从零到 Go:24 小时内登上 Google 主页的 Go 语言应用“火鸡”doodle 开发纪实

有效的请求 URL 形如:http://google-turkey.appspot.com/thumb/20332620

/thumb/ 后面跟着的数字字串(十六进制)代表各外观元素要绘制的形状,如下图所示:

从零到 Go:24 小时内登上 Google 主页的 Go 语言应用“火鸡”doodle 开发纪实

程序的请求接管器解析 URL 决定各组件所选定的元素,在背景上绘制对应图像,并返回 JPEG 成品。

如果出错则返回默认图像。不必返回错误页面,因为用户不可能看到——浏览器肯定是在加载 image 标记中的 URL。

实现

在软件包层面,我们声明了一些数据结构,描述火鸡的各个元素、对应图像所在文件夹,以及各图像应绘制在背景图上的位置。

上述各点的几何位置是通过图像中各元素的实际位置而得到的。

每次请求都从磁盘加载图像是很浪费的重复行为,因此我们在收到首个请求时就将全部 106 幅图像(13×8 个元素 + 1 幅背景 + 1 幅默认图)加载到全局变量中。

请求按下述顺序处理:
1、解析请求 URL,按顺序解码出各字符的十进制值。

2、为背景图像创建副本,作为最终图像的基础。

3、在背景图像上绘制各图像元素(使用 layoutMap 判断应绘制的位置。)

4、将图像编码为 JPEG

5、将 JPEG 直接写入 HTTP 响应写入器中,将图像返回给用户。

如果出错,则将 defaultImage 返回给用户,并在 App Engine 控制台记下日志,供日后分析之用。

下面是含说明注释的请求接管器代码:

 

为简洁起见,这些代码段中我省略了一些辅助函数。完整代码请参阅源码

性能

从零到 Go:24 小时内登上 Google 主页的 Go 语言应用“火鸡”doodle 开发纪实

该图表从 App Engine 控制台截取,展示了发布后的平均请求时间。显然,即使在高负载情况下也没有超过 60 ms,中位延迟时间为 32 ms。考虑请求接管器在处理图像并实时编码,这已经相当快了。

结论

我觉得 Go 语言的语法直观、简单且洁净。我过去常与解析型语言打交道,尽管 Go 是静态录入编译型语言,编写这款应用的感觉却更像是在用动态解析型语言。

开发服务器提供了可以在程序有变动后迅速重新编译的 SDK,所以开发部署与解析型语言一样快。而且非常简单——我只花了不到一分钟就配置好了开发环境。

Go 语言优秀的文档也帮助了我迅速完成开发。文档是从源代码生成的,各函数的文档与相关联的源码直接链接。这不仅可以让开发者迅速理解特定函数的作用,还鼓励开发者深入挖掘软件包的实现,简化了对良好编程风格与规则的掌握。

编写这款应用的过程中,我只参考了三份资源:App Engine 的 Hello World Go 示例Go 软件包文档以及一篇演示 Draw 软件包的博文。感谢开发服务器的迅速部署,以及该语言自身的优异特性,我得以在 24 小时内掌握该语言,并开发出超快、满足生产需求的 doodle 生成器。

应用的完整源码(包括图像文件)可以在 Google Code 项目中下载到。

向设计该 doodle 的 Guillermo Real 与 Ryan Germick 致以特别的谢意。

原文:From zero to Go: launching on the Google homepage in 24 hours

1 1 收藏 评论

相关文章

可能感兴趣的话题



直接登录
跳到底部
返回顶部