如何在Ubuntu上使用Martini服务于Nginx服务器后面的Go应用程序

来自菜鸟教程
跳转至:导航、​搜索

状态: 已弃用

本文介绍了不再受支持的 Ubuntu 版本。 如果您当前正在运行运行 Ubuntu 12.04 的服务器,我们强烈建议您升级或迁移到受支持的 Ubuntu 版本:

原因: Ubuntu 12.04 已于 2017 年 4 月 28 日终止生命周期 (EOL) and no longer receives security patches or updates. This guide is no longer maintained.

请参阅: 本指南可能仍可用作参考,但可能不适用于其他 Ubuntu 版本。 如果可用,我们强烈建议使用为您正在使用的 Ubuntu 版本编写的指南。 您可以使用页面顶部的搜索功能来查找更新的版本。


介绍


Web 框架是很好的工具,可以减轻开发 Web 应用程序的一些痛苦。 他们经常处理一些较低级别的配置,以便让您专注于应用程序的功能和呈现。

Martini 是实现这些功能的 Go 编程语言包。 它提供路由、静态文件服务、错误处理和中间件,并与现有的 Go web 功能挂钩。 这使您可以轻松地将其插入现有的 Go 代码并简化您的工作量。

在本指南中,我们将讨论如何使用 Martini 在 Ubuntu 12.04 服务器上快速构建 Go Web 应用程序。

使用 GVM 安装 Go


虽然 Ubuntu 12.04 可以在其默认存储库中安装 Go 软件包,但 Martini 需要 Go 版本 1.1 或更高版本才能正常运行。 存储库中的版本不满足此要求。

我们将使用 Go 版本管理器 gvm 来安装最新版本的 Go,而不是从存储库安装 Go。 然而,在我们这样做之前,我们 do 需要来自存储库的一些依赖项:

sudo apt-get update
sudo apt-get install curl git mercurial make binutils bison gcc

安装好 gvm 依赖后,我们可以从项目的 GitHub 页面下载并运行 gvm 安装脚本:

bash < <(curl -s https://raw.github.com/moovweb/gvm/master/binscripts/gvm-installer)

这会将 gvm 脚本和文件安装到您的主文件夹中名为 .gvm 的隐藏目录中。 要使用 gvm 安装 Go 版本,我们首先需要获取脚本,以便我们当前的 shell 会话具有可用的脚本:

source ~/.gvm/scripts/gvm

现在 gvm 命令在我们当前的 shell 中可用,我们可以通过发出以下命令来安装 Go 版本 1.2:

gvm install go1.2

这将安装与 Martini 兼容的 Go 版本。 通过键入以下内容将其设置为默认值:

gvm use go1.2 --default

设置 Go 环境


现在我们已经安装了 Go,我们应该设置一个 Go 环境。 Go 期望以某种方式组织事物以正确构建。 它需要一个包含 bin、src 和 pkg 子目录的项目目录。

我们将在我们的主目录中创建这个结构:

cd ~
mkdir -p go/{bin,pkg,src}

现在我们必须设置我们的 Go 路径以反映这个项目目录,并将 go/bin 目录添加到我们的常规路径中,以便我们可以轻松地运行我们的 Go 程序:

export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin

您可以将这些添加到您的 .bashrc 以便在您登录时执行它们:

echo "export GOPATH=$HOME/go" >> ~/.bashrc
echo "export PATH=$PATH:$GOPATH/bin" >> ~/.bashrc

您现在应该准备好处理您的第一个 Martini 应用程序。

创建您的第一个 Martini 应用程序


您可以轻松地创建一个“Hello world”示例程序来展示 Martini 应用程序的一些品质。

我们将调用我们的程序 hello.go 并将其放在 ~/go/src 目录内的同名应用程序目录中:

cd ~/go/src
mkdir hello
nano hello/hello.go

在这个文件中,我们将从主程序的通用 Go 包声明开始。 在此之后,我们将通过列出可以获取的位置来导入 Martini 包:

package main

import "github.com/codegangsta/martini"

接下来,我们将创建我们的 main 函数,它将包含我们程序的大部分内容:

package main

import "github.com/codegangsta/martini"

func main() {

    server := martini.Classic()
    server.Get("/", func() string {

        return "<h1>Hello, world!</h1>"

    })

    server.Run()

}

让我们看看我们插入到main()函数中的代码是做什么的。

server := martini.Classic()

这一行初始化了一个名为 server 的变量,并将“Classic”对象的一个实例分配给它。 classic() 函数创建一个 Martini 实例,其中包含一些大多数应用程序将从中受益的默认值和功能。

server.Get("/", func() string {

    return "<h1>Hello, world!</h1>"

})

这部分代码设置了一个 URL 处理程序,该处理程序响应对资源“/”的 HTTP 获取请求,该资源“/”是根 URL 位置。 换句话说,当用户请求服务器的基本 IP 地址或域名时,部分代码将被执行。

该函数返回一个字符串,然后将其作为响应正文传回并呈现在用户的浏览器窗口中。

server.Run()

这一行是实际启动 Martini 服务器以侦听请求和路由流量的行。

完成后保存并关闭文件。

接下来,我们需要获取 Martini 包,以便 Go 可以运行我们刚刚键入的程序:

go get github.com/codegangsta/martini

这会将包下载到我们的路径,以便 Go 可以找到并使用此资源。

最后,我们可以通过键入以下命令来运行我们的程序:

go run hello.go

Martini 在端口 3000 上提供应用程序,因此您可以通过访问您的 IP 地址和 Web 浏览器中的端口号来访问您的应用程序:

http:// your_ip :3000

添加路由和参数


我们的“hello world”程序的第一次迭代已经完成,但是我们可以通过利用 Martini 的路由功能来改进它。

我们已经创建了一个路由,它为基本 URL 的请求提供服务。 这作为一般默认设置效果很好,但如果我们想对其进行个性化,我们需要能够从用户那里获取输入。

从用户那里获取输入的一种方法是通过 URL 本身。 我们可以将 URL 的一部分设置为参数,在设计函数的返回值时可以调用该参数。

在基本 URL 路由下方,让我们添加另一个:

. . .
server.Get("/", func() string {

    return "<h1>Hello, world!</h1>"

})

server.Get("/:who", func(args martini.Params) string {

    return "<h1>Hello " + args["who"] + "</h1>"

})
. . .

我们的新处理程序响应基本 URL 之后的任何请求,直到另一个斜线。 它不匹配特定的 URL 字符串,而是使用称为 :who 的占位符。 这个占位符是一个名为“who”的参数,它将采用用户在第一个“/”之后输入的任何值。

您还应该注意到,函数声明现在接受一个名为 args 的参数,类型为 martini.Params。 这允许我们访问将设置为用户请求的 URL 值的“谁”参数。

在处理程序内部,我们基本上有相同的返回字符串,但我们使用语法 args["who"] 访问参数。 这会将“who”的值插入到我们的字符串中。

如果我们保存并再次运行它,我们可以访问我们上次访问基本 URL 的同一页面。 但是,如果用户使用“/your_name”跟随基本 URL,我们也可以通过名称动态问候用户:

http:// your_ip :3000/彼得

我们可以通过将 URL 中的空格替换为“%20”来将多个单词串在一起:

http:// your_ip :3000/is%20a%20rather%20fine%20greeting

如何通过 Nginx 代理您的应用程序


尽管 Martini 服务器是为应用程序提供服务的好方法,但允许它作为主服务器接口公开可能不是最佳实践。 我们可以使用 Nginx 作为反向代理,将适当的参数传递给我们的应用程序。

从 Ubuntu 的存储库安装 Nginx,这样我们就可以开始了:

sudo apt-get install nginx

我们的配置会比较基础。 它只会将我们的请求直接传递给我们的 Martini 服务器。

编辑默认的 Nginx 配置文件:

sudo nano /etc/nginx/sites-enabled/default

在里面,更改 server_name 声明以匹配您的 IP 地址或域名。 如果您使用的是域名,请确保 在您的 DigitalOcean 控制面板 中设置主机名。

server_name your_ip_or_domain ;

接下来,我们将更改 location / 声明以将请求信息传递给我们的 Martini 应用程序。 删除或注释掉默认的 location / 部分并添加一个新的来处理这个 pass:

location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://127.0.0.1:3000;
}

进行这些更改后,保存并关闭文件。

现在,我们将重新启动服务器以实现我们的更改:

sudo service nginx restart

现在,我们已经配置好前端服务器并准备好将连接传递给我们的应用程序。 我们需要启动我们的程序来接受这些连接。

目前,我们一直在使用以下语法运行我们的程序:

去运行程序名

我们应该安装我们的程序,以便我们可以按名称运行它。 我们已经设置了系统路径来查找我们将使用 Go 安装的程序。

通过键入以下内容安装您的程序:

go install hello

这将编译我们的程序并将其保存到 ~/go/bin 目录。

现在,我们只需键入以下内容即可启动我们的程序:

hello

这将启动我们的 Martini 服务器,它将像往常一样监听端口 3000 上的请求。

如果我们希望能够访问命令行,我们应该在后台启动它。 通过键入“CTRL-C”停止程序,然后像这样启动它:

hello &

这将允许我们在应用程序运行时继续键入命令。

如果您通过访问服务器的 IP 地址或域名来访问您的服务器,您应该会被路由到您的应用程序。 如果您使用斜线和名称跟随域,您将受到欢迎:

http:// your_ip_or_domain /约翰

结论


Martini 使在 Go 程序中处理 Web 请求变得容易。 它不是从头开始重写所有内容,而是尝试创建在逻辑上扩展核心 Web 包中现有服务器功能的功能。

尽管我们在本文中的示例相当简单,但 Martini 可以处理更复杂的配置。 它实现了一个中间件系统,用于将其他功能注入服务进程,并且可以通过使用社区贡献进行扩展。 Martini 简化了 Web 流程,让您专注于应用程序的核心功能。

贾斯汀·艾林伍德