Golang中如何设置自动定时发布功能

Golang中如何设置自动定时发布功能 如何通过 Golang 实现类似 Facebook 的删除、取消点赞、加入群组等功能

1 回复

更多关于Golang中如何设置自动定时发布功能的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Golang中实现自动定时发布功能,通常使用time包配合goroutine和channel。以下是几种实现方式:

1. 使用time.Ticker实现定时任务

package main

import (
    "fmt"
    "time"
)

func schedulePost(content string, publishTime time.Time) {
    now := time.Now()
    if publishTime.After(now) {
        duration := publishTime.Sub(now)
        time.AfterFunc(duration, func() {
            publishPost(content)
        })
    }
}

func publishPost(content string) {
    fmt.Printf("定时发布: %s\n发布时间: %s\n", content, time.Now().Format("2006-01-02 15:04:05"))
}

func main() {
    // 设置10秒后发布
    schedulePost("第一篇定时文章", time.Now().Add(10*time.Second))
    
    // 设置1分钟后发布
    schedulePost("第二篇定时文章", time.Now().Add(1*time.Minute))
    
    // 保持程序运行
    time.Sleep(2 * time.Minute)
}

2. 使用cron表达式(推荐用于复杂调度)

package main

import (
    "fmt"
    "github.com/robfig/cron/v3"
    "time"
)

func main() {
    c := cron.New()
    
    // 每天10:30发布
    c.AddFunc("30 10 * * *", func() {
        publishScheduledPost("每日新闻简报")
    })
    
    // 每周一9:00发布
    c.AddFunc("0 9 * * 1", func() {
        publishScheduledPost("每周技术总结")
    })
    
    // 每5分钟发布一次
    c.AddFunc("*/5 * * * *", func() {
        publishScheduledPost("定时更新内容")
    })
    
    c.Start()
    
    // 保持程序运行
    select {}
}

func publishScheduledPost(content string) {
    fmt.Printf("[%s] 发布: %s\n", 
        time.Now().Format("2006-01-02 15:04:05"), 
        content)
}

3. 结合数据库的完整定时发布系统

package main

import (
    "database/sql"
    "fmt"
    "log"
    "time"
    _ "github.com/go-sql-driver/mysql"
)

type ScheduledPost struct {
    ID          int
    Content     string
    PublishTime time.Time
    Status      string // "pending", "published"
}

func startScheduler(db *sql.DB) {
    ticker := time.NewTicker(1 * time.Minute)
    defer ticker.Stop()
    
    for range ticker.C {
        checkAndPublishPosts(db)
    }
}

func checkAndPublishPosts(db *sql.DB) {
    now := time.Now()
    query := `
        SELECT id, content, publish_time 
        FROM scheduled_posts 
        WHERE status = 'pending' 
        AND publish_time <= ? 
        LIMIT 10
    `
    
    rows, err := db.Query(query, now)
    if err != nil {
        log.Printf("查询失败: %v", err)
        return
    }
    defer rows.Close()
    
    for rows.Next() {
        var post ScheduledPost
        err := rows.Scan(&post.ID, &post.Content, &post.PublishTime)
        if err != nil {
            log.Printf("扫描数据失败: %v", err)
            continue
        }
        
        // 发布文章
        go publishPostToPlatform(post.Content)
        
        // 更新状态
        updatePostStatus(db, post.ID)
    }
}

func publishPostToPlatform(content string) {
    // 实现实际的发布逻辑
    fmt.Printf("发布到平台: %s\n", content)
}

func updatePostStatus(db *sql.DB, postID int) {
    _, err := db.Exec("UPDATE scheduled_posts SET status = 'published' WHERE id = ?", postID)
    if err != nil {
        log.Printf("更新状态失败: %v", err)
    }
}

func scheduleNewPost(db *sql.DB, content string, publishTime time.Time) error {
    _, err := db.Exec(
        "INSERT INTO scheduled_posts (content, publish_time, status) VALUES (?, ?, 'pending')",
        content, publishTime,
    )
    return err
}

4. 使用context控制定时任务

package main

import (
    "context"
    "fmt"
    "time"
)

func scheduledWorker(ctx context.Context, interval time.Duration, task func()) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()
    
    for {
        select {
        case <-ctx.Done():
            fmt.Println("定时任务停止")
            return
        case <-ticker.C:
            task()
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())
    
    // 启动定时发布任务
    go scheduledWorker(ctx, 30*time.Second, func() {
        fmt.Printf("定时执行: %s\n", time.Now().Format("15:04:05"))
    })
    
    // 运行5分钟后停止
    time.Sleep(5 * time.Minute)
    cancel()
    time.Sleep(1 * time.Second)
}

关键要点:

  1. 简单定时:使用time.AfterFunctime.Ticker
  2. 复杂调度:使用第三方库如robfig/cron
  3. 持久化存储:结合数据库存储定时任务
  4. 并发控制:使用goroutine处理多个定时任务
  5. 错误处理:添加适当的错误恢复机制

对于生产环境,建议使用消息队列(如RabbitMQ、Kafka)或任务调度系统(如Celery)配合Golang实现更可靠的定时发布功能。

回到顶部