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

news2025/1/19 3:41:41

简介

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Jenkins工具系列 —— 快速构建项目

文章目录 添加项目选择构建的项目添加项目参数添加项目仓库添加编译脚本 添加项目 选择构建的项目 添加项目参数 添加项目仓库 添加编译脚本

电脑技巧:分享五款非常实用的电脑软件,值得收藏

目录 1、RX文件管理器(UWP) 2、WizTree 3、QuickLook 4、优效日历 5、FastStone Capture 今天小编给大家分享非常实用的电脑软件,值得收藏! 1、RX文件管理器(UWP) RX文件管理器是优雅的UWP文件管理器…

leetcode原题 路径总和 I II III(递归实现)

路径总和 I : 给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。…

FreeRTOS源码分析-8 信号量

1 信号量概念及应用 信号灯解决的问题: 行人、车辆共享一个马路共享资源的问题,第二个解决通过的问题。 计数停车位的问题: 解决共享资源停车位计数的问题,因为车位是有限的,客流是无限的,计数可以很好的…

无涯教程-Lua - Iterators(迭代器)

迭代器是一种构造,使您可以遍历所谓的集合或集合的元素。在Lua中,这些集合通常引用表,这些表用于创建各种数据结构(如数组)。 通用迭代器 通用的 for 迭代器提供集合中每个元素的键值对。下面给出一个简单的示例。 array{"Lua",…

程序的编译和调试

gcc编译器 gcc(GNU Compiler Collection)是GNU推出的多平台编译器,可将C、C源程序编译连接成可执行文件,支持以下后缀: .c c语言源代码 .h 程序所包含的头文件 .i 已经预处理过的C源代码文件 .s 汇编语言源代码文件 .o 编译后的目标文件…

Leetcode69 x的平方根

二分查找法 代码 public int mySqrt(int x){int l 0, r x,ans -1;while(l < r){int mid l (r - l) / 2;if((long) mid * mid < x){ans mid;l mid 1;}else{r mid - 1;}}return ans; }

C++ 多文件结构和编译预处理命令——C++程序的一般组织结构

1. C程序的一般组织结构 C源程序的结构基本上都是由3个部分构成&#xff1a;类的定义、类的成员的实现和主函数。因为所编写的程序比较小&#xff0c;所以这三个部分都写在了同一个文件当中。在规模比较大的项目中&#xff0c;往往需要多个源程序文件&#xff0c;每个源程序文…

windows编译zookeeker动态库供C++链接使用以及遇到的错误处理方法

windows下面C链接zookeeper资料不多&#xff0c;特此记录一下 编译环境VS 2015 一. 相关安装包安装下载 1. zookeeper zookeeper3.6.4 下载zip包解压即可 2. ant apache-ant-1.9.16 将包进行解压D:project\apache-ant-1.9.16&#xff0c;然后配置环境变量 新建 ANT_HOME 系…

linux/windows如何退出telnet

在运维过程中&#xff0c;我们需要使用telnet来验证tcp端口的连通性&#xff0c;当tcp端口的连通性处于正常状态时&#xff0c;那么此时如果退出呢&#xff1f;下面就为大家讲一讲这个小常识&#xff0c;希望能对大家有所帮助。 1.Linux下telnet退出 如果没有telnet命令&…

Apache Flink概述

Flink 是构建在数据流之上的一款有状态的流计算框架&#xff0c;通常被人们称为第三代大数据分析方案 第一代大数据处理方案&#xff1a;基于Hadoop的MapReduce 静态批处理 | Storm 实时流计算 &#xff0c;两套独立的计算引擎&#xff0c;难度大&#xff08;2014年9月&#x…

第五章 Git

5-1、Git的安装 1、为什么要使用代码版本控制系统 【1】版本控制 【2】开发中存在的麻烦 2、Git和SVN的对比 【1】Git和SVN对比 &#xff08;1&#xff09;SVN &#xff08;2&#xff09;Git 3、Git下载和安装 【1】下载 【2】安装 一路下一步就好了&#xff0c;更换安装…

【力扣】 12. 整数转罗马数字 模拟

力扣 12. 整数转罗马数字 解题思路 当某个位数的某个数不为4或9时&#xff0c;高位对应的字符总是在低位对应的字符前面。只有当该数为4或9时&#xff0c;低位对应的字符在高位前面。 根据这一特性&#xff0c;我们进行分类讨论。 1.当数为4时&#xff0c;则对应的罗马数为 10 …

【心电图信号压缩】ECG信号压缩与通过三次样条近似重建的ECG信号压缩研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Vue [Day2]

指令修饰符 v-model.trim v-model.number 事件名.stop click.stop 事件名.prevent keyup.enter <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-w…

数据泄露的平均成本创历史新高

IBM Security 发布了年度数据泄露成本报告&#xff0c;显示数据泄露的全球平均成本在 2023 年达到 445 万美元&#xff0c;创下该报告的历史新高&#xff0c;并且比过去 3 年增加了 15%。 检测和升级成本在同一时间段内跃升了 42%&#xff0c;占违规成本的最高部分&#xff0c…

促科技创新:高德数据优化篇之OceanBase最佳实践

本文作者&#xff1a; 振飞&#xff08;高德地图总裁&#xff09; 炳蔚&#xff08;高德技术服务平台负责人&#xff09; 福辰&#xff08;高德服务端架构师&#xff09; 背景 高德成立于2002年&#xff0c;是中国领先的移动数字地图、导航及实时交通信息服务提供商&#xff0c…

Ctfshow web入门 JWT篇 web345-web350 详细题解 全

CTFshow JWT web345 先看题目&#xff0c;提示admin。 抓个包看看看。 好吧我不装了&#xff0c;其实我知道是JWT。直接开做。 在jwt.io转换后&#xff0c;发现不存在第三部分的签证&#xff0c;也就不需要知道密钥。 全称是JSON Web Token。 通俗地说&#xff0c;JWT的本质…

通讯协议030——全网独有的OPC HDA知识一之基本概念(一)

本文简单介绍OPC HDA规范的基本概念&#xff0c;更多通信资源请登录网信智汇(wangxinzhihui)。 目前&#xff0c;大多数历史数据系统都使用自己的专有接口对外提供数据服务&#xff0c;不能与任何其他系统互操作。OPC HDA规范旨在提供历史数据访问的标准接口&#xff0c;促进用…

2023年信息系统项目管理师-学习计划安排

1. 关注信管网&#xff1a; 信管网 - 考试专业网站&#xff01; (cnitpm.com) 2023年下半年信息系统项目管理师报名时间将于8月14日开始&#xff0c;各地报名时间不同&#xff0c;请考生注意查看当地报名时间&#xff0c;但报名官网入口是统一的&#xff0c;均在中国计算机技术…