go: Parallelism Pattern

项目结构:

image

 

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:25
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : settings.go
*/
package config

import (
	"os"
	"path/filepath"
)

// 基础路径
var BaseDir, _ = filepath.Abs(".")
var ImageSaveDir = filepath.Join(BaseDir, "jewelry_images")
var LogDir = filepath.Join(BaseDir, "logs")

// 并发池配置
const (
	ThreadMaxWorkers  = 16 // IO密集worker数量
	ProcessMaxWorkers = 4  // CPU密集worker数量
)

// 业务模拟数据量
const (
	JewelryCount = 100
	OrderCount   = 50
	WarehouseCnt = 5
)

func InitDir() error {
	if err := os.MkdirAll(ImageSaveDir, 0755); err != nil {
		return err
	}
	if err := os.MkdirAll(LogDir, 0755); err != nil {
		return err
	}
	return nil
}





/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式 go get github.com/rs/zerolog
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:25
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : logger.go
*/
package utils

import (
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"godesginpattern/parallelism/config"
	"os"
	"path/filepath"
	"time"
)

var Logger zerolog.Logger

func InitLogger() {
	dateStr := time.Now().Format("2006-01-02")
	logPath := filepath.Join(config.LogDir, "jewelry_"+dateStr+".log")
	file, err := os.OpenFile(logPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
	if err != nil {
		panic("init log file failed: " + err.Error())
	}

	multi := zerolog.MultiLevelWriter(os.Stdout, file)
	Logger = zerolog.New(multi).With().Timestamp().Logger()
	log.Logger = Logger
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : parallel.go
*/
package utils

import (
	"fmt"
	"godesginpattern/parallelism/config"
	"sync"
)

// TaskFunc 通用任务函数签名
type TaskFunc[T any] func(item T) string

// ParallelPool 通用并发执行池
type ParallelPool[T any] struct {
	maxWorker int
	taskFunc  TaskFunc[T]
	inputList []T
	wg        sync.WaitGroup
	inputChan chan T
}

func NewParallelPool[T any](maxWorker int, fn TaskFunc[T], list []T) *ParallelPool[T] {
	return &ParallelPool[T]{
		maxWorker: maxWorker,
		taskFunc:  fn,
		inputList: list,
		inputChan: make(chan T, len(list)),
	}
}

func (p *ParallelPool[T]) Run() []string {
	var results []string
	var mu sync.Mutex

	// 填充任务通道
	go func() {
		for _, item := range p.inputList {
			p.inputChan <- item
		}
		close(p.inputChan)
	}()

	// 启动worker
	for i := 0; i < p.maxWorker; i++ {
		p.wg.Add(1)
		go func() {
			defer p.wg.Done()
			for item := range p.inputChan {
				res, err := p.runSingle(item)
				mu.Lock()
				results = append(results, res)
				mu.Unlock()
				if err != nil {
					Logger.Error().Msg(res)
				} else {
					Logger.Info().Msg(res)
				}
			}
		}()
	}
	p.wg.Wait()
	return results
}

func (p *ParallelPool[T]) runSingle(item T) (string, error) {
	defer func() {
		if r := recover(); r != nil {
			errMsg := fmt.Sprintf("任务panic: %v, item=%+v", r, item)
			Logger.Error().Msg(errMsg)
		}
	}()
	ret := p.taskFunc(item)
	return ret, nil
}

// 对外封装快捷方法
func RunIOTasks[T any](fn TaskFunc[T], list []T) []string {
	pool := NewParallelPool(config.ThreadMaxWorkers, fn, list)
	return pool.Run()
}

func RunCPUTasks[T any](fn TaskFunc[T], list []T) []string {
	pool := NewParallelPool(config.ProcessMaxWorkers, fn, list)
	return pool.Run()
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : entity.go
*/
package model

import (
	"fmt"
	"godesginpattern/parallelism/config"
)

// 业务实体
type Jewelry struct {
	ID string
}

type Order struct {
	ID string
}

type Warehouse struct {
	ID string
}

// EntityFactory 实体工厂,生成批量测试数据
type EntityFactory struct{}

func (e EntityFactory) GetJewelryList() []Jewelry {
	var list []Jewelry
	for i := 1; i <= config.JewelryCount; i++ {
		id := fmt.Sprintf("珠宝_%03d", i)
		list = append(list, Jewelry{ID: id})
	}
	return list
}

func (e EntityFactory) GetOrderList() []Order {
	var list []Order
	for i := 1; i <= config.OrderCount; i++ {
		id := fmt.Sprintf("订单_%03d", i)
		list = append(list, Order{ID: id})
	}
	return list
}

func (e EntityFactory) GetWarehouseList() []Warehouse {
	var list []Warehouse
	for i := 0; i < config.WarehouseCnt; i++ {
		char := rune('A' + i)
		id := fmt.Sprintf("仓库_%c", char)
		list = append(list, Warehouse{ID: id})
	}
	return list
}

  

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : quality.go
*/

// service 分层业务服务(单一职责)
package service

import (
	"fmt"
	"godesginpattern/parallelism/model"
	"math/rand"
	"time"
)

// 原料质检服务
func QualityInspect(j model.Jewelry) string {
	time.Sleep(200 * time.Millisecond)
	resList := []string{"合格", "不合格"}
	ret := resList[rand.Intn(2)]
	return fmt.Sprintf("【质检】%s:%s", j.ID, ret)
}




/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : image.go
*/
package service

import (
	"fmt"
	"godesginpattern/parallelism/config"
	"godesginpattern/parallelism/model"
	"godesginpattern/parallelism/utils"
	"os"
	"path/filepath"
	"time"
)

// 商品图片处理服务
func ProcessImage(j model.Jewelry) string {
	// 定义返回结果变量
	var result string

	defer func() {
		if r := recover(); r != nil {
			// 捕获panic,赋值给结果变量
			result = fmt.Sprintf("【图片处理】%s:失败 panic:%v", j.ID, r)
			utils.Logger.Error().Msg(result)
		}
	}()

	savePath := filepath.Join(config.ImageSaveDir, j.ID+".jpg")
	// 模拟生成图片,省去图片库依赖,仅流程模拟
	f, err := os.Create(savePath)
	if err != nil {
		msg := fmt.Sprintf("【图片处理】%s:失败 err:%s", j.ID, err.Error())
		utils.Logger.Error().Msg(msg)
		result = msg
		return result
	}
	_ = f.Close()
	time.Sleep(150 * time.Millisecond)

	// 正常成功结果
	result = fmt.Sprintf("【图片处理】%s:完成", j.ID)
	return result
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : stock.go
*/
package service

import (
	"fmt"
	"godesginpattern/parallelism/model"
	"math/rand"
	"time"
)

// 仓库盘点服务
func StockCheck(w model.Warehouse) string {
	time.Sleep(300 * time.Millisecond)
	num := rand.Intn(151) + 50
	return fmt.Sprintf("【库存盘点】%s:库存%d件", w.ID, num)
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : notice.go
*/
package service

import (
	"fmt"
	"godesginpattern/parallelism/model"
	"time"
)

// 订单发货通知服务
func SendShipNotice(o model.Order) string {
	time.Sleep(100 * time.Millisecond)
	return fmt.Sprintf("【发货通知】%s:已推送短信+邮件", o.ID)
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : cert.go
*/
package service

import (
	"fmt"
	"godesginpattern/parallelism/model"
	"math/rand"
	"time"
)

// 珠宝证书核验服务
func VerifyCertificate(j model.Jewelry) string {
	time.Sleep(250 * time.Millisecond)
	certNo := fmt.Sprintf("NGTC%06d", rand.Intn(900000)+100000)
	return fmt.Sprintf("【证书核验】%s:证书%s 有效", j.ID, certNo)
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:27
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : price.go
*/
package service

import (
	"fmt"
	"godesginpattern/parallelism/model"
	"math/rand"
	"time"
)
// 成本定价核算服务
func CalcPrice(j model.Jewelry) string {
	time.Sleep(220 * time.Millisecond)
	price := rand.Intn(49001) + 1000
	return fmt.Sprintf("【定价核算】%s:定价%d元", j.ID, price)
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Parallelism Pattern 并行模式
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:28
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : manager.go
*/
package task

import (
	"godesginpattern/parallelism/model"
	"godesginpattern/parallelism/service"
	"godesginpattern/parallelism/utils"
)

// 任务编排中心
type JewelryTaskManager struct {
	jewelryList []model.Jewelry
	orderList   []model.Order
	wareList    []model.Warehouse
}

func NewJewelryTaskManager() *JewelryTaskManager {
	factory := model.EntityFactory{}
	return &JewelryTaskManager{
		jewelryList: factory.GetJewelryList(),
		orderList:   factory.GetOrderList(),
		wareList:    factory.GetWarehouseList(),
	}
}

func (m *JewelryTaskManager) RunAll() {
	// IO密集任务:图片、通知、仓库盘点
	utils.RunIOTasks(service.ProcessImage, m.jewelryList)
	utils.RunIOTasks(service.SendShipNotice, m.orderList)
	utils.RunIOTasks(service.StockCheck, m.wareList)

	// CPU密集任务:质检、证书核验、定价核算
	utils.RunCPUTasks(service.QualityInspect, m.jewelryList)
	utils.RunCPUTasks(service.VerifyCertificate, m.jewelryList)
	utils.RunCPUTasks(service.CalcPrice, m.jewelryList)
}

  

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:
# Author    : geovindu,Geovin Du 涂聚文.
# IDE       : goLang 2024.3.6 go 26.2
# os        : windows 10
# database  : mysql 9.0 sql server 2019, postgreSQL 17.0  Oracle 21c Neo4j
# Datetime  : 2026/6/19 14:42
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : parallelismbll.go
*/
package bll

import (
	"godesginpattern/parallelism/config"
	"godesginpattern/parallelism/task"
	"godesginpattern/parallelism/utils"
	"math/rand"
	"time"
)

func ParallelismMain() {
	rand.Seed(time.Now().UnixMilli())
	// 初始化目录
	if err := config.InitDir(); err != nil {
		panic("create dir failed: " + err.Error())
	}
	// 初始化日志
	utils.InitLogger()
	utils.Logger.Info().Msg("=== Go企业级珠宝并行任务系统 启动 ===")

	start := time.Now()
	// 执行全业务并行任务
	manager := task.NewJewelryTaskManager()
	manager.RunAll()

	cost := time.Since(start).Seconds()
	utils.Logger.Info().Float64("cost_sec", cost).Msg("=== 系统执行完成 ===")
}

  

输出:

image

 

posted @ 2026-06-19 15:00  ®Geovin Du Dream Park™  阅读(7)  评论(0)    收藏  举报