基础功能
定时任务
定时任务如果是遇到自定义的定时任务的时候
尽量采用每分钟去扫描缓存数据的方式,而不要创建成千上万的定时器
定时任务需要考虑不同服务器执行的时候只能有一台机器可以执行,而这个时候可以采用函数式适应所有的任务。
icon任务和分布式锁
//异步队列的定时器
crontab := cron.New()
//推送ecp通知
crontab.AddFunc(“”, service.EcpMsgSendTask)
crontab.Start()
func EcpMsgSendTask() {
removeExpiredValueKey := "EcpMsgSendTask"
uuid := util.GetUuid()
util.TodayRedis.ActionIfLock(removeExpiredValueKey, uuid, config.AppConfiguration.AutoRecoveryLockTime, EcpMsgSend)
}
func EcpMsgSend() {
defer util.HandlePanic("EcpMsgSend")
ctx := context.Background()
var filters []bson.M
groupFilter := bson.M{
"$group": bson.M{
"_id": bson.M{"account": "$account"},
"count": bson.M{"$sum": 1},
"userId": bson.M{"$max": "$userId"},
"companyId": bson.M{"$max": "$companyId"}}}
match := bson.M{"$match": bson.M{"appId": "ecp"}}
filters = append(filters, match)
filters = append(filters, groupFilter)
datas, err := db.UserEcpBizIdGroup(ctx, filters)
if err != nil {
logger.Info("ecp定时器查库失败")
return
}
//初始化协程池
goroutinePool := &goroutine_pool.GoroutinePool{}
goroutinePool.StartPool(10)
//获取mgc请求地址
url, err := GetMgcUrl()
if err != nil {
logger.Info("GetMgcUrl:", err)
return
}
logger.Info("SendMsg:url:", url)
sendAccount := config.PageConfiguration.SendAccount
var all bool
if len(sendAccount) == 0 {
all = true
}
now := time.Now().String()
for _, data := range datas {
marshal, err := json.Marshal(data)
if err != nil {
logger.Error("data:Marshal异常", err)
}
var countData CountData
err = json.Unmarshal(marshal, &countData)
if err != nil {
logger.Error("data:Marshal异常", err)
}
//白名单控制
if all || collection.Collect(sendAccount).Contains(countData.Id.Account) {
//放入协程池处理
logger.Info(countData.Id.Account, ":SendMsg:", countData.Count, ":time:", now)
goroutinePool.Dispatch(SendMsg, countData, url)
}
}
goroutinePool.StopPool()
}
func (p *RedisPool) ActionIfLock(key string, value interface{}, timeOut int, handler Distributed) {
if ok := p.getLock(key, value, timeOut); ok {
handler()
p.unlock(key, value)
}
}
周期任务Ticker的使用,
如果是每个人有自己的ticker,用map去保存,当任务停止的时候就能主动停止任务。
https://blog.csdn.net/weixin_34227447/article/details/91699679
定时任务
https://blog.csdn.net/qq_39503880/article/details/114088176
来自网络的例子
package main
import (
"fmt"
"time"
)
func main() {
d := time.Duration(time.Second * 2)
t1 := time.NewTicker(d)
defer t1.Stop()
go func() {
for {
<- t1.C
fmt.Println("NewTicker...")
}
}()
t2 := time.NewTimer(d)
defer t2.Stop()
go func() {
for {
<- t2.C
fmt.Println("NewTimer...")
}
}()
for {
select {
case <- time.After(d):
fmt.Println("select...")
}
}
}
定时任务
package main
import (
"fmt"
"time"
)
func main() {
var ch chan int
//定时任务
ticker := time.NewTicker(time.Second * 5)
go func() {
for range ticker.C {
fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}
ch <- 1
}()
<-ch
}