Golang生产Web应用程序配置


120

对于那些在生产环境中运行Go后端的人:

运行Go Web应用程序的堆栈/配置是什么?

除了人们使用标准库net / http包来保持服务器运行之外,在该主题上我还没有看到太多东西。我阅读了使用Nginx将请求传递到Go服务器的信息- 使用Go的 Nginx

在我看来,这有点脆弱。例如,如果重新启动计算机(没有其他配置脚本),服务器将不会自动重新启动。

是否有更可靠的生产设置?

除了我的意图外,我正在为我的下一个项目规划一个Go支持的REST后端服务器,并希望确保Go在开始投入实际工作之前能够投入大量精力,然后再投入大量精力。


3
“如果重新启动计算机(没有其他配置脚本),服务器将不会自动重新启动。” 我认为无法做到这一点。理想情况下,您将为服务创建init / systemd / upstart脚本。这是控制任何unix守护程序的推荐方法。
Intermernet

你是对的。我想我的意思是与apache之类的服务器形成对比,该服务器会在安装时自动设置这些功能。
Chaseph

Answers:


134

Go程序可以侦听端口80并直接处理HTTP请求。相反,您可能想在Go程序前使用反向代理,以便它侦听端口80并在端口上连接您的程序(例如4000)。这样做的原因很多:不必运行您的Go程序以root身份在同一主机上提供其他网站/服务,SSL终止,负载平衡,日志记录等。

我在前面使用HAProxy。任何反向代理都可以工作。Nginx也是一个不错的选择(比HAProxy受欢迎得多,并且能够执行更多操作)。

如果您阅读了HAProxy的文档HTML版本),则它很容易配置。haproxy.cfg如果您需要起点,我的Go项目之一的完整文件如下。

global
        log     127.0.0.1       local0
        maxconn 10000
        user    haproxy
        group   haproxy
        daemon

defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        retries 3
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend http
        bind :80
        acl  is_stats  hdr(host)       -i      hastats.myapp.com
        use_backend    stats   if      is_stats
        default_backend        myapp
        capture        request header Host     len     20
        capture        request header Referer  len     50

backend myapp
        server  main    127.0.0.1:4000

backend stats
       mode     http
       stats    enable
       stats    scope   http
       stats    scope   myapp
       stats    realm   Haproxy\ Statistics
       stats    uri     /
       stats    auth    username:password

Nginx更容易。

关于服务控制,我将Go程序作为系统服务运行。我想每个人都这样做。我的服务器运行Ubuntu,因此使用Upstart。我把它放在/etc/init/myapp.confUpstart上来控制我的程序:

start on runlevel [2345]
stop on runlevel [!2345]

chdir /home/myapp/myapp
setgid myapp
setuid myapp
exec ./myapp start 1>>_logs/stdout.log 2>>_logs/stderr.log

另一个方面是部署。一种选择是仅通过发送程序和必要资产的二进制文件进行部署。IMO这是一个非常好的解决方案。我使用另一个选项:在服务器上编译。(在设置所谓的“连续集成/部署”系统时,我将切换为使用二进制文件进行部署。)

我在服务器上有一个小的Shell脚本,可以从远程Git存储库中提取项目代码,使用Go进行构建,然后将二进制文件和其他资产复制到~/myapp/,然后重新启动服务。

总体而言,整个过程与其他任何服务器设置都没有太大不同:您必须有一种方法来运行代码并使其能够处理HTTP请求。在实践中,事实证明,Go对于这种东西非常稳定。


9
好答案!推荐的基本设置所需的一切的良好示例。
Intermernet

您如何处理日志轮换?这几乎是我使用supervisor的唯一原因,但是当日志太多时,它会受到影响。
fiorix

@fiorix,我很确定您可以打开一个关于日志轮换的其他问题,但是如果您使用的是Unix并想使用标准工具,请查看logrotate:linuxcommand.org/man_pages/logrotate8.html。许多众所周知的服务(apache,yum等)都使用它,并且配置起来非常容易。
Doody P

在Go中创建自己的反向代理有多容易?与使用nginx或haproxy相比,这是一个更糟糕的主意吗?我的意思是Go带有强大的HTTP / HTTPS / HTTP / 2支持。
thomasrutter

58

nginx用于:

  • 反向HTTP代理到我的Go应用程序
  • 静态文件处理
  • SSL终止
  • HTTP标头(Cache-Control等)
  • 访问日志(并因此利用系统日志循环)
  • 重写(裸体到www,http://到https://等)

nginx使此操作非常容易,尽管感谢您可以直接从Go提供服务net/http,但仍有很多“重新发明轮子”的工作,诸如全局HTTP标头之类的事情就涉及到一些您可以避免的样板。

监督的管理我的Go二进制文件。Ubuntu的Upstart(如Mostafa所述)也不错,但是我喜欢主管,因为它相对于发行版而言是相对独立的,并且有据可查。

主管,对我来说:

  • 根据需要运行我的Go二进制文件
  • 崩溃后将其调出
  • 将我的环境变量(会话身份验证密钥等)保存为单个配置的一部分。
  • 运行我的数据库(以确保没有它,我的Go二进制文件不会运行)

8

对于那些希望简单的go app作为守护程序运行的用户,请使用systemd(许多Linux发行版支持)而不是Upstart。

在以下位置创建服务文件

touch /etc/systemd/system/my-go-daemon.service

输入

[Unit]
Description=My Go App

[Service]
Type=simple
WorkingDirectory=/my/go/app/directory
ExecStart=/usr/lib/go run main.go 

[Install]
WantedBy=multi-user.target

然后启用并启动服务

systemctl enable my-go-daemon
systemctl start my-go-daemon
systemctl status my-go-daemon

systemd有一个单独的日记系统,可让您添加日志以方便进行故障排除。


5

您可以使用以下方式将二进制文件绑定到套接字上的Internet域特权端口(端口号小于1024): setcap

setcap 'cap_net_bind_service=+ep' /path/to/binary

  1. 该命令需要升级。sudo有必要的
  2. 程序的每个新版本都会产生一个新的二进制文件,该二进制文件需要由 setcap

setcap 文件资料

cap_net_bind_service 文件资料

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.