Golang in Action: 최소 작업 스케줄링 시스템을 신속하게 구현하는 방법
소개
작업 예약은 소프트웨어 시스템에서 가장 중요한 기능 중 하나이며, 말 그대로 특정 사양에 따라 긴 작업이나 스크립트를 할당하고 실행하는 것을 의미합니다. 웹 크롤러 관리 플랫폼Crawlab에서 작업 예약은 핵심 모듈 역할을 하며, 이를 처음부터 구축하는 방법이 궁금할 수 있습니다. 이 기사에서는 Go로 간단하지만 유용한 작업 스케줄러를 구축하는 방법을 소개합니다.
아이디어
태스크 스케줄링 시스템에 필요한 사항에 초점을 맞추겠습니다.
아래는 기본적인 과정입니다.

HTTP API를 사용하여 예약된 작업을 생성할 수 있으며 실행자는 사양에 따라 주기적으로 스크립트를 실행합니다.
동작
사용자 인터페이스
먼저 기본 구조를 만들어 봅시다. 이제 루트 디렉터리 아래에 파일
main.go을 만들고 아래 내용을 입력합니다. gin는 Go로 작성된 널리 사용되는 API 엔진입니다.package main
import (
"fmt"
"github.com/gin-gonic/gin"
"os"
)
func main() {
// api engine
app := gin.New()
// api routes
app.GET("/jobs", GetJobs)
app.POST("/jobs", AddJob)
app.DELETE("/jobs", DeleteJob)
// run api on port 9092
if err := app.Run(":9092"); err != nil {
_, err = fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
그런 다음 아래와 같은 내용으로 파일
api.go을 생성합니다. 여기에는 구현이 없지만 대신 자리 표시자가 있습니다.package main
import "github.com/gin-gonic/gin"
func GetJobs(c *gin.Context) {
// TODO: implementation here
}
func AddJob(c *gin.Context) {
// TODO: implementation here
}
func DeleteJob(c *gin.Context) {
// TODO: implementation here
}
일정 작업
이제 작업 스케줄러의 핵심인 cron 작업을 구현해 보겠습니다. 우리는 Go로 작성된 평판이 좋은 cron 라이브러리인 robfig/cron 을 사용할 것입니다.
이제 아래와 같은 내용으로 새 파일
cron.go을 생성합니다. 변수 Cron는 robfig/cron의 클래스에서 시작된 인스턴스입니다.package main
import "github.com/robfig/cron"
func init() {
// start to run
Cron.Run()
}
// Cron create a new cron.Cron instance
var Cron = cron.New()
작업 스케줄러 인스턴스가 생성되면 이제 이전에 생성한 자리 표시자에 핵심 코드를 채울 수 있습니다.
api.go에서 다시 핵심 코드를 추가해 보겠습니다.package main
import (
"github.com/gin-gonic/gin"
"github.com/robfig/cron/v3"
"net/http"
"strconv"
)
func GetJobs(c *gin.Context) {
// return a list of cron job entries
var results []map[string]interface{}
for _, e := range Cron.Entries() {
results = append(results, map[string]interface{}{
"id": e.ID,
"next": e.Next,
})
}
c.JSON(http.StatusOK, Cron.Entries())
}
func AddJob(c *gin.Context) {
// post JSON payload
var payload struct {
Cron string `json:"cron"`
Exec string `json:"exec"`
}
if err := c.ShouldBindJSON(&payload); err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
// add cron job
eid, err := Cron.AddFunc(payload.Cron, func() {
// TODO: implementation here
})
if err != nil {
c.AbortWithStatusJSON(http.StatusInternalServerError, map[string]interface{}{
"error": err.Error(),
})
return
}
c.AbortWithStatusJSON(http.StatusOK, map[string]interface{}{
"id": eid,
})
}
func DeleteJob(c *gin.Context) {
// cron job entry id
id := c.Param("id")
eid, err := strconv.Atoi(id)
if err != nil {
c.AbortWithStatus(http.StatusBadRequest)
return
}
// remove cron job
Cron.Remove(cron.EntryID(eid))
c.AbortWithStatus(http.StatusOK)
}
코드 블록에서 우리는 가장 많은 로직을 구현했습니다. 유일하게 남은 부분은
Cron.AddFunc 함수의 AddJob에 있는 두 번째 매개변수의 실제 실행 논리입니다.태스크 실행
이제 작업 실행 로직을 구현해 보겠습니다. 먼저 아래 내용으로 새 파일
exec.go을 만듭니다. 여기에서는 내장 Golang 라이브러리os/exec를 사용하여 모든 셸 명령을 실행했습니다.package main
import (
"fmt"
"os"
"os/exec"
"strings"
)
func ExecuteTask(execCmd string) {
// execute command string parts, delimited by space
execParts := strings.Split(execCmd, " ")
// executable name
execName := execParts[0]
// execute command parameters
execParams := strings.Join(execParts[1:], " ")
// execute command instance
cmd := exec.Command(execName, execParams)
// run execute command instance
if err := cmd.Run(); err != nil {
_, err = fmt.Fprintln(os.Stderr, err)
fmt.Println(err.Error())
}
}
아주 잘. 이제 이 부분을 이전 자리 표시자에 넣을 수 있습니다.
...
// add cron job
eid, _ := Cron.AddFunc(payload.Cron, func() {
ExecuteTask(payload.Exec)
})
...
최종 결과
좋아, 모두 끝났어! 이제 우리는 이 최소 작업 스케줄러를 가지고 놀 수 있습니다.
명령 프롬프트를 열고
go run . 를 입력하면 API 엔진이 시작됩니다.[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] GET /jobs --> main.GetJobs (1 handlers)
[GIN-debug] POST /jobs --> main.AddJob (1 handlers)
[GIN-debug] DELETE /jobs/:id --> main.DeleteJob (1 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :9092
이제 다른 명령 프롬프트를 열고
curl -X POST -d '{"cron":"* * * * *","exec":"touch /tmp/hello.txt"}' http://localhost:9092/jobs 를 입력하면 아래와 같은 결과가 나타납니다. 즉, ID가 1인 일정 작업이 생성되고 매분 업데이트/tmp/hello.txt됩니다.{"id":1}
그런 다음 이 프롬프트에 명령
curl http://localhost:9092/jobs을 입력합니다.[{"id":1,"next":"2022-10-03T12:46:00+08:00"}]
이는 다음 실행이 1분 후임을 의미합니다.
잠시 기다렸다가 실행
ls -l /tmp/hello.txt하면 아래 결과가 표시됩니다.-rw-r--r-- 1 marvzhang wheel 0B Oct 3 12:46 /tmp/hello.txt
완벽하게 작동한다는 의미입니다!
결론
이 기사에서는 Golang의 몇 가지 라이브러리를 간단하게 조합하여 최소 작업 스케줄링 시스템을 개발하는 방법을 소개했습니다.
핵심 라이브러리:
전체 프로젝트의 코드는 GitHub에 있습니다: https://github.com/tikazyq/codao-code/tree/main/2022-10/go-task-scheduler
Reference
이 문제에 관하여(Golang in Action: 최소 작업 스케줄링 시스템을 신속하게 구현하는 방법), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tikazyq/golang-in-action-how-to-quickly-implement-a-minimal-task-scheduling-system-fel텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)