golang执行异步任务的第三方库jobrunner库实践

简介

我们在 Web 开发中时常会遇到这样的需求,执行一个操作之后,需要给用户一定形式的通知。例如,用户下单之后通过邮件发送电子发票,网上购票支付后通过短信发送车次信息。但是这类需求并不需要非常及时,如果放在请求流程中处理,会影响请求的响应时间。这类任务我们一般使用异步的方式来执行。jobrunner就是其中一个用来执行异步任务的 Go 语言库。得益于强大的cron库,再搭配jobrunner的任务状态监控,jobrunner非常易于使用。

快速使用

本文使用 Go Modules。

创建目录并初始化:

复制代码
$ mkdir jobrunner && cd jobrunner
$ go mod init github.com/darjun/go-daily-lib/jobrunner

安装jobrunner

复制代码
$ go get -u github.com/bamzi/jobrunner

使用:

复制代码
package main

import (
  "fmt"
  "time"

  "github.com/bamzi/jobrunner"
)

type GreetingJob struct {
  Name string
}

func (g GreetingJob) Run() {
  fmt.Println("Hello, ", g.Name)
}

func main() {
  jobrunner.Start()
  jobrunner.Schedule("@every 5s", GreetingJob{Name: "dj"})

  time.Sleep(10 * time.Second)
}

我们创建一个任务,每隔 5s 打印一条欢迎信息。任务的创建和执行与cron完全相同,详细使用见我前面的一篇博文

注意,jobrunner需要先Start(),然后再添加任务。因为在Start()中创建MainCron对象,先添加任务会panic!!!

注意main函数尾的time.Sleep(10 * time.Second),因为主 goroutine 结束之后整个程序就退出了,jobrunner中的任务就没有机会被执行了。加上time.Sleep是为了让大家能看到输出,实际使用中不会这样做。

与 web 框架整合

jobrunner能很方便地与当前常见的 Web 框架整合,如Gin/Echo/Martini/Beego/Revel等。下面通过一个简单的例子演示如何在 Gin 中使用jobrunner:用户登录时给他的邮箱发送一封邮件。

首先需要安装相应的库:

复制代码
$ go get -u github.com/gin-gonic/gin
$ github.com/jordan-wright/email

编写代码:

package main

import (

"fmt"

"net/smtp"

"time"

"github.com/bamzi/jobrunner"

"github.com/gin-gonic/gin"

"github.com/jordan-wright/email"

)

type EmailJob struct {

Name string

Email string

}

type User struct {

Name string `form:"name"`

Email string `form:"email"`

}

func (j EmailJob) Run() {

e := email.NewEmail()

e.From = "leedarjun@126.com"

e.To = \[\]string{j.Email}

e.Cc = \[\]string{"leedarjun@126.com"}

e.Subject = "Welcome To Awesome-Web"

e.Text = \[\]byte(fmt.Sprintf(`

Hello, %s

Welcome Back

`, j.Name))

err := e.Send("smtp.126.com:25", smtp.PlainAuth("", "leedarjun@126.com", "yyyyyy", "smtp.126.com"))

if err != nil {

fmt.Printf("failed to send email to %s, err:%v", j.Name, err)

}

}

func login(c *gin.Context) {

var u User

if c.ShouldBind(&u) == nil {

c.String(200, "login success")

jobrunner.In(5*time.Second, EmailJob{Name: u.Name, Email: u.Email})

} else {

c.String(404, "login failed")

}

}

func main() {

r := gin.Default()

r.GET("/login", login)

r.Run(":8888")

}

这里只是为了简单演示,我们编写了一个简陋的login函数处理登录,传入nameemail,然后给该email发送邮件。email库的详细使用可以查看我之前的博文了解。

只需要在浏览器中输入http://localhost:8888/login?name=dj&email=935653229@qq.com,我的 QQ 邮箱就能收到邮件:

监控

jobrunner内置了一个监控模块,可以很方便地通过网页或者 API 获取当前的任务状态数据:

package main

import (

"fmt"

"html/template"

"os"

"time"

"github.com/bamzi/jobrunner"

"github.com/gin-gonic/gin"

)

type GreetingJob struct {

Name string

}

func (g GreetingJob) Run() {

fmt.Println("Hello,", g.Name)

}

type EmailJob struct {

Email string

}

func (e EmailJob) Run() {

fmt.Println("Send,", e.Email)

}

func main() {

r := gin.Default()

jobrunner.Start()

jobrunner.Every(5*time.Second, GreetingJob{Name: "dj"})

jobrunner.Every(10*time.Second, EmailJob{Email: "935653229@qq.com"})

r.GET("/jobrunner/json", JobJson)

r.GET("/jobrunner/html", JobHtml)

r.Run(":8888")

}

func JobJson(c *gin.Context) {

c.JSON(200, jobrunner.StatusJson())

}

func JobHtml(c *gin.Context) {

t, err := template.ParseFiles(os.Getenv("GOPATH") + "/src/github.com/bamzi/jobrunner/views/Status.html")

if err != nil {

c.JSON(400, "error")

}

t.Execute(c.Writer, jobrunner.StatusPage())

}

运行之后,在浏览器中输入http://localhost:8888/jobrunner/html查看任务状态:

这里显示任务名、任务 ID、状态、上次运行时间、下次运行时间以及处理延迟。

我们还可以通过http://localhost:8888/jobrunner/json获取原始 JSON 格式的数据自己处理:

相关推荐
福大大架构师每日一题1 天前
ollama v0.30.7 正式发布:Hermes 桌面端落地,接口、文档、底层依赖全方位优化
golang·log4j
不爱编程的小陈1 天前
深入解析 Go 网络 I/O 的底层引擎:从 epoll 到 netpoll
服务器·网络·golang
何以解忧,唯有..1 天前
Go 语言数据类型详解:从基础到复合类型
开发语言·golang·mfc
踏着七彩祥云的小丑1 天前
Go学习第7天:Map集合 + 递归函数 + 类型转换
开发语言·学习·golang·go
何以解忧,唯有..1 天前
Go语言变量的声明方式详解
开发语言·后端·golang
寂夜了无痕1 天前
Go 多版本管理工具G 保姆级安装配置教程
golang·go多版本管理
张忠琳1 天前
【Go 1.26.4】Golang Slice 深度解析
开发语言·后端·golang
张忠琳2 天前
【Go 1.26.4】Golang Channel 深度解析
开发语言·后端·golang
张忠琳2 天前
【Go 1.26.4】Golang Map 深度解析
开发语言·后端·golang
何以解忧,唯有..2 天前
Go 语言安装与环境配置完整指南
开发语言·后端·golang