前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go-zero 成长之路—微服务电商实战系列(七、并发处理工具MapReduce的使用)

go-zero 成长之路—微服务电商实战系列(七、并发处理工具MapReduce的使用)

原创
作者头像
GoLang成长之路
修改2022-10-20 18:13:04
5560
修改2022-10-20 18:13:04
举报

该系列源码已开源:

枫零落/microShop
枫零落/microShop

1. 概述

大家都知道:go-zeroapi服务需要通过api文件进行定义。其中返回值的类型定义中并没有支持time.Time的类型。

那问题来了:如果在返回值中需要时间的结果,针对sqlxgorm模型定义的time.Time的时间类型应该怎么处理呢?

接下来咱们就以产品服务版块中的产品列表的返回结果来说明如何解决的!

如果历史文章不是很清楚的,可通过如下传送门:

2. go-zero返回结果中实现 time.Time 的处理

在这里咱们用到了:并发处理工具MapReduce,具体的工具介绍参考:https://legacy.go-zero.dev/cn/mapreduce.html

MapReducego-zero 框架中自带的,不需要额外安装。

MapReduce使用注意事项

  • mapperreducer中都可以调用cancel,参数为error,调用后立即返回,返回结果为nil, error
  • mapper中如果不调用writer.Writeitem最终不会被reducer聚合
  • reducer中如果不调用writer.Wirte则返回结果为nil, ErrReduceNoOutput
  • reducer为单线程,所有mapper出来的结果在这里串行聚合

使用流程:

  1. generate 产生需要使用数据
  2. mapper 处理 generate 产生的数据
  3. mappermapper 的数据进行聚合处理,然后输出到结果
  4. mapper 返回的结果:interface{} 通过 json.Marshaljson.Unmarshal 处理成想要的数据

完整代码如下:

代码语言:go
复制
productsData, productsDataErr := mr.MapReduce(func(source chan<- interface{}) {
	// 这里是 generate | 将列表的下标值记录到 chan
	// 传入到 mapper
	for key := range products {
		source <- key
	}
}, func(item interface{}, writer mr.Writer, cancel func(error)) {
	// 这里是 mapper | 处理存入的 chan
	key := item.(int)
	// 写入到 reducer
	writer.Write(key)
}, func(pipe <-chan interface{}, writer mr.Writer, cancel func(error)) {
	// 处理 reducer | 对 mapper 进行数据聚合
	productsData := []types.ProductItem{}
	productsDataMap := []any{}
	for p := range pipe {
		itemOne := products[p.(int)]
		FormatString := "2006-01-02 15:04:05"
		product := types.ProductItem{
			ID:          int64(itemOne.Id),
			Title:       itemOne.Title,
			CoverPic:    itemOne.CoverPic,
			Property:    itemOne.Property,
			MtPrice:     itemOne.MtPrice,
			DisPrice:    itemOne.DisPrice,
			Stock:       int64(itemOne.Stock),
			State:       int64(itemOne.State),
			SalesVolume: itemOne.SalesVolume,
			Images:      itemOne.Images,
			Detail:      itemOne.Detail,
			CreateTime:  itemOne.CreateTime.Format(FormatString),
			UpdateTime:  itemOne.UpdateTime.Format(FormatString),
		}
		// 插入 []数组
		productsDataMap = append(productsDataMap, product)
		// interface 转  []types.ProductItem{}
		productsDataJson, _ := json.Marshal(productsDataMap)
		json.Unmarshal(productsDataJson, &productsData)
	}
	// 输出到结果
	writer.Write(productsData)
})

if productsDataErr != nil {
	return nil, errorx.NewDefaultError(productsDataErr.Error())
}

productsDataList := []*types.ProductItem{}
// 对 MapReduce 结果进行转换 | 因为 MapReduce 返回的结果是 interface{} 跟咱们返回的Data类型不一致
// interface 转  []*types.ProductItem{}
productsDataJson, _ := json.Marshal(productsData)
json.Unmarshal(productsDataJson, &productsDataList)

3. 结束语

本篇文章介绍说明了在开发过程中会出现的一些清情况:

  • 检索条件的组合
  • 分页条数的计算
  • 检索条件的sql语句格式化输出
  • 数据的返回

另外,如果你感兴趣,非常欢迎你加入,我们一起来完成这个项目,为社区献出自己的一份力。

希望本篇文章对你有所帮助,谢谢。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 概述
  • 2. go-zero返回结果中实现 time.Time 的处理
  • 3. 结束语
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档