专栏首页学院君的专栏基于 Go 语言开发在线论坛(九):部署 Go Web 应用

基于 Go 语言开发在线论坛(九):部署 Go Web 应用

部署 Go Web 应用

0、简介

与 PHP 应用相比,部署 Go 应用相对简单,因为所有应用代码都被打包成一个二进制文件了(视图模板、静态资源和配置文件等非 Go 代码除外),并且不需要依赖其他库(PHP 需要安装各种扩展),不需要额外的运行时环境(比如 Java 需要再安装 JVM),也不需要部署额外的 HTTP 服务器(比如 PHP 还需要再启动 PHP-FPM 处理请求)。

对于在线论坛项目,包含了静态资源文件(CSS、JavaScript、图片),所以我们将在 Go Web 应用之前前置一个 Nginx 服务器处理静态资源请求,然后通过反向代理处理动态资源请求(指向 Go 处理器方法的请求),对于那些不包含静态资源和视图模板的纯 API 项目,通常只需要打包一份二进制文件部署到服务器即可,更加便捷。

注:其实 Go 应用部署的最佳实践是基于 Docker,后续我们在部署专题中再介绍如何基于 Docker 将应用快速部署到远程云服务器。

1、构建应用

首先,我们可以在本地项目根目录下通过如下命令将应用代码打包成二进制可执行文件:

GOOS=linux GOARCH=amd64 go build

注意这里指定了 GOOSGOARCH 选项进行交叉编译,因为我们是在 Mac 系统(amd64)中打包,并且目标二进制文件需要在 Linux 服务器(linux)执行。该命令执行成功后会在当前目录下生成和项目名称相同的二进制文件:

构建 Go Web 应用二进制文件

然后我们可以将代码提交到 Github 或者其他代码仓库。

2、部署应用

部署代码

再登录服务器到部署目录下拉取代码:

git clone https://github.com/nonfu/chitchat

初次拉取使用 git clone,后续在 chitchat 目录下运行 git pull 即可。

然后我们进入 chitchat 目录,配置 config.json 进行服务端数据库配置(正式项目不要将 config.json 提交到代码仓库,以免安全风险和后续拉取代码覆盖),确保 logs 目录对 Web 用户具有写权限(比如配置权限为 777,或者所属用户与 Web 用户组一致)。

注:当然我们这里部署代码的方式比较原始,对于多人协作的大型项目,可以借助持续集成工具(比如 Jenkins)进行自动化部署,并且由于项目比较简单,就不再演示单元测试、CI/CD 等其他 DevOps 工具的使用了。

数据库初始化

在服务端 MySqL 数据库中创建 chitchat 数据库,并初始化对应数据表。

注:如果不了解如何安装和创建数据库,可以参考学院君网站的这篇教程:https://xueyuanjun.com/post/9749.html。

访问应用

完成以上工作后,我们就可以在 chitchat 项目目录下运行 chitchat 二进制文件启动应用了:

启动在线论坛

然后我们在本地 hosts 文件中自定义一个测试域名与服务器 IP 的映射:

your-server-ip-address chitchat.test

将上述 your-server-ip-address 替换成自己的远程服务器 IP 地址,然后我们就可以在浏览器中通过 http://chitchat.test:8080 访问应用了:

访问在线论坛

3、通过 Nginx 做反向代理

虽然上述方式可以正常运行,但是如果要高效处理静态资源文件并对其做缓存,可以借助 Nginx 作为反向代理服务器来完成,我们在 Nginx 虚拟主机配置目录 /etc/nginx/sites-available 中新增一个配置文件 chitchat.conf(以 Ubuntu 服务器为例):

server {
    listen      80; 
    server_name chitchat.test www.chitchat.test;

    # 静态资源交由 Nginx 管理,并缓存一天
    location /static {
        root        /var/www/chitchat/public;
        expires     1d;
        add_header  Cache-Control public;
        access_log  off;
        try_files $uri @goweb;
    }

    location / {
        try_files /_not_exists_ @goweb;
    }

    # 动态请求默认通过 Go Web 服务器处理
    location @goweb {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Scheme $scheme;
        proxy_redirect off;
        proxy_pass http://127.0.0.1:8080;
    }

    error_log /var/log/nginx/chitchat_error.log;
    access_log /var/log/nginx/chitchat_access.log;
}

然后再启用该配置文件:

ln -s /etc/nginx/sites-available/chitchat /etc/nginx/sites-enabled/chitchat

重启 Nginx 服务:

service nginx restart

与此同时,我们可以把 chitchat/config.json 中的 App 配置项启动 IP 地址改为 127.0.0.1

"App": {
    "Address": "127.0.0.1:8080",
    "Static": "public",
    "Log": "logs",
    "Locale": "locales",
    "Language": "zh"
  },

并再次重启这个 Go 应用,这样就只能通过 Nginx 访问应用,在浏览器中访问 http://chitchat.test

通过 Nginx 访问在线论坛

而当你试图再通过 http://chitchat.test:8080 访问应用,则会报错:

不能再直接通过 IP + 端口号访问 Go Web 应用后端进程了

我们可以测试下注册登录功能以及创建新群组功能:

测试在线论坛

4、通过 Supervisor 维护应用守护进程

看起来一切都 OK 了,但是目前这种模式下,用户退出后 Go Web 应用进程会关闭,这显然是不行的,而且如果 Go Web 应用进程因为其他异常挂掉,也无法自动重启,每次需要我们登录到服务器进行启动操作,这很不方便,也影响在线应用的稳定性,为此,我们需要借助第三方进程监控工具帮我们实现 Go Web 应用进程以后台守护进程的方式运行。常见的进程监控工具有 Supervisor、Upstart、systemd 等,由于我的服务器之前部署过 Supervisor,所以我就借助它来管理 Go Web 应用进程。

注:对 Supervisor 安装配置不了解的同学,可以参考学院君网站的这篇教程:https://xueyuanjun.com/post/21566。

首先创建对应的 Supervisor 配置文件 /etc/supervisor/conf.d/chitchat.conf,这里需要设置进程启动目录及命令、进程意外挂掉后是否自动重启、以及日志文件路径等:

[program:chitchat]
process_name=%(program_name)s
directory=/var/www/chitchat
command=/var/www/chitchat/chitchat
autostart=true
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/var/www/chitchat/logs/chitchat.log

注意:我们需要进入 chitchat 所在目录执行启动命令,否则会找不到配置文件和其他资源路径,所以需要配置 directory 选项。

然后关闭之前通过手动运行 chitchat 启动的 Go Web 服务器,再运行如下指令通过 Supervisor 启动并维护 Go Web 应用进程:

supervisorctl reread
supervisorctl update
supervisorctl start chitchat

你可以通过 ps -ef | grep chitchat 查看进程是否启动成功:

查看 chitchat 进程是否启动成功

启动成功后,就可以在浏览器通过 http://chitchat.test 访问部署在远程服务器的在线论坛了:

再次访问在线论坛

并且无论是否退出远程服务器还是关闭 Go Web 应用进程,都不会影响在线论坛的访问,因为它是以守护进程的方式运行的,并且可以在关闭后自动重启。

好了,关于 Go Web 应用的部署学院君就简单介绍到这里,大家权当入个门。

本文分享自微信公众号 - 学院君的后花园(geekacademy),作者:xueyuanjun

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-04-17

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 通过 PDO 扩展与 MySQL 数据库交互(上)

    在上篇教程中,学院君给大家介绍了如何通过 PHP 内置的 Mysqli 扩展与 MySQL 数据库交互,今天我们来看看另一个 PHP 内置的数据库扩展 —— P...

    学院君
  • 基于 Go 语言构建在线论坛项目索引篇

    本文是「基于 Go 语言开发在线论坛项目」的汇总篇,方便大家作为目录索引进行查阅,你可以在学院君公众号(xueyuanjun)首页底部菜单实战项目中看到入口:

    学院君
  • 玩转 PhpStorm 系列(十二):单元测试篇

    PHP 生态有很多测试框架,其中最流行的当属 PHPUnit,我们还是以 Laravel 项目为例,在 PhpStorm 中演示如何通过 PHPUnit 对 P...

    学院君
  • Spring-AOP实践 - 统计访问时间

    公司的项目有的页面超级慢,20s以上,不知道用户会不会疯掉,于是老大说这个页面要性能优化。于是,首先就要搞清楚究竟是哪一步耗时太多。 我采用spring aop...

    Ryan-Miao
  • 如何Meteor中轻松使用Webpack

    时见疏星
  • Redis中的Shell工具

    我们在启动Redis服务时会用到redis-server Shell工具,在使用Redis客户端的时候会用到redis-cli Shell工具。实际上在Redi...

    吉林乌拉
  • 如何从传统软件开发顺利过渡到互联网技术开发-硬技能

    为什么要转型呢?云计算的盛行,导致很多产品已经云化。另外,长期专注于业务开发导致技术人员自觉乏味,没有提升空间,自我存在感、成就感大幅下降,而互联网、移动互联网...

    歪脖贰点零
  • Tomcat 优雅关闭之路

    本文通过阅读Tomcat启动和关闭流程的源码,深入分析不同的Tomcat关闭方式背后的原理,让开发人员能够了解在使用不同的关闭方式时需要注意的点,避免因JVM进...

    2020labs小助手
  • USACO全部月赛及GateWay数据

    月赛: 以07年open为例,网站如下 http://contest.usaco.org/OPEN07 其他的格式是http://contest.usaco.o...

    HansBug
  • 类图的6大关系详解

    以下类图使用 PlantUML 绘制,更多语法及使用请参考:plantuml.com/ 。

    李红

扫码关注云+社区

领取腾讯云代金券