golang 接口按需获取资源

场景

爬虫业务场景,我们需要调用三方接口获取代理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里设置过期时间。代码只共参考大体逻辑,具体实现需要修改。

posted @ 2024-07-11 17:09  zz小公子  阅读(11)  评论(0编辑  收藏  举报