مقدمه ای بر supervisor :)

گاهی وقت‌ها نیازه هستش تا ما برنامه یا اسکریپتی رو برای همیشه در سرور اجرا کنیم. یعنی بعد از بستن صفحه ترمینال برنامه متوقف نشه، یا اگر برنامه خطا داشته باشه و متوقف بشه یا سرور ریستارت بشه برنامه دوباره به صورت اتوماتیک اجرا بشه.


برای این که با supervisor کار کنیم به یک اسکریپت یا برنامه نیاز داریم. من برای این کار یک برنامه کوچک با golang نوشتم که روی پورت ۵۰۰۰ اجرا میشه.

package main

import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"os"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Println("New Request!")
		fmt.Println("---------> ", os.Getenv("TEST_ENV"))
		fmt.Println("=========> ", os.Getenv("TEST_ENV_TWO"))
		fmt.Fprintf(w, "Hello world")
	})

	http.HandleFunc("/error", func(w http.ResponseWriter, r *http.Request) {
		log.Println(errors.New("can't divide by zero"))
		fmt.Fprintf(w, "Error :)")
	})

	fmt.Println("http://localhost:5000")
	http.ListenAndServe(":5000", nil)
}

خب حالا باید بریم سراغ نصب supervisor

برای نصب supervisor نسبت به توزیع‌ خودتون یکی از دستورات زیر رو اجرا کنید

sudo apt install supervisor
sudo pacman -Suy supervisor
sudo dnf install supervisor

بعد از نصب supervisor باید این سرویس رو با دستور زیر اجرا کنیم.

sudo systemctl start supervisord

و اگر بخواهیم بعد از از ریستارت سرور supervisor خودش، خود به خود اجرا بشه دستور زیر رو اجرا میکنیم.

sudo systemctl enable supervisord

تنظیم نحوه اجرای برنامه با supervisor

اول باید محل ذخیره تنظیمات رو توی supervisor مشخص کنیم تا supervisor بتونه تنظیمات برنامه رو پیدا کنه برای این کار باید آخر فایل

/etc/supervisor/supervisord.conf

ویرایش کنیم و دستورات زیر رو بنویسم یا اصلاح کنیم:

[include]
files = /etc/supervisor/conf.d/*.conf

الان تمامی فایل هایی با پسوند .conf که در مسیر /etc/supervisor/conf.d رو supervisor میتونه پیدا کنه و در مسیر /etc/supervisor/conf.d/ فایلی به اسم test.conf ایجاد میکنیم و موارد زیر رو داخل فایل مینویسیم.

[program:test]
command=/home/majid/w/go/src/test-supervisor/server
directory=/home/majid/w/go/src/test-supervisor
autostart=true
autorestart=true
startretries=3
user=majid
environment=TEST_ENV='test env one',TEST_ENV_TWO='test env two'
stderr_logfile=/home/majid/w/go/src/test-supervisor/stderr.log
stdout_logfile=/home/majid/w/go/src/test-supervisor/stdout.log

من محتوای کامل فایل رو بالا گذاشتم تا در اینجا توضحاتشون رو بدم.

[program:test]: 

در این جا نام برنامه را تعریف کردیم که test هستش، توجه کنید که [program:-----] غیر قابل تغییر است و باید بنویسیم.

command=/home/majid/w/go/src/test-supervisor/server

با استفاده از این، دستور اجرایی یا نحوه اجرای برنامه رو مشخص میکنیم. و اگر نیاز باشد ارگومانی به برنامه پاس بدهیم باید اینجا بنویسیم.

directory=/home/majid/w/go/src/test-supervisor

محل برنامه رو مشخص میکنیم و supervisor قبل از اجرای برنامه cd میکنه داخل این پوشه.

autostart=true

وقتی مقادرش برابر true است یعنی بعد از اجرا supervisor (مثلا بعد از بوت شدن یا ریستارت سرور) برنامه به صورت اتوماتیک اجرا بشه

autorestart=true

وقتی برنامه کرش کنه یا به هر دلیلی برنامه متوقف بشه supervisor از اول برنامه را اجرا کنه البته اگر مقدارش true باشد.

startretries=3

تعداد دفعاتی که بعد از متوقف شدن یا کرش کردن، برنامه را اجرا بشه

stderr_logfile=/home/majid/w/go/src/test-supervisor/stderr.log

محل ذخیره سازی خروجی های برنامه مثل print وغیره. البته باید دقت کنید که supervisor نمی تواند پوشه ایجاد کند پس باید تمام پوشه های مسیر را بررسی کنید که وجود داشته باشد.

stdout_logfile=/home/majid/w/go/src/test-supervisor/stdout.log

خطا های برنامه (مثلا پیامی که در موقع کرش برنامه میده.) در این فایل ذخیره میشود. البته باید دقت کنید که supervisor نمی تواند پوشه ایجاد کند پس باید تمام پوشه های مسیر را بررسی کنید که وجود داشته باشد.

user=majid

اکانتی که میخواهید برنامه باهاش اجرا شود

environment=TEST_ENV='test env one',TEST_ENV_TWO='test env two'

متغیر های محیطی که برنامه در زمان اجرا نیاز دارد.

بعد از ذخیره این فایل برای اینکه supervisor این تنظیمات را بخواند باید دستورات زیر را اجرا کنیم.

Sudo supervisorctl reread # خواندن تنظیمات جدید
Sudo supervisorcrl update # اعمال تنظیمات در supervisor

حالا اگر بخواهیم ببینیم چه برنامه هایی توسط supervisor اجرا شده، دستور supervisorctl را اجرا میکنیم.

و وارد قسمت کنترل supervisor میشویم. ما میتونیم با دستور

stop test

برنامه را متوقف کنیم و با دستور

start test

برنامه رو اجرا کنیم. و اگر بخواهیم از این حالت بیرون بیاییم ctrl + c رو باید بزنیم. و همچنین بیرون از supervisorctl هم میتونیم برنامه را متوقف و اجرا کنیم.

sudo supervisorctl stop test
sudo supervisorctl start test

بعد از اجرای برنامه localhost:5000 رو باز کنید. میبینیم که برنامه به خوبی در حال اجراست.