Golang生产Web应用程序配置

时间:2013-07-03 05:34:46

标签: web go production

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

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

除了使用标准库net / http包来保持服务器运行的人之外,我还没有看到这个主题。我阅读使用Nginx将请求传递给Go服务器 - nginx with Go

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

是否有更稳固的生产设置?

除了我的意图之外 - 我正在为我的下一个项目计划一个Go支持的REST后端服务器,并希望确保Go能够在我投入太多资金之前实现启动项目。

4 个答案:

答案 0 :(得分:131)

Go程序可以侦听端口80并直接提供HTTP请求。相反,您可能希望在Go程序前使用反向代理,以便它在端口80上侦听并连接到端口上的程序,例如4000.执行后者的原因有很多:不必运行你的Go程序是root用户,服务于同一主机上的其他网站/服务,SSL终止,负载平衡,日志记录等。

我在前面使用HAProxy。任何反向代理都可以工作。 Nginx也是一个很好的选择(比HAProxy更受欢迎,能够做得更多)。

如果您阅读documentationHTML version),则很容易配置HAProxy。我的一个Go项目的整个haproxy.cfg文件如下,以防你需要一个起始点。

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.conf为Upstart控制了我的程序:

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已被证明对这些东西非常稳定。

答案 1 :(得分:57)

nginx:

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

nginx让这很容易,虽然你可以直接从Go服务,感谢net/http,但是有很多“重新发明轮子”,而像全局HTTP头这样的东西涉及到一些你可以避免的样板。

supervisord用于管理我的Go二进制文件。 Ubuntu的Upstart(正如Mostafa所提到的)也很好,但我喜欢supervisord,因为它相对与驱动程序无关并且有很好的文档记录。

Supervisord,对我来说:

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

答案 2 :(得分:6)

对于那些想要将简单的应用程序作为守护程序运行的人,请使用 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有一个单独的日记系统,可以让你记录日志,以便轻松解决问题。

答案 3 :(得分:4)

您可以使用setcap

将二进制文件绑定到套接字到Internet域特权端口(端口号小于1024)

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

  1. 此命令需要升级。必要时sudo
  2. 您的程序的每个新版本都会生成一个新的二进制文件,需要setcap
  3. 重新授权

    setcap documentation

    cap_net_bind_service documentation