在 Linux 服务器上,systemd 是管理服务的标准方式。将 Gin 应用配置为 systemd 服务,可以实现开机自启、自动重启等功能。
创建 /etc/systemd/system/myapp.service:
[Unit]
Description=Gin Web Application
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/main
Restart=always
RestartSec=5
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=myapp
Environment=GIN_MODE=release
Environment=PORT=8080
[Install]
WantedBy=multi-user.target
使用环境变量文件管理配置:
/opt/myapp/.env:
GIN_MODE=release
PORT=8080
DB_HOST=localhost
DB_PORT=3306
DB_USER=myuser
DB_PASSWORD=mypassword
DB_NAME=myapp
服务配置:
[Service]
EnvironmentFile=/opt/myapp/.env
ExecStart=/opt/myapp/main
# 重新加载配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start myapp
# 停止服务
sudo systemctl stop myapp
# 重启服务
sudo systemctl restart myapp
# 查看状态
sudo systemctl status myapp
# 开机自启
sudo systemctl enable myapp
# 取消开机自启
sudo systemctl disable myapp
# 查看日志
sudo journalctl -u myapp -f
[Unit]
Description=My Gin Application
Documentation=https://example.com/docs
After=network.target network-online.target
Wants=network-online.target
[Service]
Type=notify
User=app
Group=app
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/main
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
LimitNPROC=4096
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
NoNewPrivileges=true
ReadWritePaths=/opt/myapp/logs
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
Environment=GIN_MODE=release
EnvironmentFile=/opt/myapp/config.env
TimeoutStopSec=30
TimeoutStartSec=10
[Install]
WantedBy=multi-user.target
让 systemd 知道应用已启动:
package main
import (
"github.com/gin-gonic/gin"
"github.com/coreos/go-systemd/daemon"
)
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(200, "Hello")
})
go func() {
if _, err := daemon.SdNotify(false, daemon.SdNotifyReady); err != nil {
log.Printf("Failed to notify systemd: %v", err)
}
}()
r.Run(":8080")
}
服务配置使用 Type=notify:
[Service]
Type=notify
ExecStart=/opt/myapp/main
配置日志轮转:
/etc/logrotate.d/myapp:
/var/log/myapp/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 app app
sharedscripts
postrotate
systemctl reload myapp > /dev/null 2>&1 || true
endscript
}
[Service]
LimitNOFILE=65536
LimitNPROC=4096
LimitMEMLOCK=infinity
MemoryMax=1G
CPUQuota=100%
[Service]
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
NoNewPrivileges=true
ReadOnlyPaths=/
ReadWritePaths=/opt/myapp/logs /opt/myapp/data
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_BIND_SERVICE
/etc/systemd/system/myapp@.service:
[Unit]
Description=My Gin Application - Instance %i
After=network.target
[Service]
Type=simple
User=app
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/main -port %i
Restart=always
[Install]
WantedBy=multi-user.target
启动多个实例:
sudo systemctl start myapp@8080
sudo systemctl start myapp@8081
sudo systemctl start myapp@8082
systemd 是 Linux 上管理 Gin 应用的标准方式。配置服务后可以实现自动重启、开机自启。使用 EnvironmentFile 管理配置,使用 journalctl 查看日志。生产环境建议配置资源限制和安全加固。