存档:

文章标签 ‘Go’
0

适用于 Go 1.0 版的 Google App Engine SDK 发布

2012年3月29日

今天凌晨 Go 项目组正式发布了 Go 编程语言、官方库和工具集的 1.0 稳定版本。同步开发的 GAE 团队很早就按捺不住,昨天下午就删除了 appengine-go 项目的全部下载,并在今天正式发布了 1.6.4 版的 Google App Engine SDK for the Go runtime

Go runtime 为常用的 App Engine 服务(Blobstore、Datastore、Memcache 等)提供了简明易用的 Go API 和直截了当的开发过程。与 Python 及 Java SDK 一样,Go 应用也可以通过开发服务器在本地测试,最方便的是,开发服务器会自动编译 Go 代码,因此测试修改后的代码只是刷新浏览器这样简单。

Go 1 SDK 还包含一些功能改进与错误修正。整个 SDK 采用了 Go 1 的 time API,还为批量操作的错误处理提供了 MultiError 数据类型,此外还支持 Datastore Cursors 及 XMPP 和 Log 服务。详情可参阅发布说明

尽管目前 Go App Engine runtime 还处于测试阶段,Go 1 所提供的语言稳定性是一项重要的里程碑。若要进一步了解 Go 1 的情况,可以参考 Go 1 发布以及 golang.org 丰富的文档。

via Google App Engine

5

Go 项目取得了历史性进展,Go 1 横空出世

2012年3月29日

2009 年 11 月 Google 宣布了它的 Go 项目,一个全新的开源编程语言。自从那时起,有 200 多名爱好者在代码、测试及帮助文档方面进行了数千次的优化。开源社区对于 Go 的成功起到了举足轻重的作用。

今天,我们很欣慰地宣布 Go 项目终于推出了一个稳定版本 Go version 1,或者简称 Go 1。Go 1 是耗时几个月进行了完善规范、优化执行、增强可移植性及重写和调整标准库之后的成果。Go 1 为日后发展提供了兼容性:使用 Go 1 标准编写的程序在几年内都可以稳定的运行即使 Go 还在不断开发着。

Google App Engine 的开发者们也可以感受到 Go 1 的好处,Go 1 现在已经是 Google App Engine 上的标准的 Go 运行环境了。

Go 1 提供了一个可靠的、可移植的、稳定的编写程序、项目的平台。如果想了解更多关于 Go 1 的内容,听听 Go 博客上  Gopher 们(Go 项目的吉祥物——地鼠)有什么要说的吧。更多关于 Go 的综合信息可以在 golang.org 找到,那里提供了帮助文档、参考文献、文章甚至还有一个互动的 Go 语言导览。

除了环游世界的其他时候,Go Gopher 平时与它的在各种瞩目的国际性比赛中获得的奖牌一起住在巴黎。他很喜欢 “The Wire” 和所有 Werner Herzog 的电影。

Via GoogleDevelopersBlog

作者: 分类: Google新闻 标签:
2

用 Google App Engine 开发 Go 语言应用的简明教程

2012年3月17日

Google 开发者计划工程师 Johan Euphrosine (proppy)近日在苏黎世联邦理工学院就 Go 语言与 Google App Engine 做了一次演讲。现在他已经将演示文稿发布出来,大家可以一起来了解下如何通过 GAE 开发 Go 语言应用。

这组幻灯片的主要内容包括:

  • 创建与部署简单的 web 应用
  • 解析 XML 数据
  • 解析 JSON 数据
  • 通过 goroutine 与 channel 实现多个数据源的并行装取

点击查看:Go + App Engine中译版。感兴趣的同学还可以试着完成课后作业

via proppy

作者: 分类: 其他新闻 标签: , , ,
0

【快乐周末】Go 语言源码可追溯到 1972 年?

2012年3月16日

Go 语言团队已经在本周三发布了第一个发布候选版 Go 1 RC1(即 Beta4),正式版的发布已经为期不远。地鼠(gopher)们该行动起来啦!

周四就有地鼠提问,“Go 源码中几十年前的那些修订是什嘛情况哦?

原来,Go 代码库的最初四次修订发生于 1972-1988 年,然后才有了 Go 语言规范的初稿

其中,第一次修订 Revision f6182e5abf5e (1972) 是 Brian Kernighan《B 语言入门教程》第七节中的“hello, world!”示例代码:

main( ) {
 extrn a, b, c;
 putchar(a); putchar(b); putchar(c); putchar('!*n');
}

a 'hell';
b 'o, w';
c 'orld';

第二次修订 Revision b66d0bf8da3e (1974) 将程序用 C 语言重写了一遍,当年 Unix 内核的主要部分已经采用 C 重新编写:

main() {
 printf("hello, world");
}

第三次修订 Revision ac3363d7e788 (1988) 按 ANSI C 草案的标准加上了 #include 语句,并补上了漏掉的换行符:

#include <stdio.h>

main()
{
        printf("hello, world\n");
}

第四次修订 Revision 172d32922e72 (1988) 则给程序加上了输入原型与返回值:

#include <stdio.h>

int
main(void)
{
        printf("hello, world\n");
        return 0;
}

(次年,标准 C89(ANSI X3.159-1989)诞生。)

这四次修订重现了编程语言由 B 到标准化的 C 的发展史,也显示了项目组的宏伟抱负。当然,Go 团队本身也是大有来头,其中就包括 B 语言与 Unix 作者 Kenneth Thompson 和 Plan 9 架构师 Rob Pike,他俩都曾在贝尔实验室工作,并共同完成了 UTF-8 编码的创立。(via cnet)在 Go 语言中,Ken Thompson 还弥补了没能在 Unix 中“拼全‘create’”的遗憾。(via mattn

Go 公布初期就提供了 cgo 命令以及 gcc 前端 gccgo,可以说 Go 本身就是对历代成果 fork 而来的项目。

敬请期待 Go 的正式发布!

作者: 分类: Google新闻, 故事/传闻 标签: ,
2

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

2011年12月15日

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

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

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

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

接下来要决定的就是选用哪款 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 的基础是背景图画:

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

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

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

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

实现

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

var (
    // 各外观元素存储位置的文件夹映射。
    dirs = map[string]string{
        "h": "img/heads",
        "b": "img/eyes_beak",
        "i": "img/index_feathers",
        "m": "img/middle_feathers",
        "r": "img/ring_feathers",
        "p": "img/pinky_feathers",
        "f": "img/feet",
        "w": "img/wing",
    }

    // urlMap 映射各 URL 字符与所对应的外观元素。
    urlMap = [...]string{"b", "h", "i", "m", "r", "p", "f", "w"}

    // layoutMap 映射各外观元素与在背景图像上的位置。
    layoutMap = map[string]image.Rectangle{
        "h": {image.Pt(109, 50), image.Pt(166, 152)},
        "i": {image.Pt(136, 21), image.Pt(180, 131)},
        "m": {image.Pt(159, 7), image.Pt(201, 126)},
        "r": {image.Pt(188, 20), image.Pt(230, 125)},
        "p": {image.Pt(216, 48), image.Pt(258, 134)},
        "f": {image.Pt(155, 176), image.Pt(243, 213)},
        "w": {image.Pt(169, 118), image.Pt(250, 197)},
        "b": {image.Pt(105, 104), image.Pt(145, 148)},
    }
)

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

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

var (
    // elements 映射各外观元素及其图像。
    elements = make(map[string][]*image.RGBA)

    // backgroundImage 含背景图像数据。
    backgroundImage *image.RGBA

    // defaultImage 是出错时返回的图像。
    defaultImage *image.RGBA

    // loadOnce 用于仅在首次请求时调用 load 函数。
    loadOnce sync.Once
)

// load 函数从磁盘读取各 PNG 图像,并存储到对应的全局变量中。
func load() {
    defaultImage = loadPNG(defaultImageFile)
    backgroundImage = loadPNG(backgroundImageFile)
    for dirKey, dir := range dirs {
        paths, err := filepath.Glob(dir + "/*.png")
        if err != nil {
            panic(err)
        }
        for _, p := range paths {
            elements[dirKey] = append(elements[dirKey], loadPNG(p))
        }
    }
}

请求按下述顺序处理:

  1. 解析请求 URL,按顺序解码出各字符的十进制值。
  2. 为背景图像创建副本,作为最终图像的基础。
  3. 在背景图像上绘制各图像元素(使用 layoutMap 判断应绘制的位置。)
  4. 将图像编码为 JPEG
  5. 将 JPEG 直接写入 HTTP 响应写入器中,将图像返回给用户。

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

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

func handler(w http.ResponseWriter, r *http.Request) {
    // Defer 函数可以从错乱中恢复。
    // 恢复时将错误情况记录到 App Engine 控制台并给用户发送默认图像。
    defer func() {
        if err := recover(); err != nil {
            c := appengine.NewContext(r)
            c.Errorf("%s", err)
            c.Errorf("%s", "Traceback: %s", r.RawURL)
            if defaultImage != nil {
                w.Header().Set("Content-type", "image/jpeg")
                jpeg.Encode(w, defaultImage, &imageQuality)
            }
        }
    }()

    // 在首次请求时从磁盘加载图像。
    loadOnce.Do(load)

    // 创建背景副本,作为绘制基础。
    bgRect := backgroundImage.Bounds()
    m := image.NewRGBA(bgRect.Dx(), bgRect.Dy())
    draw.Draw(m, m.Bounds(), backgroundImage, image.ZP, draw.Over)

    // 处理请求字串中的各个字符。
    code := strings.ToLower(r.URL.Path[len(prefix):])
    for i, p := range code {
        // 解码遇到的十六进制字符 p。
        if p < 'a' {
            // 是数字
            p = p - '0'
        } else {
            // 是字母
            p = p - 'a' + 10
        }

        t := urlMap[i]    // 按索引查找元素类型
        em := elements[t] // 按类型查找元素图像
        if p >= len(em) {
            panic(fmt.Sprintf("元素索引越界 %s: "+
                "%d >= %d", t, p, len(em)))
        }

        // 将元素绘制到 m 上
        // 使用 layoutMap 指定其位置。
        draw.Draw(m, layoutMap[t], em[p], image.ZP, draw.Over)
    }

    // 编码为 JPEG 图像并写为响应。
    w.Header().Set("Content-type", "image/jpeg")
    w.Header().Set("Cache-control", "public, max-age=259200")
    jpeg.Encode(w, m, &imageQuality)
}

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

性能

该图表从 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

作者: 分类: 故事/传闻 标签: , ,
0

Go 语言盛会 ECUG Con 2011 将于11月19-20日在上海举行

2011年11月8日

ECUG 即 Effective Cloud User Group(实效云计算用户组),关注并发模型与分布式开发的最佳实践,每年都会筹办一次全国性的 ECUG Con 大会,至今年已走过四个年头。

往届 ECUG Con 大会以 Erlang 语言为主要支撑。而从今年开始,大会预计将Go 编程语言为主,无疑是全国首场以 Go 语言为主题的盛宴

之所以有此变化,是因为我们认为,尽管 Erlang 给分布式开发带来了很好的思路,但是距离大规模应用的可能性还很远。Erlang 语言的优点和缺陷同样明显。但是 Go 语言带来了工程上大范围应用的希望。这两门语言有着相同的理念:让分布式开发更容易。Erlang 是这个领域的先河,Golang 则是集大成者。
可以说,Go 语言是近年来语言变革的最重要的里程碑(没有之一)。

——许式伟,ECUG 发起人、Q盘创始人(该站服务端约有十万行 Go 源码)

今年的 ECUG Con 2011 大会将于11月19~20日在上海举行,为期两天。与 Go 相关的议题包括:

其他精彩议题可到大会支持网站查阅。

会议地点定于上海广场长城假日酒店(恒丰路585号,近上海火车站)三楼王朝厅。感兴趣的读者可以报名参会,或到 ecug.org 进一步了解大会情况。

作者: 分类: 其他新闻 标签: ,
3

Google 放出 App Engine 1.5,支持 Go 编程语言

2011年5月11日

Google I/O 2011上,Google正式推出1.5版本的App Engine,带有很多新功能,包括:

  • Backends:允许开发者精确的控制长时间运行的程序实例。没有过期时间,可使用128M至1GB的内存
  • Pull Queues:允许开发者从queue里拉出一个task,好让应用对其进行处理,而不再需要Task Queues了
  • 默认启用High Replication Datastore:所有新应用都可默认启用HRD,价格从0.45刀降低到0.24刀
  • HTTP请求大小增加到32MB
  • Mail API改进:对Mail API做了更严格的限制。首先是邮件必须是从Google Apps或Gmail帐户发出,二是降低了应用每天可处理的收件人,从2000降低到100
  • Code Downloads:扩展了直接下载应用源代码的功能,现在创建者和上传者都可下载
  • 新的runtime:开始试验性的支持Go编程语言

 

Via Google Enterprise Blog

作者: 分类: Google新闻 标签: ,
2

Go 发布自动更新代码所用 API 的 gofix 工具

2011年4月21日

下一版本 Go 在最基础的 Go 软件包方面将包含显著的 API 变更。除非进行更新,采用新版 API,否则实现 HTTP 服务器句柄调用 net.Dial调用 os.Open使用 reflect 软件包的代码将无法编译。随着 Go 语言愈加稳定,发布频率减缓将成为常态。每周的快照版本中都会有 API 变更,部分可能能自动管理;然而,合计起来看,手动更新现有代码的工作量仍然非常得大。

Gofix 是一款减轻更新现有代码工作量的新工具。它读取源文件中的程序,查找对旧版 API 的使用,用当前 API 进行改写,并将程序写回文件。有些 API 变更未保持全部原有功能,所以 gofix 的改写有时并不完美。当无法自动改写旧版 API 时,gofix 将给出警告及文件名与所在行数,开发者可以检查并亲自重写代码。Gofix 负责处理乏味冗长的简单变更,而把真正应该注意的部分留给开发者处理。

每当 API有明显变更时 gofix 的代码都会得到更新,尽可能进行自动转换。如果用户更新到新版 Go 后代码无法编译,只需在源码目录运行一下 gofix。

例如,gofix 可以将出自 fmt/print.go 的这段代码:

switch f := value.(type) {
case *reflect.BoolValue:
    p.fmtBool(f.Get(), verb, field)
case *reflect.IntValue:
    p.fmtInt64(f.Get(), verb, field)
// ...
case reflect.ArrayOrSliceValue:
    // Byte slices are special.
    if f.Type().(reflect.ArrayOrSliceType).Elem().Kind() == reflect.Uint8 {
        // ...
    }
// ...
}

重写为采用新版 API 的代码:

switch f := value; f.Kind() {
case reflect.Bool:
    p.fmtBool(f.Bool(), verb, field)
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    p.fmtInt64(f.Int(), verb, field)
// ...
case reflect.Array, reflect.Slice:
    // Byte slices are special.
    if f.Type().Elem().Kind() == reflect.Uint8 {
        // ...
    }
// ...
}

几乎每行都有微小变更。重写的变更量大,但几乎完全机械化,可以交付计算机处理。

Gofix 的实现离不开 Go 标准库中对将 Go 源文件解析为语法树将语法树打印回为 Go 源代码的支持。 此外,Go 打印库能以官方格式(通常可以通过 gofmt 工具实现)打印程序,可让 gofix 对 Go 程序的机械性更改不造成谬误。实际上,设计 gofmt 的关键动机之一——或许仅次于避免特定花括号放置位置的争论——就是简化重写 Go 程序的工具,如 gofix 的设计。

Gofix 注定成为不可或缺的工具。Go 团队一直使用该工具更新他们自己的项目,甚至是更新 Google 内部的源码树。Gofix 允许用户修复错误或重构包 API 而无须担心转换现有代码的开销。用户也可以对 gofix 进行扩展,来支持他们自己的 API。

via The Go Programming Language Blog

作者: 分类: Google新闻 标签: , ,
2

Brad Fitzpatrick 正式参与到 Go 语言项目中

2011年4月16日

bradfitz

Brad Fitzpatrick 昨天在 Twitter 上宣布,在为 Android 项目效力一年半多后,他现在正式成为 Go 语言项目的全职“地鼠”(gopher)!

Brad Fitzpatrick布莱德·菲兹派翠克)是 LiveJournal 的创始人,还是 memcached 等诸多自由软件项目的作者,2007 年选择加入 Google。OpenIDPubSubHubbub 等项目均有他的贡献。相信 Go 会因为他的到来真正得瑟起来。

顺便补充一个 Go 团队的愚人节恶搞:

Go 语言项目在本月一日发布godoc 命令工具,彰显该项目组对文档的认真态度。且看 mikespook 的译文《Godoc:文档化 Go 代码》。

via 边江

1

Google 积极参与 Linux 基金会协作峰会 2011

2011年4月7日

google_linux

本周,第五届年度 Linux 基金会协作峰会将于 4 月 6日到 8 日在加州旧金山举办,很多 Googler 将出席峰会,其中有几位 Googler 还将发表演讲。

尽管活动仅限受邀者参加,大家仍可观看免费的演讲和小组讨论的视频直播

via Google Open Source Blog
pic via pcdigital

作者: 分类: Google新闻 标签: , , ,