对于那些在生产中运行GO后端的人来说:

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

除了人们使用标准的library net/http包来保持服务器运行之外,我在这个话题上没有看到太多.我读过使用Nginx将请求传递给Go服务器的文章——nginx with Go

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

有没有更可靠的生产设备?

顺便提一下我的意图-我正计划为我的下一个项目设计一个Go驱动的睡觉后端服务器,在我投入太多资金之前,我想确保Go可以现场启动这个项目.

推荐答案

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

我前面用的是HAProxy.任何反向代理都可以工作.Nginx也是一个很好的 Select (比HAProxy更受欢迎,而且可以做更多事情).

如果你阅读HAProxy的documentation(HTML version),它很容易配置.下面是我的一个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就更简单了.

关于服务控制,我将围棋程序作为系统服务运行.我想每个人都这么做.我的服务器运行Ubuntu,所以它使用Upstart.我将Upstart设置为/etc/init/myapp.conf以控制我的程序:

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

另一个方面是部署.一种 Select 是只发送程序的二进制文件和必要的assets资源 进行部署.这是一个非常棒的解决方案,国际海事组织.我使用另一个选项:在服务器上编译.(在设置所谓的"持续集成/部署"系统时,我将切换到使用二进制文件进行部署.)

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

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

Go相关问答推荐

如何使用Promela建模语言对Golang RWLock进行建模

确定果朗CSV行中的字节数

go aws-lambda 与 terraform 中的 exec 格式错误

如何从 nil 指针创建值

nixOS 上的 Nginx 反向代理在try 加载 css/js 时返回 404

是否需要手动调用rand.Seed?

如何将字节文件高效地读入int64切片?

这是泛型的有效用例吗?

Go 中的 YAML 自定义标签

Opensearch 错误 ping 弹性服务器:由未知权威签署的 x509 证书

使用 LINQ 对内部数组进行排序

如何使用 go-git 将特定分支推送到远程

如何使用 go 包设置标头键和值:shurcooL/graphql 或 hasura/go-graphql-client?

如何使用 Status 字段创建 Kubernetes 对象?

没有堆栈跟踪的 go 程序崩溃是什么意思?

在 Golang 中获取谷歌云服务帐户的访问令牌?

Go:如何创建一个可以提供配置文件中描述的 url 的服务器

为什么 Go 中的 maps.Keys() 将 map 类型指定为 M?

如何将实际上是类型为 reflect.Int32 的类型切片的 interface{} 转换为 int32 的切片?

空接口与泛型接口有何不同?