规划消费者
This commit is contained in:
		| @ -9,8 +9,6 @@ package delay | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  |  | ||||||
| 	"github.com/go-redis/redis/v8" |  | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // IProduce 生产者约束 | // IProduce 生产者约束 | ||||||
| @ -30,9 +28,9 @@ type IProduce interface { | |||||||
| // Date : 10:19 2022/7/7 | // Date : 10:19 2022/7/7 | ||||||
| type IConsumer interface { | type IConsumer interface { | ||||||
| 	// Consume 消费数据 | 	// Consume 消费数据 | ||||||
| 	Consume(queueName string) ([]*redis.Z, error) | 	Consume(ctx context.Context) ([]*ZRangeData, error) | ||||||
| 	// ConsumeWithHandler 消费数据并使用handler处理 | 	// ConsumeWithHandler 消费数据并使用handler处理 | ||||||
| 	ConsumeWithHandler(queueName string, handler IHandler) error | 	ConsumeWithHandler(ctx context.Context, handler IHandler) error | ||||||
| } | } | ||||||
|  |  | ||||||
| // IHandler 消息的处理 | // IHandler 消息的处理 | ||||||
| @ -42,5 +40,5 @@ type IConsumer interface { | |||||||
| // Date : 10:26 2022/7/7 | // Date : 10:26 2022/7/7 | ||||||
| type IHandler interface { | type IHandler interface { | ||||||
| 	// Handle 处理消费到的数据 | 	// Handle 处理消费到的数据 | ||||||
| 	Handle(queData []*ProduceData) error | 	Handle(queData []*ZRangeData) error | ||||||
| } | } | ||||||
|  | |||||||
| @ -19,6 +19,16 @@ type ProduceData struct { | |||||||
| 	Data      map[string]interface{} `json:"data"`      // 传入的业务数据 | 	Data      map[string]interface{} `json:"data"`      // 传入的业务数据 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ZRangeData zRange读取的数据 | ||||||
|  | // | ||||||
|  | // Author : go_developer@163.com<白茶清欢> | ||||||
|  | // | ||||||
|  | // Date : 14:24 2022/7/8 | ||||||
|  | type ZRangeData struct { | ||||||
|  | 	Score int64        // 数据分值 | ||||||
|  | 	Data  *ProduceData // 实际业务数据 | ||||||
|  | } | ||||||
|  |  | ||||||
| // Queue 队列数据 | // Queue 队列数据 | ||||||
| // | // | ||||||
| // Author : go_developer@163.com<白茶清欢> | // Author : go_developer@163.com<白茶清欢> | ||||||
| @ -39,3 +49,15 @@ type Queue struct { | |||||||
| func (q *Queue) Err() error { | func (q *Queue) Err() error { | ||||||
| 	return q.err | 	return q.err | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ConsumerConfig 消费者配置 | ||||||
|  | // | ||||||
|  | // Author : go_developer@163.com<白茶清欢> | ||||||
|  | // | ||||||
|  | // Date : 14:12 2022/7/8 | ||||||
|  | type ConsumerConfig struct { | ||||||
|  | 	QueueName   string // 队列名称 | ||||||
|  | 	SonQueueCnt int    // 二级队列数量 | ||||||
|  | 	SonQueName  string // 二级队列名称 | ||||||
|  | 	HashKey     string // hash消息写到哪个二级队列的key, 若不配置或者key不存在, 使用 ProduceData.MsgID | ||||||
|  | } | ||||||
|  | |||||||
							
								
								
									
										96
									
								
								delay/redis_dispatch_consumer.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								delay/redis_dispatch_consumer.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,96 @@ | |||||||
|  | // Package delay ... | ||||||
|  | // | ||||||
|  | // Description : delay ... | ||||||
|  | // | ||||||
|  | // Author : go_developer@163.com<白茶清欢> | ||||||
|  | // | ||||||
|  | // Date : 2022-07-07 10:32 | ||||||
|  | package delay | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"errors" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"github.com/go-redis/redis/v8" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // NewRedisConsumer redis延迟队列消费者 | ||||||
|  | // | ||||||
|  | // Author : go_developer@163.com<白茶清欢> | ||||||
|  | // | ||||||
|  | // Date : 14:10 2022/7/8 | ||||||
|  | func NewRedisConsumer(redisInstance *redis.Client, cfg *ConsumerConfig) IConsumer { | ||||||
|  | 	return &redisConsumer{ | ||||||
|  | 		redisInstance: redisInstance, | ||||||
|  | 		cfg:           cfg, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type redisConsumer struct { | ||||||
|  | 	redisInstance *redis.Client | ||||||
|  | 	cfg           *ConsumerConfig | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *redisConsumer) Consume(ctx context.Context) ([]*ZRangeData, error) { | ||||||
|  | 	if nil == ctx { | ||||||
|  | 		ctx = context.Background() | ||||||
|  | 	} | ||||||
|  | 	zRangeResult := r.redisInstance.ZRange(ctx, r.cfg.QueueName, 0, time.Now().UnixNano()/1e6) | ||||||
|  | 	if err := zRangeResult.Err(); nil != err { | ||||||
|  | 		return make([]*ZRangeData, 0), err | ||||||
|  | 	} | ||||||
|  | 	// 格式化数据 | ||||||
|  | 	var ( | ||||||
|  | 		result []*ZRangeData | ||||||
|  | 	) | ||||||
|  | 	if err := json.Unmarshal([]byte(zRangeResult.String()), &result); nil != err { | ||||||
|  | 		return make([]*ZRangeData, 0), err | ||||||
|  | 	} | ||||||
|  | 	return result, nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r *redisConsumer) ConsumeWithHandler(ctx context.Context, handler IHandler) error { | ||||||
|  | 	if nil == handler { | ||||||
|  | 		return errors.New("handler instance is nil") | ||||||
|  | 	} | ||||||
|  | 	var ( | ||||||
|  | 		msgList []*ZRangeData | ||||||
|  | 		err     error | ||||||
|  | 	) | ||||||
|  |  | ||||||
|  | 	if msgList, err = r.Consume(ctx); nil != err { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// 未订阅到消息 | ||||||
|  | 	if len(msgList) == 0 { | ||||||
|  | 		return nil | ||||||
|  | 	} | ||||||
|  | 	return handler.Handle(msgList) | ||||||
|  | 	/* wg := &sync.WaitGroup{} | ||||||
|  | 	wg.Add(len(msgList)) | ||||||
|  | 	for _, item := range msgList { | ||||||
|  |  | ||||||
|  | 		go func(msgData *ZRangeData) { | ||||||
|  | 			defer wg.Done() | ||||||
|  | 			hashValue, exist := msgData.Data.Data[r.cfg.HashKey] | ||||||
|  | 			if !exist || hashValue == nil { | ||||||
|  | 				hashValue = msgData.Data.MsgID | ||||||
|  | 			} | ||||||
|  | 			shard := util.Hash.GetHashIDMod(hashValue, r.cfg.SonQueueCnt) | ||||||
|  | 			realQueue := fmt.Sprintf(r.cfg.QueueName+"_%d", shard) | ||||||
|  | 			r.redisInstance.LPush() | ||||||
|  | 		}(item) | ||||||
|  | 	} | ||||||
|  | 	wg.Wait() | ||||||
|  | 	return nil*/ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type redisConsumerMsgHandler struct { | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r redisConsumerMsgHandler) Handle(queData []*ZRangeData) error { | ||||||
|  | 	panic("implement me") | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user