如何在Ubuntu18.04上使用Nginx部署GoWeb应用程序

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

作为 Write for DOnations 计划的一部分,作者选择了 Tech Education Fund 来接受捐赠。

介绍

Go 是一种通用编程语言,正逐渐成为最流行的 Web 后端编程语言之一。 通过专注于简单性,Go 的设计者为 Web 应用程序创建了一种既易于学习又比许多其他语言更快的语言,利用了高效的特性,例如由于其并发性而能够一次处理多个请求。 因此,在 Go 中部署 Web 应用程序将对许多后端开发人员有用。

Nginx 是世界上最流行的 Web 服务器之一,因为它具有轻量级的资源使用和负载下的可靠性。 互联网上许多最大和流量最高的网站都依赖 Nginx 来提供其内容。 在部署中,Nginx 经常被用作负载均衡器或反向代理,以提高安全性并使应用程序更加健壮。 结合 Go Web 后端,Nginx 可以提供强大而快速的 Web 应用程序。

在本教程中,您将在 Go 中构建一个 Hello World Web 应用程序,并将其部署在使用 Nginx 作为反向代理的 Ubuntu 18.04 服务器上。

先决条件

要学习本教程,您将需要以下内容:

此外,为了实现 Go Web 应用程序的生产级部署,通过安装 TLS/SSL 证书来确保服务器安全非常重要。 这一步是强烈鼓励。 要保护您的 Go web 应用程序,请在本教程的 Step 3 之后按照 How To Secure Nginx with Let's Encrypt on Ubuntu 18.04 获取免费的 TLS/SSL 证书。

第 1 步 — 构建 Go Web 应用程序

在这一步中,您将构建一个示例 Go Web 应用程序,该应用程序在 your_domain 处显示 Hello World 并在 your_domain/greet/ 处向用户致意。 如果您想了解更多有关 Go 编程基础知识的信息,请查看我们的 如何在 Go 中编写您的第一个程序一文。

首先,在您的 GOPATH 目录中创建一个新目录来保存源文件。 您可以随意命名文件夹,但本教程将使用 go-web

mkdir $GOPATH/go-web

按照先决条件教程 How To Install Go and Set Up a Local Programming Environment on Ubuntu 18.04 中建议的文件结构,这将为您的目录提供 ~/go/go-web 的路径。

接下来,运行以下命令将目录更改为 GOPATH 中新创建的文件夹:

cd $GOPATH/go-web

使用 nano 或您喜欢的文本编辑器创建一个名为 main.go 的文件,该文件将包含您的 Web 应用程序的源代码:

nano main.go

要创建 Hello World 应用程序的功能,请将以下 Go 代码添加到新创建的 main.go 文件中:

~/go/go-web/main.go

package main

import (
    "fmt"
    "net/http"
)

func main() {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello World")
    })

    http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) {
        name := r.URL.Path[len("/greet/"):]
        fmt.Fprintf(w, "Hello %s\n", name)
    })

    http.ListenAndServe(":9990", nil)
}

现在让我们从第一行开始看一下前面的代码片段会做什么。

首先,您将入口点写入应用程序:

~/go/go-web/main.go

package main
...

package main 告诉 Go 编译器将此文件编译为可执行程序而不是共享库。

接下来,您有 import 语句:

~/go/go-web/main.go

...

import (
    "fmt"
    "net/http"
)
...

此代码段导入此代码运行所需的必要模块,其中包括标准 fmt 包和 Web 服务器的 net/http 包。

下一个片段在 main 函数中创建您的第一个路由,这是任何 Go 应用程序的入口点:

~/go/go-web/main.go

...
func main () {
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintf(w, "Hello World")
    })
  ...
}
...

func main 中创建了一个父路由 /,它会在请求时返回文本 Hello World

以下代码段中显示的第二个路由接受 URL 参数,在本例中为名称,以显示伴随问候语。

~/go/go-web/main.go

...
func main () {
  ...
    http.HandleFunc("/greet/", func(w http.ResponseWriter, r *http.Request) {
        name := r.URL.Path[len("/greet/"):]
        fmt.Fprintf(w, "Hello %s\n", name)
    })
...
}
...

这使用 Go 的 URL.Path 来存储 /greet/ 之后的值,并将其作为 URL 参数中的名称向下传递。

最后,您实例化您的服务器:

~/go/go-web/main.go

...
func main () {
  ...
  http.ListenAndServe(":9990", nil)
}

前面的代码片段启动服务器并使用 Go 的内置 http 服务器通过端口 9990 公开您的应用程序。

一旦你检查完 main.go 中的代码,保存文件并退出你的文本编辑器。

接下来,通过运行以下命令构建应用程序的二进制可执行文件:

go build main.go

前面的命令将编译 main.go 以生成标题为 main 的可执行文件。

您已经创建了示例 Go Web 应用程序。 接下来,您将创建一个 systemd 单元文件,以使您的应用程序在后台运行,即使您没有访问您的服务器。

第 2 步——创建一个 Systemd 单元文件

在这一步中,您将创建一个 systemd 单元文件,以使您的应用程序即使在用户从服务器注销时也能在后台运行。 这将使您的应用程序持久化,使您更接近生产级部署。

首先,使用 nano 或您喜欢的文本编辑器在 /lib/systemd/system 目录中创建一个名为 goweb.service 的新文件:

sudo nano /lib/systemd/system/goweb.service

要设置服务的参数,请将以下代码段添加到文件中。

/lib/systemd/system/goweb.service

[Unit]
Description=goweb

[Service]
Type=simple
Restart=always
RestartSec=5s
ExecStart=/home/user/go/go-web/main

[Install]
WantedBy=multi-user.target

ExecStart=/home/user/go/go-web/main 变量指定此服务的入口点是通过位于 /home/user/go/go-web 目录中的 main 可执行文件,其中 user 是服务器非root sudo 帐户用户名。 Restart=always 确保 systemd 在程序停止时总是会尝试重新启动程序。 在下一行,RestartSec=5s 设置重新启动尝试之间的五秒等待时间。 WantedBy=multi-user.target 指定您的服务器将在何种状态下启用该服务。

保存并退出文件。

现在您已经编写了服务单元文件,通过运行以下命令启动您的 Go Web 服务:

sudo service goweb start

要确认服务是否正在运行,请使用以下命令:

sudo service goweb status

您将收到以下输出:

Output● goweb.service - goweb
   Loaded: loaded (/lib/systemd/system/goweb.service; disabled; vendor preset: enabled)
   Active: active (running) since Wed 2019-07-17 23:28:57 UTC; 6s ago
 Main PID: 1891 (main)
    Tasks: 4 (limit: 1152)
   CGroup: /system.slice/goweb.service
           └─1891 /home/user/go/go-web/main

要了解有关使用 systemd 单元文件的更多信息,请查看 Understanding Systemd Units and Unit Files

现在您的应用程序已启动并运行,您可以设置 Nginx 反向代理。

第 3 步 — 使用 Nginx 设置反向代理

在这一步中,您将创建一个 Nginx 服务器块并设置一个 Nginx 反向代理以将您的应用程序公开到 Internet。

首先,将您的工作目录更改为 Nginx sites-available 目录:

cd /etc/nginx/sites-available

使用您希望在其上公开应用程序的域的名称创建一个新文件。 本教程将使用 your_domain

sudo nano your_domain

将以下行添加到文件中以建立 your_domain 的设置:

/etc/nginx/sites-available/your_domain

server {
    server_name your_domain www.your_domain;

    location / {
        proxy_pass http://localhost:9990;
    }
}

此 Nginx 服务器块使用 proxy_pass 在您的服务器 IP 地址上为 Go Web 应用程序提供服务,指示为 localhost 以使其在端口 9990 上运行。 server_name表示映射到你的IP地址的域名,本例为your_domainwww.your_domain

接下来,通过运行以下命令在 sites-enabled 文件夹中创建此 Nginx 配置的符号链接:

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/your_domain

符号链接是另一个位置的文件的快捷方式。 新创建的快捷方式将始终引用原始文件以在对其进行编辑时进行更新。 Nginx 需要两个目录中的配置副本。

接下来,通过运行 reload 命令重新加载 Nginx 配置:

sudo nginx -s reload

要确保您的部署正常工作,请在浏览器中访问 http://your_domain。 您将看到一个 Hello World 文本字符串。

注意: 如前提条件部分所述,此时建议在您的服务器上启用 SSL/TLS。 这将确保应用程序与其访问者之间的所有通信都将被加密,如果应用程序要求提供登录或密码等敏感信息,这一点尤其重要。 现在关注 How To Secure Nginx with Let's Encrypt on Ubuntu 18.04 获取免费的 Ubuntu 18.04 上 Nginx 的 SSL 证书。 获得 SSL/TLS 证书后,返回并完成本教程。


您现在已设置 Nginx 反向代理以在您的域名下公开您的应用程序,并使用 SSL/TLS 保护您的 Go Web 应用程序。 在下一步中,您将通过安全连接测试您的应用程序。

第 4 步 — 测试应用程序

在此步骤中,您将通过安全连接测试您的应用程序,以确保一切正常。

打开您喜欢的网络浏览器,访问 https://your_domain

您将收到一个简单的 Hello World 消息。 在 URL 中使用 https:// 时收到此消息表明您的应用程序正在通过安全连接提供服务。

接下来,尝试访问第二条路线 https://your_domain/greet/your-name,将 your-name 替换为您希望应用程序问候的名称:

应用程序将返回一个简单的问候语以及 your-name,它基于传递给 URL 的参数。

收到这些结果后,您就成功部署了 Go Web 应用程序。

结论

在本教程中,您使用 Go 的标准库创建了一个简单的 Web 应用程序,使用 Nginx 设置了反向代理,并在您的域上使用了 SSL 证书来保护您的应用程序。 要了解有关 Go 的更多信息,请查看他们的 官方文档 。 此外,您可以查看我们的系列 如何在 Go 中编码 以了解有关使用这种高效语言进行编程的更多信息。