如何在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 服务器上。
先决条件
要学习本教程,您将需要以下内容:
- 按照此 Ubuntu 18.04 初始服务器设置教程 设置一台 Ubuntu 18.04 服务器,包括 sudo 非 root 用户和防火墙。
- Go编程语言按照如何在Ubuntu 18.04上安装Go并设置本地编程环境进行安装。
- Nginx 按照 How To Install Nginx on Ubuntu 18.04 安装。 不要按照 步骤 5 – 设置服务器块; 您将在本教程后面创建一个 Nginx 服务器块。
- 指向您的服务器的域名,如 如何使用 DigitalOcean 设置主机名中所述。 本教程将自始至终使用
your_domain
。 这是为您的网站获取 SSL 证书所必需的,因此您可以使用 TLS 加密安全地为您的应用程序提供服务。
此外,为了实现 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_domain
和www.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 中编码 以了解有关使用这种高效语言进行编程的更多信息。