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 格式的数据自己处理:

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/57779.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java+springboot+mysql校园宿舍报修管理系统

项目介绍: 使用javaspringbootmysql开发的校园宿舍报修管理系统,系统包含管理员、维修员、学生角色,功能如下: 管理员:楼栋管理、宿舍管理、维修人员管理、学生管理;报修管理(派单给维修员&am…

npm发布包

1.npm 登录 在控制台输入命令 npm login 按提示输入用户名,密码,邮箱后登录 如果出现如下提示 需要将淘宝镜像源切换为npm源,删除或注释以下内容就行 2.发布 进入准备发布的代码的根目录下,输入命令 npm publish 3.删除已发…

微信小程序原生写法传递参数

微信小程序原生写法传递参数 data-xxx 自定义参数名 ,接收参数:方法(变量名) checkVip:function(event) {let that thisconsole.log(event,event)console.log(event.currentTarget.dataset.idx,index)let index Number(eve…

适应于Linux系统的三种安装包格式 .tar.gz、.deb、rpm

deb、rpm、tar.gz三种Linux软件包的区别 rpm包-在红帽LINUX、SUSE、Fedora可以直接进行安装,但在Ubuntu中却无法识别; deb包-是Ubuntu的专利,在Ubuntu中双击deb包就可以进入自动安装进程; tar.gz包-在所有的Linux版本中都能使用…

静态路由下一跳地址怎么确定(静态路由配置及讲解)

一、用到的所有命令及功能 ①ip route-static 到达网络地址 子网掩码 下一跳 // 配置静态路由下一跳指的是和当前网络直接连接的路由器的接口地址非直连网段必须全部做路由路径是手工指定的,在大规模网络上不能用,效率低,路径是固定的稳定的…

什么?你还没有用过JPA Buddy,那么你工作肯定没5年

1. 概述 JPA Buddy是一个广泛使用的IntelliJ IDEA插件,面向使用JPA数据模型和相关技术(如Spring DataJPA,DB版本控制工具(Flyway,Liquibase),MapStruct等)的新手和有经验的开发人员…

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(19)-Fiddler精选插件扩展安装,将你的Fiddler武装到牙齿

1.简介 Fiddler本身的功能其实也已经很强大了,但是Fiddler官方还有很多其他扩展插件功能,可以更好地辅助Fiddler去帮助用户去开发、测试和管理项目上的任务。Fiddler已有的功能已经够我们日常工作中使用了,为了更好的扩展Fiddler&#xff0c…

C# 外观模式

概述 外观模式(Facade Pattern)是一种结构型设计模式,它提供了一个统一的接口,用于访问子系统中的一组接口。外观模式隐藏了子系统的复杂性,使得客户端可以通过简单的接口与子系统进行交互。 外观模式定义了一个高层…

微信小程序 - 解析富文本插件版们

一、html2wxml 插件版 https://gitee.com/qwqoffice/html2wxml 申请使用注意事项 插件版本解析服务是由 QwqOffice 完成,存在不稳定因素,如对稳定性有很高的要求,请自行搭建解析服务,或在自家服务器上直接完成解析。对于有关插…

生成对抗网络DCGAN学习

在AI内容生成领域,有三种常见的AI模型技术:GAN、VAE、Diffusion。其中,Diffusion是较新的技术,相关资料较为稀缺。VAE通常更多用于压缩任务,而GAN由于其问世较早,相关的开源项目和科普文章也更加全面&#…

STM32入门——外部中断

中断系统概述 中断:在主程序运行过程中,出现了特定的中断触发条件(中断源),使得CPU暂停当前正在运行的程序,转而去处理中断程序,处理完成后又返回原来被暂停的位置继续运行中断优先级&#xff…

vue 图片回显标签

第一种 <el-form-item label"打款银行回单"><image-preview :src"form.bankreceiptUrl" :width"120" :height"120"/></el-form-item>// 值为 https://t11.baidu.com/it/app106&fJPEG&fm30&fmtauto&…

Kafka-Broker工作流程

kafka集群在启动时&#xff0c;会将每个broker节点注册到zookeeper中&#xff0c;每个broker节点都有一个controller&#xff0c;哪个controller先在zookeeper中注册&#xff0c;哪个controller就负责监听brokers节点变化&#xff0c;当有分区的leader挂掉时&#xff0c;contro…

Python基本数据类型之散列类型详解

前言&#xff1a; python的基本数据类型可以分为三类&#xff1a;数值类型、序列类型、散列类型&#xff0c;本文主要介绍散列类型。 一、散列类型 散列类型&#xff1a;内部元素无序&#xff0c;不能通过下标取值 1&#xff09;字典&#xff08;dict&#xff09;&#xff…

20230803激活手机realme GT Neo3

20230803激活手机realme GT Neo3 缘起&#xff1a; 新买的手机&#xff1a;realme GT Neo3 需要确认&#xff1a; 1、4K录像&#xff0c;时间不限制。 【以前的很多手机都是限制8/10/12/16分钟】 2、通话自动录音 3、定时开关机。 4、GPS记录轨迹不要拉直线&#xff1a;户外助…

1345:香甜的黄油(Dijkstra)---信息学奥赛一本通

【题目描述】 农夫John发现做出全威斯康辛州最甜的黄油的方法&#xff1a;糖。把糖放在一片牧场上&#xff0c;他知道N&#xff08;1≤N≤500&#xff09;只奶牛会过来舔它&#xff0c;这样就能做出能卖好价钱的超甜黄油。当然&#xff0c;他将付出额外的费用在奶牛上。 农夫Jo…

【秋招】算法岗的八股文之机器学习

目录 机器学习特征工程常见的计算模型总览线性回归模型与逻辑回归模型线性回归模型逻辑回归模型区别 朴素贝叶斯分类器模型 (Naive Bayes)决策树模型随机森林模型支持向量机模型 (Support Vector Machine)K近邻模型神经网络模型卷积神经网络&#xff08;CNN&#xff09;循环神经…

【css】css实现一个简单的按钮

四种链接状态分别是&#xff1a; a:link - 正常的&#xff0c;未访问的链接a:visited - 用户访问过的链接a:hover - 用户将鼠标悬停在链接上时a:active - 链接被点击时 <style> a:link, a:visited {//未访问、访问过background-color: #07c160;//设置背景颜色color: wh…

MFC、Qt、WPF?该用哪个?

MFC、Qt和WPF都是流行的框架和工具&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;应用程序。选择哪个框架取决于你的具体需求和偏好。MFC&#xff08;Microsoft Foundation Class&#xff09;是微软提供的框架&#xff0c;使用C编写&#xff0c;主要用于Windows…

牛客网Verilog刷题——VL47

牛客网Verilog刷题——VL47 题目答案 题目 实现4bit位宽的格雷码计数器。 电路的接口如下图所示&#xff1a; 输入输出描述&#xff1a; 信号类型输入/输出位宽描述clkwireIntput1时钟信号rst_nwireIntput1异步复位信号&#xff0c;低电平有效gray_outregOutput4输出格雷码计数…