~/saidqb cat wiki/stack/server-extra/go.md
commit by saidqb
Go: setup tambahan (Queue, WebSocket, Scheduler)
Lanjutan dari deploy-go.md — versi Go dari 3 topik yang sama dibahas di laravel.md/fastapi.md, walau caranya beda karena Go juga tidak punya queue/scheduler bawaan. Path & user (goapp, /home/goapp/app) ikut konvensi dokumen deploy utama.
1. Background job queue (Asynq + Redis)
Go tidak punya queue bawaan. Asynq library Go yang paling umum dipakai buat ini — mirip konsepnya sama Celery di Python, pakai Redis sebagai broker.
sudo apt install redis-server -y
go get github.com/hibiken/asynq
Worker biasanya dibuat jadi binary terpisah dari server HTTP utama (cmd/worker/main.go), di-build & dikirim ke server dengan cara yang sama seperti deploy-go.md Langkah 2:
GOOS=linux GOARCH=amd64 go build -o worker cmd/worker/main.go
scp worker user@server:/home/goapp/app/worker
ssh user@server 'sudo chown goapp:goapp /home/goapp/app/worker && sudo chmod +x /home/goapp/app/worker'
/etc/systemd/system/goapp-worker.service
[Unit]
Description=Asynq worker for Go app
After=network.target redis-server.service
[Service]
User=goapp
Group=goapp
WorkingDirectory=/home/goapp/app
ExecStart=/home/goapp/app/worker
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now goapp-worker
Redis default cuma listen di localhost, jadi tidak perlu dibuka di firewall/Nginx — cuma diakses internal oleh app & worker di server yang sama.
2. WebSocket
Sama seperti FastAPI: Go tidak butuh service terpisah buat WebSocket. Library populer (gorilla/websocket, nhooyr.io/websocket) jalan di proses HTTP yang sama dengan deploy-go.md — cukup nambah handler route baru di binary yang sama.
Yang perlu diubah cuma block Nginx yang sudah ada (deploy-go.md Langkah 4) — tambahkan header upgrade koneksi:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
sudo nginx -t && sudo systemctl reload nginx
Karena Go biasanya dijalankan satu proses saja (bukan banyak worker kayak Gunicorn -w 4), tidak ada masalah "koneksi nempel ke worker mana" seperti di FastAPI — semua koneksi WebSocket ketemu di satu proses yang sama, gampang di-broadcast dari memori langsung tanpa perlu Redis pub/sub tambahan (kecuali memang butuh scale ke lebih dari satu instance).
3. Scheduled tasks
Dua pilihan, mirip pola FastAPI:
Opsi A — cron biasa, manggil binary dengan flag/subcommand khusus:
sudo -u goapp crontab -e
0 * * * * /home/goapp/app/app --job=hourly-cleanup >> /dev/null 2>&1
(App-nya perlu baca flag --job dan jalanin fungsi yang sesuai lalu exit — bukan start server HTTP.)
Opsi B — robfig/cron, jadwal jalan in-process di dalam binary server yang sama (cocok kalau jadwalnya perlu akses langsung ke state/koneksi app, tidak perlu proses/binary terpisah):
go get github.com/robfig/cron/v3
c := cron.New()
c.AddFunc("@every 30m", myTask)
c.Start()
Kalau sudah pakai Asynq dari Langkah 1, Asynq juga punya scheduler built-in (asynq.NewScheduler) buat task berulang — tidak perlu robfig/cron terpisah kalau memang sudah masuk ekosistem Asynq.