在B端业务中常见
系统模块分类为:cms系统,crm系统,会员系统,订单管理,采购管理,wms仓储管理,财务管理,供应商管理,质检系统等;
常见服务:文件图片上传服务,物流服务,商品搜索服务,订单服务,会员服务等;
开发语言:php+golang
在上述介绍的模块中,采用分布式部署方案,在公司业务发展壮大后,会遇到各个系统业务流转,获取数据,分发,同步数据等问题,常见的有:消息队列异步任务,定时任务。
异步任务分发(处理完订单或者某一个流程后需要异步通知其它系统或者发送消息),一般采用队列监听(异步任务消息即可);
报表,统计等需要定时任务完成;
但是在系统、服务越来越多的情况下,服务器上运行的队列服务将会很庞大,十几台乃至几十台服务器有各种不同的服务很难以管理
注:像一次性任务,比如golang任务发布,打包部署等可以采取jenkins来部署
1,定时任务采取方案就是找一套开源的或者自己开发一套分布式任务管理系统
2,任务分发
像订单审核后同步订单到采购,采购单同步到wms 入库单同步wms 发货单,收款单,等各个系统衔接的数据对接如果按照普通api接口会影响业务性能
分布式任务管理系统介绍:
后台php,服务用golang开发(1,对接后台api接口,新增一次性任务和定时任务,2.处理任务),采用golang+etcd+mongodb
部署方案:
学习golang的分布式任务之前先学习协etcd的使用,重点需要学习etcd的 续租,watch监听key
etcd的安装
etcd的使用
golang分布式任务主要分为
master 服务端 主要提供后台操作的api,添加定时任务和一次性任务到etcd中,对任务进行增删改查 日志 服务发现 服务注册等功能
worker 客户端 主要监听etcd中的任务(与自己服务器ip相关的任务) 一次性任务立即执行即可,定时任务解析表达式后,放入内存中,定时执行
woker执行流程:.
githu地址:https://github.com/sunlongv520/go-crontab
code可以手动向etcd添加任务 或者删除任务
package main
import (
"context"
"fmt"
"github.com/coreos/etcd/clientv3"
"time"
)
func main(){
var (
config clientv3.Config
err error
client *clientv3.Client
kv clientv3.KV
getResp *clientv3.GetResponse
)
//配置
config = clientv3.Config{
Endpoints:[]string{"192.168.2.232:2379"},
DialTimeout:time.Second*5,
}
//连接 床见一个客户端
if client,err = clientv3.New(config);err != nil{
fmt.Println(err)
return
}
//用于读写etcd的键值对
kv = clientv3.NewKV(client)
//删除key
//kv.Delete(context.TODO(),"/cron/jobs/192.168.2.246/job1",clientv3.WithPrefix())
//kv.Delete(context.TODO(),"/cron/jobs",clientv3.WithPrefix())
//kv.Delete(context.TODO(),"/cron/oncejobs",clientv3.WithPrefix())
//
//return
//新增定时任务
//putResp, err := kv.Put(context.TODO(),"/cron/jobs/192.168.2.232/job2","{\"name\":\"job2\",\"command\":\"D:/phpstudy/PHPTutorial/php/php-5.6.27-nts/php E:/WWW/a.php\",\"cronExpr\":\"*/7 * * * * * *\"}",clientv3.WithPrevKV())
//putResp, err := kv.Put(context.TODO(),"/cron/jobs/192.168.2.246/job2","{\"name\":\"job2\",\"command\":\" echo hello world\",\"cronExpr\":\"*/5 * * * * * *\"}",clientv3.WithPrevKV())
//putResp, err := kv.Put(context.TODO(),"/cron/jobs/192.168.2.246/job3","{\"name\":\"job3\",\"command\":\" echo hello boy\",\"cronExpr\":\"*/10 * * * * * *\"}",clientv3.WithPrevKV())
//fmt.Println(putResp)
//fmt.Println(err)
//新增一次性任务
//putResp, err := kv.Put(context.TODO(),"/cron/oncejobs/192.168.2.232/job10","{\"name\":\"job10\",\"command\":\" echo hello world \"}",clientv3.WithPrevKV())
//强杀任务
//putResp, err := kv.Put(context.TODO(),"/cron/killer/192.168.2.246/job10","")
//
//if err != nil{
// fmt.Println(err)
//}else{
// fmt.Println("Revision:",putResp.Header.Revision)
// if putResp.PrevKv != nil{
// fmt.Println("key:",string(putResp.PrevKv.Key))
// fmt.Println("Value:",string(putResp.PrevKv.Value))
// fmt.Println("Version:",string(putResp.PrevKv.Version))
// }
//}
//查询
getResp,err = kv.Get(context.TODO(),"/cron/workers",clientv3.WithPrefix())
if err != nil {
fmt.Println(err)
return
}
for _, kvpair := range getResp.Kvs {
fmt.Println(kvpair)
}
getResp,err = kv.Get(context.TODO(),"/cron/jobs",clientv3.WithPrefix())
if err != nil {
fmt.Println(err)
return
}
for _, kvpair := range getResp.Kvs {
fmt.Println(kvpair)
}
getResp,err = kv.Get(context.TODO(),"/cron/oncejobs",clientv3.WithPrefix())
if err != nil {
fmt.Println(err)
return
}
for _, kvpair := range getResp.Kvs {
fmt.Println(kvpair)
}
}
View Code
** master:**
主要负责接收后台对任务的管理 提供api接口
go run .\master\main\master.go -config= .\master\main\master.json
** worker:**
监听任务,执行任务,任务调度
go run .\worker\main\worker.go -config=./worker\main\worker.json -logDir=./logs/worker
该套分布式任务管理开箱即用,如有疑问可以随时提问
项目框架解析: 供学习爱好者
#!/bin/bash
cd /data/gocode/golang_asynctask
git reset --hard HEAD
git pull origin master
filename="/data2/gocode/golang_asynctask/build/crm/sync_comuser_to_erp"
rm -f $filename
go build -o /data2/gocode/golang_asynctask/build/crm/sync_comuser_to_erp /data2/gocode/golang_asynctask/cmd/crm/sync_comuser_to_erp/main.go
supervisorctl restart crm_sync_comuser_to_erp:*
一次性任务脚本
一次性任务脚本