10 1

Go 内嵌静态资源

使用 Go 开发应用的时候,有时会遇到需要读取静态资源的情况。比如开发 Web 应用,程序需要加载模板文件生成输出的 HTML。在程序部署的时候,除了发布应用可执行文件外,还需要发布依赖的静态资源文件。这给发布过程添加了一些麻烦。既然发布单独一个可执行文件是非常简单的操作,就有人会想办法把静态资源文件打包进 Go 的程序文件中。下面就来看一些解决方案:

go-bindata

go-bindata 是目前我的程序 pugo 在用的嵌入静态资源的工具。它可以把静态文件嵌入到一个 go 文件中,并提供一些操作方法。

安装 go-bindata

go get -u github.com/jteeuwen/go-bindata/...

注意 go get 地址最后的三个点 ...。这样会分析所有子目录并下载依赖编译子目录内容。go-bindata 的命令工具在子目录中。(还要记得把 $GOPATH/bin 加入系统 PATH)。

使用命令工具 go-bindata ( pugo 的例子):

go-bindata -o=app/asset/asset.go -pkg=asset source/... theme/... doc/source/... doc/theme/... 

-o 输出文件到 app/asset/asset.go,包名 -pkg=asset,然后是需要打包的目录,三个点包括所有子目录。这样就可以把所有相关文件打包到 asset.go 且开头是 package asset 保持和目录一致。

pugo 里释放静态文件的代码:

dirs := []string{"source", "theme", "doc"} // 设置需要释放的目录

for _, dir := range dirs {
    // 解压dir目录到当前目录
    if err := asset.RestoreAssets("./", dir); err != nil {
        isSuccess = false
        break
    }
}
if !isSuccess {
    for _, dir := range dirs {
        os.RemoveAll(filepath.Join("./", dir))
    }
}

asset.go 内的静态内容还是根据实际的目录位置索引。所以我们可以直接通过目录或者文件地址去操作。

9 24

Go 开发 HTTP 的另一个选择 fasthttp

fasthttp 是 Go 的一款不同于标准库 net/http 的 HTTP 实现。fasthttp 的性能可以达到标准库的 10 倍,说明他魔性的实现方式。主要的点在于四个方面:

  • net/http 的实现是一个连接新建一个 goroutine;fasthttp 是利用一个 worker 复用 goroutine,减轻 runtime 调度 goroutine 的压力
  • net/http 解析的请求数据很多放在 map[string]string(http.Header) 或 map[string][]string(http.Request.Form),有不必要的 []byte 到 string 的转换,是可以规避的
  • net/http 解析 HTTP 请求每次生成新的 *http.Requesthttp.ResponseWriter; fasthttp 解析 HTTP 数据到 *fasthttp.RequestCtx,然后使用 sync.Pool 复用结构实例,减少对象的数量
  • fasthttp 会延迟解析 HTTP 请求中的数据,尤其是 Body 部分。这样节省了很多不直接操作 Body 的情况的消耗

但是因为 fasthttp 的实现与标准库差距较大,所以 API 的设计完全不同。使用时既需要理解 HTTP 的处理过程,又需要注意和标准库的差别。

package main

import (
    "fmt"

    "github.com/valyala/fasthttp"
)

// RequestHandler 类型,使用 RequestCtx 传递 HTTP 的数据
func httpHandle(ctx *fasthttp.RequestCtx) {
    fmt.Fprintf(ctx, "hello fasthttp") // *RequestCtx 实现了 io.Writer
}

func main() {
    // 一定要写 httpHandle,否则会有 nil pointer 的错误,没有处理 HTTP 数据的函数
    if err := fasthttp.ListenAndServe("0.0.0.0:12345", httpHandle); err != nil {
        fmt.Println("start fasthttp fail:", err.Error())
    }
}
9 20

Go 开发 HTTP

Go 是一门新语言。很多人都是用 Go 来开发 Web 服务。Web 开发很多同学急于求成,直接使用 beego, echoiris 等知名框架。对标准库 net/http 的了解甚少。这里我就主要聊一下标准库 net/http 开发 Web 服务时的使用细节。

创建 HTTP 服务

在 Go 中,创建 HTTP 服务很简单:

package main

// in main.go

import (
    "fmt"
    "net/http"
)

func main(){
    if err := http.ListenAndServe(":12345",nil); err != nil{
        fmt.Println("start http server fail:",err)
    }
}

这样就会启动一个 HTTP 服务在端口 12345。浏览器输入 http://localhost:12345/ 就可以访问。当然从代码看出,没有给这个 HTTP 服务添加实际的处理逻辑,所有的访问都是默认的 404 Not Found

6 24

Go 语言入门资料

Go 语言,自2012年发布 1.0,至今 1.7 ,历经5年。Go 的相关工具和生态已经逐渐完善,这里综述一下 Go 语言学习开发可以找到的入门资料。

入门教程

  • 官方文档

第一步,学习基本语法和命令操作。Go 的官方文档是第一选择。但因为众所周知的原因,官网无法访问。可以访问 godoc.golangtc.com 镜像网站查看。或者下载安装好 Go 语言后执行 godoc 命令:

godoc -http=:6060

访问 http://localhost:6060 浏览内置的官网镜像站点。另外,godoc 会自动分析 GOPATH 中的源码生成文档,可以在网站访问 /pkg 直接查看。

  • 视频教程

推荐 无闻《Go 编程基础》。无闻的视频教程简单直接的介绍 Go 的基本语法的命令操作,简单的介绍一些标准库的使用方法。学好基础语法和操作是入门必需,来不得半点敷衍。实际开发实践时,自己再去深入了解使用的标准库和第三方库细节。

如果偏向 Web 方面的开发者,看完《Go 编程基础》 后可以再去学习无闻的 《Go Web 基础》 。里面以开发博客程序为例子,对 Go 语言开发 Web 的过程有比较详细的说明。但是因为已经是比较早的视频,可能所使用的类库已经发生较大的版本更新,需要自己根据库类的相关文档实践修正。

以前的