http通知转达
说明
此转达库目的是让消息一定转达成功,利用数据库事务来实现,只适合gorm支持的数据库,消息至少到达一次。
相比MQ服务,减少了学习和部署成本,并更高效。
安装
go get -u gitee.com/xy02/goutil@v0.2
使用
import (
"log"
"gorm.io/driver/mysql"
"gorm.io/gorm"
n "gitee.com/xy02/goutil/notification"
)
//用于测试的业务模型
type Test struct {
gorm.Model
// ID string `gorm:"primaryKey; type:varchar(255);"`
}
func main() {
//初始化数据库客户端
db, err := gorm.Open(mysql.Open("root:password@tcp(localhost:3306)/test?charset=utf8&parseTime=true&loc=Local"),
&gorm.Config{
SkipDefaultTransaction: true,
})
if err != nil {
log.Panicln(err)
}
//自动建表
db.AutoMigrate(&Test{})
//创建新的通知器,此通知器会自动轮询发送未成功通知,如果有多个目标服务,请创建多个Notifier实例
notifier, err := n.NewNotifier(db, n.Options{
ServiceName: "test",
})
if err != nil {
log.Panicln(err)
}
//以上是初始化代码,请重复使用上面的实例,以下是业务代码
err = onSaveBusinessData(db, notifier)
if err != nil {
log.Panicln(err)
}
//阻塞主携程,关闭接收服务测试
forever := make(chan int)
<-forever
}
func onSaveBusinessData(db *gorm.DB, notifier *n.Notifier) error {
//创建需要通知的消息,默认POST发送json数据
m, err := notifier.NewNotifierMessage(n.Message{
Hosts: "http://localhost:7001, http://127.0.0.1:7001", //随机请求hosts其中之一,得到一个成功的应答
Path: "/test",
Data: []byte(`{"propA":"测试"}`),
})
if err != nil {
return err
}
//与业务数据在同一个事务中记录到数据库,一起成功或失败
if err := db.Transaction(func(tx *gorm.DB) error {
//业务的事务逻辑
if err := tx.Create(&Test{}).Error; err != nil {
// return any error will rollback
return err
}
//同时记录要通知的消息
if err := tx.Create(m).Error; err != nil {
return err
}
// return nil will commit the whole transaction
return nil
}); err != nil {
return err
}
//在事务之后发送通知
res, err := notifier.Notify(m)
log.Println(res)
return err
}