为什么systemd无法启动golang web app,没有答案

时间:2016-05-18 11:04:00

标签: go deployment supervisord systemd

当我使用systemd时,我的golang网络应用程序无法启动,但在手动启动时它可以正常工作。我的systemd配置有什么问题?

goweb.service

$ cat goweb.service 
[Unit]
Description=Backend service
After=network.target

[Service]
User=myapp
Group=myapp
Restart=on-failure
ExecStart=/u01/backend

[Install]
WantedBy=multi-user.target

backend是使用命令env GOOS=linux GOARCH=amd64 go build -v bitbucket.org/myapp/backend

编译的二进制文件

systemd服务状态

$ sudo service goweb status
Redirecting to /bin/systemctl status  goweb.service
● goweb.service - Backend service
   Loaded: loaded (/usr/lib/systemd/system/goweb.service; disabled; vendor preset: disabled)
   Active: inactive (dead)

May 18 10:55:56 instance-1 systemd[1]: Started Backend service.
May 18 10:55:56 instance-1 systemd[1]: Starting Backend service...

P / S :看起来我的网络应用已启动,但随后立即停止。

我尝试配置Type=forking,然后服务状态显示如下。有人可以解释为什么日志Started Backend service.Starting Backend service...订单被颠倒了。

$ sudo service goweb status
Redirecting to /bin/systemctl status  goweb.service
● goweb.service - Backend service
   Loaded: loaded (/usr/lib/systemd/system/goweb.service; enabled; vendor preset: disabled)
   Active: inactive (dead) since Wed 2016-05-18 11:06:02 UTC; 2s ago
  Process: 25847 ExecStart=/u01/backend (code=exited, status=0/SUCCESS)

May 18 11:06:02 instance-1 systemd[1]: Starting Backend service...
May 18 11:06:02 instance-1 systemd[1]: Started Backend service.

当我手动(从终端)运行Web应用程序时的结果:

$ /u01/backend
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] POST   /upload                   --> main.uploadFileHandler (3 handlers)
[GIN-debug] Environment variable PORT="9005"
[GIN-debug] Listening and serving HTTP on :9005

更新

  1. 我尝试supervisord并且它工作正常(相同的二进制文件)
  2. 使用systemd,我将服务配置更改为Restart=alwaysRestartSec=15systemd不断重新启动我的网络应用。
  3. 有谁知道为什么supervisord工作正常但systemd没有?我认为systemd可以正常完成这样的基本任务!

5 个答案:

答案 0 :(得分:5)

我会采取疯狂的刺,并猜测你的应用程序侦听端口80和/或443,所以你最好的选择是使用setcap来授予它权限。

示例:sudo setcap 'cap_net_bind_service=+ep' /u01/backend,每次编译应用时都需要这样做。

答案 1 :(得分:4)

我知道这已经过时了,但看到没有足够的答案,所以我想发帖。我的应用程序也是手动运行的,但是在使用systemd时它不会起作用。我意识到它与Go程序所声明的文件路径有关,例如:

tpl = template.Must(template.ParseGlob("templates/*"))

当手动运行应用程序时,模板文件夹相对于我的main.go文件,但是当systemd运行它时,文件路径是不同的(不知道为什么或如何解决这个问题),但是现在我只是硬编码绝对文件路径,例如:

tpl = template.Must(template.ParseGlob("./home/ubuntu/templates/*"))

现在systemd正常工作。

希望这会有所帮助。如果有人能详细说明如何提出更好的解决方案,那么我也会完全帮助我!

答案 2 :(得分:2)

在上面的@RijulSudhir评论中,插入:

WorkingDirectory=/home/ubuntu/

以下:

[service]

systemd服务文件。

答案 3 :(得分:0)

使用仅转储环境的最小版本临时替换您的应用。手动运行且systemd下的环境是否足够相似?

答案 4 :(得分:0)

在这个特定的例子中,我猜是因为你没有指定

ExecStart=/path/to/app

结果,没有什么可开始的。