惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
T
The Blog of Author Tim Ferriss
P
Proofpoint News Feed
T
Threat Research - Cisco Blogs
T
The Exploit Database - CXSecurity.com
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cybersecurity and Infrastructure Security Agency CISA
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Martin Fowler
Martin Fowler
GbyAI
GbyAI
P
Palo Alto Networks Blog
N
Netflix TechBlog - Medium
C
Cisco Blogs
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
A
About on SuperTechFans
PCI Perspectives
PCI Perspectives
Scott Helme
Scott Helme
TaoSecurity Blog
TaoSecurity Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
K
Kaspersky official blog
W
WeLiveSecurity
Y
Y Combinator Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
有赞技术团队
有赞技术团队
人人都是产品经理
人人都是产品经理
月光博客
月光博客
N
News | PayPal Newsroom
Microsoft Azure Blog
Microsoft Azure Blog
G
GRAHAM CLULEY
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
MongoDB | Blog
MongoDB | Blog
V
V2EX
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Know Your Adversary
Know Your Adversary
博客园 - Franky
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
F
Full Disclosure
V
Vulnerabilities – Threatpost
V
Visual Studio Blog
Forbes - Security
Forbes - Security
Attack and Defense Labs
Attack and Defense Labs
MyScale Blog
MyScale Blog
Hacker News: Ask HN
Hacker News: Ask HN
T
Tor Project blog

博客园 - ®Geovin Du Dream Park™

go: Functional Options Pattern go:Timing Functions Pattern python: Timing Functions Pattern go: Steady-State Pattern python: Steady-State Pattern go: Handshaking Pattern python: Handshaking Pattern go: Fail-Fast Pattern python: Fail-Fast Pattern I go: Deadline Pattern python: Deadline Pattern go: Circuit-Breaker Pattern python: Circuit-Breaker Pattern go: Bulkheads Pattern python: Bulkheads Pattern python: Push & Pull Pattern python: Publish/Subscribe Pattern II go: Publish/Subscribe Pattern python: Publish/Subscribe Pattern go: Futures & Promises Pattern python: Futures & Promises Pattern go: Worker Pool Pattern go:Pipeline Pattern python: Worker Pool Pattern python: Pipeline Pattern go: Fan-Out Pattern python: Fan-Out Pattern go: Fan-In Pattern python: Fan-In Pattern Fan-In go: Producer Consumer  Pattern python: Producer Consumer Pattern go: Parallelism Pattern python: Parallelism Pattern go: Reactor Pattern python: Reactor Pattern go: Generators Pattern python: speech to text offline python: Generators Pattern go: Coroutines Pattern python:Coroutines Pattern go: Broadcast Pattern python: Broadcast Pattern python: Bounded Parallelism Pattern go: Bounded Parallelism Pattern python: N-Barrier Pattern go: N-Barrier Pattern python: Semaphore Pattern go: Semaphore Pattern python: Read-Write Lock Pattern go: Read-Write Lock Pattern python: Monitor Pattern go: Monitor Pattern python: Mutex Pattern go: Lock/Mutex Pattern Python: Condition Variable Pattern go:Condition Variable Pattern python: Registry Pattern python: Interpreter Pattern go: Interpreter Pattern go: Registry Pattern go: Memento Pattern go: Command Pattern go: State Pattern go:Template Method Pattern go: Strategy Pattern go: Visitor Pattern go: Observer Pattern go: Mediator Pattern go: Iterator Pattern go: Chain of Responsibility Pattern go: Proxy Pattern go:Decorator Pattern go: Facade Pattern go: Flyweight Pattern go: Composite Pattern go: Singleton Pattern go: Prototype Pattern go: Bridge Pattern go: Adapter Pattern go: Builder Pattern 密码进行加盐哈希 using CSharp,Python,Go,Java go: Abstract Factory Pattern go: Model,Interface,DAL ,Factory,BLL using mysql go: Simple Factory Pattern go: Factory Method Pattern go: goLang 在Windows环境搭建Go语言开发环境 CSharp: Parallel Extensions cpp: class python: 蝴蝶跟随鼠标 javascript: 中国历史人物热力分布图using echart javascript: 中国历史人物热力图 python: 初养龙虾微信纯文字自动回复using workBuddy python: object 入门 python: Factory Method Pattern python: Simple Factory Pattern python: Abstract Factory Pattern 区域化 代码 python: Null Object Pattern python: Builder Pattern python: Adapter Pattern
go: Push & Pull Pattern
®Geovin Du Dream Park™ · 2026-06-25 · via 博客园 - ®Geovin Du Dream Park™

项目结构:

image

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:25
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : config.go
*/
package config

import "time"

// ZMQ 端口 go get github.com/zeromq/goczmq
const (
	PortRawMaterial = 5555
	PortProcess     = 5556
	PortQuality     = 5557
	PortSale        = 5558
)

// 超时毫秒
const ZmqTimeoutMs = 3000

// 消息分隔符
const (
	MsgSep = "|"
	KvSep  = ":"
)

// 连接地址
const (
	LocalTcpAddr = "tcp://localhost"
	BindAddr     = "tcp://*"
)

// 珠宝品类常量
var JewelryCategory = []string{
	"钻石戒指", "黄金项链", "翡翠手镯", "铂金耳钉", "彩宝吊坠",
}

// 质检等级
var QualityGrade = []string{
	"S级(收藏)", "A级(精品)", "B级(常规)", "C级(特价)",
}

// 休眠间隔
const (
	SleepRaw     = 2 * time.Second
	SleepProcess = 1 * time.Second
	SleepQuality = 500 * time.Millisecond
	SleepSale    = 1 * time.Second
	IdleSleep    = 100 * time.Millisecond // 无消息空转休眠
)



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : logger.go
*/
package utils

import (
	"fmt"
	"log"
	"os"
	"time"
)

func GetLogger(module string) *log.Logger {
	prefix := fmt.Sprintf("[%s] ", module)
	logger := log.New(os.Stdout, prefix, log.LstdFlags)
	return logger
}

// 格式化时间输出辅助
func NowStr() string {
	return time.Now().Format("2006-01-02 15:04:05")
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : message.go
*/
package model

import (
	"godesginpattern/pushpull/config"
	"strings"
)

// BaseMessage 统一消息打包解包
type BaseMessage struct{}

// Pack map 转消息字符串
// 首字母大写,跨包可访问
var MsgHelper = &BaseMessage{}

func (b *BaseMessage) Pack(data map[string]string) string {
	var parts []string
	for k, v := range data {
		parts = append(parts, k+config.KvSep+v)
	}
	return strings.Join(parts, config.MsgSep)
}

func (b *BaseMessage) Unpack(raw string) map[string]string {
	res := make(map[string]string)
	items := strings.Split(raw, config.MsgSep)
	for _, item := range items {
		kv := strings.SplitN(item, config.KvSep, 2)
		if len(kv) == 2 {
			res[kv[0]] = kv[1]
		}
	}
	return res
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:25
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : socket_factory.go
*/

package core

import (
	"bufio"
	"fmt"
	"godesginpattern/pushpull/config"
	"godesginpattern/pushpull/utils"
	"io"
	"net"
	"sync"
	"time"
)

var logger = utils.GetLogger("SocketFactory")

type TcpPushSocket struct {
	listener net.Listener
	clients  []net.Conn
	mu       sync.Mutex
}

func NewTcpPushSocket(port int) *TcpPushSocket {
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port))
	if err != nil {
		logger.Fatalf("创建Push监听失败: %v", err)
	}
	sock := &TcpPushSocket{listener: listener}
	go sock.acceptLoop()
	logger.Printf("Push 绑定成功: tcp://localhost:%d", port)
	return sock
}

func (s *TcpPushSocket) acceptLoop() {
	for {
		conn, err := s.listener.Accept()
		if err != nil {
			logger.Printf("Accept错误: %v", err)
			return
		}
		s.mu.Lock()
		s.clients = append(s.clients, conn)
		s.mu.Unlock()
		logger.Printf("新客户端连接: %s", conn.RemoteAddr())
	}
}

func (s *TcpPushSocket) Send(msg string) (int, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, conn := range s.clients {
		conn.SetWriteDeadline(time.Now().Add(time.Duration(config.ZmqTimeoutMs) * time.Millisecond))
		if _, err := conn.Write([]byte(msg + "\n")); err != nil {
			logger.Printf("发送失败: %v", err)
		}
	}
	return len(msg), nil
}

func (s *TcpPushSocket) Close() {
	s.mu.Lock()
	defer s.mu.Unlock()
	for _, conn := range s.clients {
		conn.Close()
	}
	s.listener.Close()
}

type TcpPullSocket struct {
	conn   net.Conn
	reader *bufio.Reader
}

func NewTcpPullSocket(port int) *TcpPullSocket {
	conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port))
	if err != nil {
		logger.Fatalf("连接Push失败: %v", err)
	}
	logger.Printf("Pull 连接成功: tcp://localhost:%d", port)
	return &TcpPullSocket{
		conn:   conn,
		reader: bufio.NewReader(conn),
	}
}

var ErrConnectionClosed = fmt.Errorf("connection closed")

func (s *TcpPullSocket) Recv(nonBlocking bool) (string, error) {
	if nonBlocking {
		s.conn.SetReadDeadline(time.Now().Add(50 * time.Millisecond))
	} else {
		s.conn.SetReadDeadline(time.Now().Add(time.Duration(config.ZmqTimeoutMs) * time.Millisecond))
	}
	msg, err := s.reader.ReadString('\n')
	if err != nil {
		if nonBlocking && (err == bufio.ErrBufferFull || isTimeoutError(err)) {
			return "", fmt.Errorf("resource temporarily unavailable")
		}
		if err == io.EOF {
			return "", ErrConnectionClosed
		}
		return "", err
	}
	return msg[:len(msg)-1], nil
}

func (s *TcpPullSocket) Close() {
	s.conn.Close()
}

func isTimeoutError(err error) bool {
	if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
		return true
	}
	return false
}
/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : rawmaterial.go
*/

package service

import (
	"godesginpattern/pushpull/config"
	"godesginpattern/pushpull/core"
	"godesginpattern/pushpull/model"
	"godesginpattern/pushpull/utils"
	"math/rand"
	"strconv"
	"time"
)

var rawLog = utils.GetLogger("RawMaterialService")

type RawMaterialService struct {
	pushSock *core.TcpPushSocket
}

func NewRawMaterialService() *RawMaterialService {
	return &RawMaterialService{
		pushSock: core.NewTcpPushSocket(config.PortRawMaterial),
	}
}

func (r *RawMaterialService) RunProduce(total int) {
	rawLog.Println("原料采购服务启动")
	rand.Seed(time.Now().UnixNano())
	for i := 1; i <= total; i++ {
		cat := config.JewelryCategory[rand.Intn(len(config.JewelryCategory))]
		msg := model.MsgHelper.Pack(map[string]string{
			"type":     "原料订单",
			"order_id": "RAW_" + strconv.Itoa(i),
			"category": cat,
			"status":   "已采购待加工",
		})
		_, _ = r.pushSock.Send(msg)
		rawLog.Printf("推送: %s", msg)
		time.Sleep(config.SleepRaw)
	}
	rawLog.Println("原料订单全部推送完成")
	time.Sleep(time.Second)
	r.pushSock.Close()
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : process.go
*/

package service

import (
	"godesginpattern/pushpull/config"
	"godesginpattern/pushpull/core"
	"godesginpattern/pushpull/model"
	"godesginpattern/pushpull/utils"
	"math/rand"
	"strings"
	"time"
)

var procLog = utils.GetLogger("Process")

type ProcessService struct {
	pullSock *core.TcpPullSocket
	pushSock *core.TcpPushSocket
	done     chan struct{}
}

func NewProcessService() *ProcessService {
	return &ProcessService{
		pullSock: core.NewTcpPullSocket(config.PortRawMaterial),
		pushSock: core.NewTcpPushSocket(config.PortProcess),
		done:     make(chan struct{}),
	}
}

func (p *ProcessService) RunPipeline() {
	procLog.Println("加工车间启动")
	for {
		select {
		case <-p.done:
			procLog.Println("加工车间停止")
			return
		default:
			msg, err := p.pullSock.Recv(true)
			if err != nil {
				if err == core.ErrConnectionClosed {
					procLog.Println("加工车间连接关闭")
					return
				}
				if err.Error() == "resource temporarily unavailable" {
					time.Sleep(config.IdleSleep)
					continue
				}
				procLog.Printf("接收错误: %v", err)
				time.Sleep(config.IdleSleep)
				continue
			}

			data := model.MsgHelper.Unpack(msg)
			procLog.Printf("收到: %s", msg)
			time.Sleep(config.SleepProcess + time.Duration(rand.Intn(2000))*time.Millisecond)

			sendMsg := model.MsgHelper.Pack(map[string]string{
				"type":     "成品珠宝",
				"order_id": strings.Replace(data["order_id"], "RAW", "FIN", 1),
				"category": data["category"],
				"status":   "已加工待质检",
			})
			_, _ = p.pushSock.Send(sendMsg)
			procLog.Printf("加工完成: %s", sendMsg)
		}
	}
}

func (p *ProcessService) Stop() {
	close(p.done)
	p.pullSock.Close()
	p.pushSock.Close()
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : quality.go
*/

package service

import (
	"godesginpattern/pushpull/config"
	"godesginpattern/pushpull/core"
	"godesginpattern/pushpull/model"
	"godesginpattern/pushpull/utils"
	"math/rand"
	"time"
)

var qualityLog = utils.GetLogger("Quality")

type QualityService struct {
	pullSock *core.TcpPullSocket
	pushSock *core.TcpPushSocket
	done     chan struct{}
}

func NewQualityService() *QualityService {
	return &QualityService{
		pullSock: core.NewTcpPullSocket(config.PortProcess),
		pushSock: core.NewTcpPushSocket(config.PortQuality),
		done:     make(chan struct{}),
	}
}

func (q *QualityService) RunPipeline() {
	qualityLog.Println("质检中心启动")
	for {
		select {
		case <-q.done:
			qualityLog.Println("质检中心停止")
			return
		default:
			msg, err := q.pullSock.Recv(true)
			if err != nil {
				if err == core.ErrConnectionClosed {
					qualityLog.Println("质检中心连接关闭")
					return
				}
				if err.Error() == "resource temporarily unavailable" {
					time.Sleep(config.IdleSleep)
					continue
				}
				qualityLog.Printf("接收错误: %v", err)
				time.Sleep(config.IdleSleep)
				continue
			}

			data := model.MsgHelper.Unpack(msg)
			qualityLog.Printf("收到: %s", msg)
			time.Sleep(config.SleepQuality + time.Duration(rand.Intn(1500))*time.Millisecond)

			sendMsg := model.MsgHelper.Pack(map[string]string{
				"type":     "质检成品",
				"order_id": data["order_id"],
				"category": data["category"],
				"grade":    config.QualityGrade[rand.Intn(len(config.QualityGrade))],
				"status":   "可销售",
			})
			_, _ = q.pushSock.Send(sendMsg)
			qualityLog.Printf("质检完成: %s", sendMsg)
		}
	}
}

func (q *QualityService) Stop() {
	close(q.done)
	q.pullSock.Close()
	q.pushSock.Close()
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : sale.go
*/

package service

import (
	"godesginpattern/pushpull/config"
	"godesginpattern/pushpull/core"
	"godesginpattern/pushpull/model"
	"godesginpattern/pushpull/utils"
	"math/rand"
	"strconv"
	"strings"
	"time"
)

var saleLog = utils.GetLogger("Sale")

type SaleService struct {
	pullSock *core.TcpPullSocket
	pushSock *core.TcpPushSocket
	done     chan struct{}
}

func NewSaleService() *SaleService {
	return &SaleService{
		pullSock: core.NewTcpPullSocket(config.PortQuality),
		pushSock: core.NewTcpPushSocket(config.PortSale),
		done:     make(chan struct{}),
	}
}

func (s *SaleService) RunPipeline() {
	saleLog.Println("销售部启动")
	for {
		select {
		case <-s.done:
			saleLog.Println("销售部停止")
			return
		default:
			msg, err := s.pullSock.Recv(true)
			if err != nil {
				if err == core.ErrConnectionClosed {
					saleLog.Println("销售部连接关闭")
					return
				}
				if err.Error() == "resource temporarily unavailable" {
					time.Sleep(config.IdleSleep)
					continue
				}
				saleLog.Printf("接收错误: %v", err)
				time.Sleep(config.IdleSleep)
				continue
			}

			data := model.MsgHelper.Unpack(msg)
			saleLog.Printf("收到: %s", msg)
			time.Sleep(config.SleepSale + time.Duration(rand.Intn(1500))*time.Millisecond)

			sendMsg := model.MsgHelper.Pack(map[string]string{
				"type":     "销售完成",
				"order_id": strings.Replace(data["order_id"], "FIN", "SALE", 1),
				"category": data["category"],
				"price":    strconv.Itoa(rand.Intn(49000)+1000) + "元",
				"status":   "已售出",
			})
			_, _ = s.pushSock.Send(sendMsg)
			saleLog.Printf("销售完成: %s", sendMsg)
		}
	}
}

func (s *SaleService) Stop() {
	close(s.done)
	s.pullSock.Close()
	s.pushSock.Close()
}



/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : aftersale.go
*/

package service

import (
	"godesginpattern/pushpull/config"
	"godesginpattern/pushpull/core"
	"godesginpattern/pushpull/model"
	"godesginpattern/pushpull/utils"
	"time"
)

var afterLog = utils.GetLogger("AfterSale")

type AfterSaleService struct {
	pullSock *core.TcpPullSocket
	done     chan struct{}
}

func NewAfterSaleService() *AfterSaleService {
	return &AfterSaleService{
		pullSock: core.NewTcpPullSocket(config.PortSale),
		done:     make(chan struct{}),
	}
}

func (a *AfterSaleService) RunConsumer() {
	afterLog.Println("售后维保启动")
	for {
		select {
		case <-a.done:
			afterLog.Println("售后维保停止")
			return
		default:
			msg, err := a.pullSock.Recv(true)
			if err != nil {
				if err == core.ErrConnectionClosed {
					afterLog.Println("售后维保连接关闭")
					return
				}
				if err.Error() == "resource temporarily unavailable" {
					time.Sleep(config.IdleSleep)
					continue
				}
				afterLog.Printf("接收错误: %v", err)
				time.Sleep(config.IdleSleep)
				continue
			}

			data := model.MsgHelper.Unpack(msg)
			afterLog.Printf("收到单据: %s", msg)
			afterLog.Printf("✅ 维保生效 | 品类:%s | 订单:%s",
				data["category"], data["order_id"])
		}
	}
}

func (a *AfterSaleService) Stop() {
	close(a.done)
	a.pullSock.Close()
}

调用:

/*
# 版权所有  2026 ©涂聚文有限公司™ ®
# 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎
# 描述:Push & Pull  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/25 21:26
# User      :  geovindu
# Product   : GoLand
# Project   : godesginpattern
# File      : pushpullbll.go
*/

package bll

import (
	"godesginpattern/pushpull/service"
	"godesginpattern/pushpull/utils"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var ppLog = utils.GetLogger("pushpullbll")

func PushPullMain() {
	sig := make(chan os.Signal, 1)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)

	raw := service.NewRawMaterialService()
	proc := service.NewProcessService()
	quality := service.NewQualityService()
	sale := service.NewSaleService()
	after := service.NewAfterSaleService()

	go func() {
		<-sig
		ppLog.Println("退出中...")
		proc.Stop()
		quality.Stop()
		sale.Stop()
		after.Stop()
		os.Exit(0)
	}()

	go proc.RunPipeline()
	time.Sleep(200 * time.Millisecond)
	go quality.RunPipeline()
	time.Sleep(200 * time.Millisecond)
	go sale.RunPipeline()
	time.Sleep(200 * time.Millisecond)
	go after.RunConsumer()
	time.Sleep(200 * time.Millisecond)

	ppLog.Println("✅ 珠宝 Push-Pull 流水线启动完成")
	raw.RunProduce(5)

	time.Sleep(5 * time.Second)

	proc.Stop()
	quality.Stop()
	sale.Stop()
	after.Stop()

	ppLog.Println("✅ 珠宝 Push-Pull 流水线运行结束")
}

输出:

image

哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)