网站平台建设总结网站建设 中企动力东莞后台管理

当前位置: 首页 > news >正文

网站平台建设总结,网站建设 中企动力东莞后台管理,深圳网站制作哪家便宜,天津建设工程信息网几点更新文章目录 一、使用 time 包实现定时任务1.1 使用 time.Ticker1.2 使用 time.After 二、使用 cron 表达式调度任务#xff08;推荐#xff09;2.1 安装2.2 基本用法 正确做法#xff1a;使用 sync.WaitGroup 或 signal.Notify方法一#xff1a;使用 os.Signal 优雅监听退出信… 文章目录 一、使用 time 包实现定时任务1.1 使用 time.Ticker1.2 使用 time.After 二、使用 cron 表达式调度任务推荐2.1 安装2.2 基本用法 正确做法使用 sync.WaitGroup 或 signal.Notify方法一使用 os.Signal 优雅监听退出信号方法二主线程保活 发起 API 请求等逻辑 不推荐仅用 select {} 的场景总结2.3 Cron 表达式格式2.4 使用带秒的 Cron 表达式 三、任务控制停止、重启、带上下文四、多个任务调度五、进阶结合业务任务使用六、总结七、建议实践八、Go 定时任务实战项目完整版包括项目结构 1. 配置文件支持config/config.yaml2. main.go3. tasks/api_task.go4. tasks/report_task.go5. Dockerfile6. systemd 服务支持cron.service可选扩展点项目打包 资源 常规使用习惯大概率都是crontab脚本来分离业务逻辑但是有时候在具体项目代码中也会使用到定时任务的操作以下几个我用过的方式来分享一下 在日常开发中我们经常会遇到 定时执行任务 的需求比如 每天凌晨备份数据每隔 10 秒轮询服务状态每周一清理日志文件 虽然 Go 标准库没有专门的任务调度包但它提供了丰富的时间处理功能配合第三方库可实现非常强大的定时任务系统。本文将介绍 Go 原生定时器的使用time.Ticker 与 time.After基于 cron 表达式的定时任务多任务调度与取消推荐的第三方库robfig/cron 一、使用 time 包实现定时任务 Go 标准库中的 time 包提供了简单易用的时间控制函数。 1.1 使用 time.Ticker 每隔固定时间执行一次任务 package mainimport (fmttime )func main() {ticker : time.NewTicker(5 * time.Second)defer ticker.Stop()for {select {case t : -ticker.C:fmt.Println(执行任务时间:, t)}} }上面代码会每 5 秒执行一次任务直到程序退出。 1.2 使用 time.After 只执行一次任务延迟执行 func main() {fmt.Println(等待5秒…)time.Sleep(5 * time.Second)fmt.Println(开始执行任务) }二、使用 cron 表达式调度任务推荐 Go 没有内置 cron 表达式解析器但 robfig/cron 是最流行的调度库之一功能强大语法熟悉。 2.1 安装 go get github.com/robfig/cron/v32.2 基本用法 package mainimport (fmtgithub.com/robfig/cron/v3 )func main() {c : cron.New()// 每分钟执行一次c.AddFunc(* * * * , func() {fmt.Println(每分钟执行一次任务)})c.Start()// 阻塞主线程示例中直接 sleepselect {} }以上是单独定时任务使用里边的select{} 是 Go 中一种阻塞主线程、保持程序运行的常见写法但它的确会导致 主 goroutine 被永久挂起从而无法继续执行其他逻辑比如发起 API 请求、控制台交互等。 单独使用引起整个项目中其他逻辑挂起所以一般通过如下替代 正确做法使用 sync.WaitGroup 或 signal.Notify 下面是两种推荐方式既能阻塞主线程防止退出又能支持优雅退出、处理请求等行为 方法一使用 os.Signal 优雅监听退出信号 package mainimport (fmtosos/signalsyscallgithub.com/robfig/cron/v3 )func main() {c : cron.New()c.AddFunc(/10 * * * * *, func() {fmt.Println(每10秒执行一次任务)})c.Start()// 监听退出信号支持后续请求或中止quit : make(chan os.Signal, 1)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)fmt.Println(定时任务已启动按 CtrlC 退出…)-quitfmt.Println(收到退出信号停止定时任务)c.Stop() }适合实际应用能处理任务 后续请求 优雅退出。 方法二主线程保活 发起 API 请求等逻辑 如果你有主逻辑比如 Web 服务或某个任务可以这样写 func main() {// 启动定时任务startCronTask()// 启动你的主服务如监听 HTTP 或进行其他处理startHTTPServer()// 保持主进程运行或处理退出信号select {} // 或用 signal.Notify 替代 }不推荐仅用 select {} 的场景 使用 select {} 虽然可以快速阻塞主线程但无法 退出程序接受信号执行并发任务控制 总结 场景建议写法快速测试任务可用 select {} 临时阻塞实际服务、API任务用 signal.Notify 监听退出主线程还有其他任务如 Web多 goroutine channel 控制 2.3 Cron 表达式格式 标准 5 字段格式秒可选

  • * * * * → 分 时 日 月 星期示例 表达式含义0 0 * * 每天 0 点执行一次/10 * * * *每 10 分钟执行一次30 9 * * 1每周一 9:30 执行 2.4 使用带秒的 Cron 表达式 c : cron.New(cron.WithSeconds()) c.AddFunc(*/5 * * * * , func() {fmt.Println(每5秒执行一次任务) })三、任务控制停止、重启、带上下文 你可以通过 cron.EntryID 来管理任务例如取消某个任务 id, _ : c.AddFunc(/1 * * * *, func() {fmt.Println(正在执行任务) })c.Remove(id) // 移除定时任务也可以使用带 context.Context 的任务实现超时控制。 四、多个任务调度 你可以添加多个不同任务 c : cron.New()c.AddFunc(0 * * * *, func() {fmt.Println(每小时整点执行) }) c.AddFunc(30 9 * * *, func() {fmt.Println(每天早上9:30执行) }) c.Start()五、进阶结合业务任务使用 假设你要实现每天0点生成报告可以这样封装 func generateReport() {// 业务逻辑fmt.Println(生成日报成功) }func scheduleReportTask() {c : cron.New()c.AddFunc(0 0 * * *, generateReport)c.Start() }六、总结 技术方式特点time.Ticker简单、适合循环任务time.After单次延迟执行robfig/cron强大、支持 Cron 表达式、任务管理 七、建议实践 简单轮询用 time.Ticker周期任务用 robfig/cron支持取消/错误处理结合 context 和 log 八、Go 定时任务实战项目完整版包括 API请求 日报任务支持日志输出和错误处理使用配置文件控制调度逻辑可部署为服务带 Dockerfile 和 systemd 示例支持日志平台或数据库扩展使用 context.WithTimeout 控制请求 项目结构 go-cron-service/ ├── config/ │ └── config.yaml ├── logs/ │ └── … ├── tasks/ │ ├── api_task.go │ └── report_task.go ├── main.go ├── go.mod ├── go.sum ├── Dockerfile └── cron.service # systemd服务配置1. 配置文件支持config/config.yaml api_url: https://httpbin.org/get request_timeout: 5sschedules:api_task: */10 * * * * *report_task: 0 0 0 * * *2. main.go package mainimport (fmtosos/signalsyscalltimego-cron-service/tasksgopkg.in/yaml.v3github.com/robfig/cron/v3io/ioutil )type Config struct {APIURL string yaml:api_urlRequestTimeout time.Duration yaml:request_timeoutSchedules map[string]string yaml:schedules }var AppConfig Configfunc loadConfig() error {data, err : ioutil.ReadFile(config/config.yaml)if err ! nil {return err}return yaml.Unmarshal(data, AppConfig) }func main() {if err : loadConfig(); err ! nil {panic(配置加载失败: err.Error())}c : cron.New(cron.WithSeconds())c.AddFunc(AppConfig.Schedules[api_task], func() {tasks.FetchAPI(AppConfig.APIURL, AppConfig.RequestTimeout)})c.AddFunc(AppConfig.Schedules[report_task], tasks.GenerateReport)c.Start()fmt.Println(Cron 服务已启动按 CtrlC 退出)quit : make(chan os.Signal, 1)signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)-quitfmt.Println(接收到中断信号退出…)c.Stop() }3. tasks/api_task.go package tasksimport (contextfmtionet/httptime )func FetchAPI(apiURL string, timeout time.Duration) {ctx, cancel : context.WithTimeout(context.Background(), timeout)defer cancel()req, err : http.NewRequestWithContext(ctx, GET, apiURL, nil)if err ! nil {fmt.Println(构建请求失败:, err)return}resp, err : http.DefaultClient.Do(req)if err ! nil {fmt.Println(请求失败:, err)return}defer resp.Body.Close()body, _ : io.ReadAll(resp.Body)fmt.Printf([%s] 请求成功长度: %d\n, time.Now().Format(15:04:05), len(body)) }4. tasks/reporttask.go package tasksimport (fmtostime )func GenerateReport() {now : time.Now().Format(2006-01-02)filePath : fmt.Sprintf(logs/report-%s.txt, now) os.MkdirAll(logs, 0755)file, err : os.Create(filePath)if err ! nil {fmt.Println(创建报告失败:, err)return}defer file.Close()content : fmt.Sprintf(日报生成时间%s\n状态正常\n, time.Now().Format(2006-01-02 15:04:05))file.WriteString(content)fmt.Println(报告已生成:, filePath) }5. Dockerfile FROM golang:1.22-alpineWORKDIR /app COPY . .RUN go build -o cron-service main.goCMD [./cron-service]构建并运行 docker build -t go-cron-service . docker run -v $(pwd)/logs:/app/logs go-cron-service6. systemd 服务支持cron.service [Unit] DescriptionGo Cron 定时任务服务 Afternetwork.target[Service] Typesimple ExecStart/usr/local/bin/cron-service WorkingDirectory/opt/go-cron-service Restartalways StandardOutputjournal StandardErrorjournal[Install] WantedBymulti-user.target部署方法 sudo cp cron.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl enable cron.service sudo systemctl start cron.service可选扩展点 功能说明日志接入 ELK、Loki使用 logrus/zap 结构化日志写入数据库可记录任务结果到 MySQL/Postgres热加载任务使用 fsnotify 监听配置变更Web 管理界面提供前端管理和动态增删任务Gin cron 项目打包 你可以将此项目上传至 GitHub gh repo create go-cron-service –public –source. git add . git commit -m init: go-cron-service git push -u origin main资源 Go time 包官方文档robfig/cron GitHub 项目