Golang生产Web应用程序配置

Cha*_*eph 116 production go web

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

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

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

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

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

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

Mos*_*afa 131

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

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

如果您阅读其文档(HTML版本),HAProxy非常容易配置.我haproxy.cfg的一个Go项目的整个文件如下,如果你需要一个起始pont.

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

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

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

总的来说,整个事情与任何其他服务器设置没有太大差别:您必须有办法运行代码并让它提供HTTP请求.在实践中,Go已被证明对这些东西非常稳定.

  • 很棒的答案!建议的基本设置所需的一切的好例子. (9认同)

eli*_*rar 57

nginx:

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

nginx让这很容易,虽然你可以直接从Go服务net/http,但是有很多"重新发明轮子",像全局HTTP标题这样的东西涉及一些你可以避免的样板.

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

Supervisord,对我来说:

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


Emp*_*rth 6

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

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

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

setcap 文件

cap_net_bind_service 文件


mix*_*dev 6

对于那些想要简单的应用程序作为守护进程运行的人,请使用systemd(由许多Linux发行版支持)而不是Upstart.

在.创建服务文件

touch /etc/systemd/system/my-go-daemon.service
Run Code Online (Sandbox Code Playgroud)

输入

[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
Run Code Online (Sandbox Code Playgroud)

然后启用并启动该服务

systemctl enable my-go-daemon
systemctl start my-go-daemon
systemctl status my-go-daemon
Run Code Online (Sandbox Code Playgroud)

systemd有一个单独的日志系统,可以让你拖尾日志,以便轻松解决问题.