golang 介面按需獲取資源

zz小公子發表於2024-07-11

場景

爬蟲業務場景,我們需要呼叫三方介面獲取代理ip地址,每個ip地址可以使用的時間有限和價格的,本著不浪費資源,我們在這裡做一層封裝。

當有其他業務呼叫我們介面的時候,會拉起定時任務,這個定時任務的生命週期為5分鐘,超過5分鐘這個定時任務就會停止,每一次請求時都會更新定時生命週期。這樣既保證其他業務呼叫時能及時拿到代理ip地址,空閒時間又不浪費資源。

程式碼實現

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/robfig/cron/v3"
	"net/http"
	"sync"
	"time"
)

type TaskManager struct {
	cron          *cron.Cron
	entryID       cron.EntryID
	running       bool
	lifecycle     int
	lifecycleMux  sync.Mutex
	lifecycleTick *time.Ticker
	stopChan      chan struct{}
}

func NewTaskManager() *TaskManager {
	return &TaskManager{
		cron:     cron.New(cron.WithSeconds()),
		running:  false,
		stopChan: make(chan struct{}),
	}
}

func (tm *TaskManager) StartTask() {
	tm.lifecycleMux.Lock()
	defer tm.lifecycleMux.Unlock()

	if tm.running {
		tm.lifecycle = 5
		return
	}

	// 啟動定時任務,每分鐘執行一次
	tm.entryID, _ = tm.cron.AddFunc("@every 1m", tm.task)
	tm.cron.Start()
	tm.running = true
	tm.lifecycle = 5

	// 啟動生命週期ticker,每分鐘遞減一次
	tm.lifecycleTick = time.NewTicker(1 * time.Minute)
	go tm.lifecycleManager()
}

func (tm *TaskManager) StopTask() {
	tm.lifecycleMux.Lock()
	defer tm.lifecycleMux.Unlock()

	if tm.running {
		tm.cron.Remove(tm.entryID)
		tm.lifecycleTick.Stop()
		close(tm.stopChan)
		tm.running = false
		println("Task has stopped")
	}
}

func (tm *TaskManager) lifecycleManager() {
	for {
		select {
		case <-tm.lifecycleTick.C:
			tm.updateLifecycle()
		case <-tm.stopChan:
			return
		}
	}
}

func (tm *TaskManager) updateLifecycle() {
	tm.lifecycleMux.Lock()
	defer tm.lifecycleMux.Unlock()

	tm.lifecycle--
	if tm.lifecycle <= 0 {
		tm.StopTask()
	}
}

func (tm *TaskManager) task() {
	// 這裡編寫定時任務要執行的邏輯
	println("Task is running")
}

var taskManager = NewTaskManager()

func main() {
	r := gin.Default()

	// 定義請求處理函式
	r.GET("/v1/ip", handleRequest)

	r.Run(":8080")
}

func handleRequest(c *gin.Context) {
	taskManager.StartTask()

	c.JSON(http.StatusOK, gin.H{
		"message": "Task lifecycle updated",
	})
}

注意: 獲取的ip地址放到redis裡設定過期時間。程式碼只共參考大體邏輯,具體實現需要修改。

相關文章