You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
2.9 KiB
Go
117 lines
2.9 KiB
Go
package producer
|
|
|
|
import (
|
|
"context"
|
|
"joybuywork/internal/app"
|
|
"joybuywork/internal/consts"
|
|
"joybuywork/internal/consts/ckey"
|
|
"joybuywork/internal/plugins/jsonm"
|
|
"joybuywork/internal/utils"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/Shopify/sarama"
|
|
"github.com/rs/xid"
|
|
"gits.branchcn.com/backend/microcode/plugins/derivative/delay"
|
|
"gits.branchcn.com/backend/microcode/plugins/kafka"
|
|
)
|
|
|
|
var AP *AsyncProducer
|
|
|
|
func SetUp() {
|
|
AP, _ = NewAsyncProducer(kafka.DefaultProducerConfig())
|
|
|
|
initCommonProducer()
|
|
}
|
|
|
|
type AsyncProducer struct {
|
|
producer sarama.AsyncProducer
|
|
}
|
|
|
|
func NewAsyncProducer(config *sarama.Config) (*AsyncProducer, error) {
|
|
p, err := app.Kafka.NewAsyncProducer(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
ap := &AsyncProducer{producer: p}
|
|
|
|
// 监听消息发送结果
|
|
app.GoSafe(ap.handleSuccesses, "默认生产者监听发送成功消息")
|
|
app.GoSafe(ap.handleErrors, "默认生产者监听发送错误消息")
|
|
|
|
return ap, nil
|
|
}
|
|
|
|
func (p *AsyncProducer) Produce(ctx context.Context, topic string, key string, value any, setHeader ...sarama.RecordHeader) (err error) {
|
|
b, err := jsonm.Marshal(value)
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
var headers = []sarama.RecordHeader{
|
|
{
|
|
Key: []byte(consts.CtxMsgId),
|
|
Value: []byte(xid.New().String()),
|
|
},
|
|
}
|
|
traceId := ctx.Value(consts.TraceIdKey)
|
|
if traceId == nil {
|
|
headers = append(headers, sarama.RecordHeader{
|
|
Key: []byte(consts.TraceIdKey),
|
|
Value: []byte(xid.New().String()),
|
|
})
|
|
} else {
|
|
headers = append(headers, sarama.RecordHeader{
|
|
Key: []byte(consts.TraceIdKey),
|
|
Value: []byte(traceId.(string)),
|
|
})
|
|
}
|
|
|
|
for _, header := range setHeader {
|
|
headers = append(headers, header)
|
|
}
|
|
|
|
m := &sarama.ProducerMessage{
|
|
Headers: headers,
|
|
Topic: topic,
|
|
Key: sarama.StringEncoder(key),
|
|
Value: sarama.ByteEncoder(b),
|
|
Timestamp: time.Now(),
|
|
}
|
|
|
|
p.producer.Input() <- m
|
|
return
|
|
}
|
|
|
|
func (p *AsyncProducer) handleSuccesses() {
|
|
for v := range p.producer.Successes() {
|
|
ctx := context.Background()
|
|
for _, header := range v.Headers {
|
|
ctx = context.WithValue(ctx, utils.Bs(header.Key), utils.Bs(header.Value))
|
|
}
|
|
|
|
key, _ := v.Key.Encode()
|
|
val, _ := v.Value.Encode()
|
|
app.Logger.Info(ctx, fmt.Sprintf("默认生产者发送消息成功, key: %s, val: %s", utils.Bs(key), utils.Bs(val)))
|
|
}
|
|
}
|
|
|
|
func (p *AsyncProducer) handleErrors() {
|
|
for v := range p.producer.Errors() {
|
|
ctx := context.Background()
|
|
for _, header := range v.Msg.Headers {
|
|
ctx = context.WithValue(ctx, utils.Bs(header.Key), utils.Bs(header.Value))
|
|
}
|
|
key, _ := v.Msg.Key.Encode()
|
|
val, _ := v.Msg.Value.Encode()
|
|
app.Logger.Info(ctx, fmt.Sprintf("默认生产者发送消息失败:%v, key: %s, val: %s", v.Err, utils.Bs(key), utils.Bs(val)))
|
|
}
|
|
}
|
|
|
|
var DelayCommon *delay.Producer
|
|
|
|
func initCommonProducer() {
|
|
DelayCommon = delay.NewRedisDelayQueue(context.Background(), app.Redis.Cache, ckey.DelayCommonKey()).Producer()
|
|
}
|