当前位置: 首页 > news >正文

go: Circuit-Breaker Pattern

项目结构:

断路器模式是稳定性设计模式的核心之一,核心作用:当依赖服务持续失败时,自动切断请求调用,避免级联故障、耗尽系统资源,保护核心业务流程。
它有 3 种状态:
关闭 (Closed):正常放行所有请求
打开 (Open):连续失败达到阈值,直接拦截请求,快速失败
半开 (Half-Open):超时后尝试放行少量请求,验证服务是否恢复

/* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:38 # User : geovindu # Product : GoLand # Project : godesginpattern # File : settings.go */ package config import "time" // CircuitBreakerConfig 断路器配置 type CircuitBreakerConfig struct { FailureThreshold int RecoveryTimeout time.Duration SuccessThreshold int } // JewelryBusinessConfig 珠宝业务配置 type JewelryBusinessConfig struct { FallbackGoldPrice float64 FailureRate float64 } // 全局单例配置 var ( CbConfig = CircuitBreakerConfig{ FailureThreshold: 3, RecoveryTimeout: 10 * time.Second, SuccessThreshold: 2, } JewelryConfig = JewelryBusinessConfig{ FallbackGoldPrice: 628.5, FailureRate: 0.7, } ) /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:38 # User : geovindu # Product : GoLand # Project : godesginpattern # File : exception.go */ package core import "fmt" // ServiceErr 业务基础异常 type ServiceErr struct { Msg string } func (e *ServiceErr) Error() string { return fmt.Sprintf("service error: %s", e.Msg) } // ExternalServiceErr 第三方外部服务异常 func NewExternalServiceErr(msg string) error { return &ServiceErr{Msg: msg} } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:39 # User : geovindu # Product : GoLand # Project : godesginpattern # File : base.go */ package circuitbreaker // State 断路器状态 type State string const ( StateClosed State = "CLOSED" StateOpen State = "OPEN" StateHalfOpen State = "HALF_OPEN" ) // CircuitBreaker 断路器接口 type CircuitBreaker interface { IsAllowed() bool OnSuccess() OnFailure() GetState() State } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:39 # User : geovindu # Product : GoLand # Project : godesginpattern # File : impl.go */ package circuitbreaker import ( "fmt" "godesginpattern/circuitbreaker/config" "time" ) // DefaultCircuitBreaker 默认断路器实现 type DefaultCircuitBreaker struct { failureThreshold int recoveryTimeout time.Duration successThreshold int state State failureCount int successCount int lastFailureTs int64 } func NewDefaultCircuitBreaker() *DefaultCircuitBreaker { cfg := config.CbConfig return &DefaultCircuitBreaker{ failureThreshold: cfg.FailureThreshold, recoveryTimeout: cfg.RecoveryTimeout, successThreshold: cfg.SuccessThreshold, state: StateClosed, } } func (d *DefaultCircuitBreaker) GetState() State { return d.state } func (d *DefaultCircuitBreaker) IsAllowed() bool { if d.state == StateOpen { now := time.Now().Unix() if now-d.lastFailureTs >= int64(d.recoveryTimeout.Seconds()) { d.state = StateHalfOpen d.successCount = 0 fmt.Println("🔄 断路器超时 → 进入半开状态") return true } return false } return true } func (d *DefaultCircuitBreaker) OnSuccess() { switch d.state { case StateClosed: d.failureCount = 0 case StateHalfOpen: d.successCount++ if d.successCount >= d.successThreshold { fmt.Println("✅ 半开状态连续成功 → 断路器关闭") d.reset() } } } func (d *DefaultCircuitBreaker) OnFailure() { switch d.state { case StateClosed: d.failureCount++ fmt.Printf("失败计数:%d/%d\n", d.failureCount, d.failureThreshold) if d.failureCount >= d.failureThreshold { fmt.Println("🔥 连续失败达到阈值 → 断路器打开") d.open() } case StateHalfOpen: fmt.Println("❌ 半开状态请求失败 → 重新打开断路器") d.open() } } func (d *DefaultCircuitBreaker) open() { d.state = StateOpen d.lastFailureTs = time.Now().Unix() d.successCount = 0 } func (d *DefaultCircuitBreaker) reset() { d.state = StateClosed d.failureCount = 0 d.successCount = 0 d.lastFailureTs = 0 } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:40 # User : geovindu # Product : GoLand # Project : godesginpattern # File : breaker_decorator.go */ package util import ( "fmt" "godesginpattern/circuitbreaker/config" "godesginpattern/circuitbreaker/core/circuitbreaker" ) // PriceResult 金价返回结构体 type PriceResult struct { Status string `json:"status"` GoldPrice float64 `json:"gold_price"` Message string `json:"message,omitempty"` UpdateTime string `json:"update_time,omitempty"` } // WrapBreaker 断路器包装函数(替代Python装饰器) func WrapBreaker(breaker circuitbreaker.CircuitBreaker, fn func() (PriceResult, error)) PriceResult { if !breaker.IsAllowed() { fmt.Printf("⚠️ 断路器已打开 | 当前状态:%s → 使用兜底金价\n", breaker.GetState()) return PriceResult{ Status: "fallback", Message: "断路器已开启,使用兜底数据", GoldPrice: config.JewelryConfig.FallbackGoldPrice, } } res, err := fn() if err != nil { breaker.OnFailure() fmt.Printf("❌ 请求失败 | 断路器状态:%s | 异常:%v\n", breaker.GetState(), err) return PriceResult{ Status: "error", Message: "第三方金价服务调用失败", GoldPrice: config.JewelryConfig.FallbackGoldPrice, } } breaker.OnSuccess() fmt.Printf("✅ 请求成功 | 断路器状态:%s\n", breaker.GetState()) return res }
/* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:41 # User : geovindu # Product : GoLand # Project : godesginpattern # File : inventory.go */ package service // 库存服务 // StockResp 库存返回 type StockResp struct { Weight float64 `json:"weight"` Stock string `json:"stock"` Status string `json:"status"` } // InventoryService 珠宝库存服务 type InventoryService struct{} func NewInventoryService() *InventoryService { return &InventoryService{} } // CheckGoldStock 校验黄金库存 func (i *InventoryService) CheckGoldStock(weight float64) StockResp { return StockResp{ Weight: weight, Stock: "充足", Status: "success", } } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:41 # User : geovindu # Product : GoLand # Project : godesginpattern # File : price.go */ package service import ( "godesginpattern/circuitbreaker/config" "godesginpattern/circuitbreaker/core" "godesginpattern/circuitbreaker/core/circuitbreaker" "godesginpattern/circuitbreaker/util" "math/rand" "time" ) // 第三方金价服务 var globalBreaker = circuitbreaker.NewDefaultCircuitBreaker() // PriceService 金价服务 type PriceService struct{} func NewPriceService() *PriceService { return &PriceService{} } // GetRealtimePrice 获取实时金价(熔断保护) func (p *PriceService) GetRealtimePrice() util.PriceResult { // 包装断路器逻辑 return util.WrapBreaker(globalBreaker, func() (util.PriceResult, error) { rand.Seed(time.Now().UnixNano()) if rand.Float64() < config.JewelryConfig.FailureRate { return util.PriceResult{}, core.NewExternalServiceErr("第三方金价接口超时/500错误") } price := 630 + rand.Float64()*20 return util.PriceResult{ Status: "success", GoldPrice: float64(int(price*100)) / 100, UpdateTime: time.Now().Format("2006-01-02 15:04:05"), }, nil }) } /* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:42 # User : geovindu # Product : GoLand # Project : godesginpattern # File : order.go */ package service import ( "fmt" "time" ) // Order 订单结构体 type Order struct { OrderID string `json:"order_id"` UserID string `json:"user_id"` SKU string `json:"sku"` Weight float64 `json:"weight"` GoldPrice float64 `json:"gold_price"` TotalAmount float64 `json:"total_amount"` OrderStatus string `json:"order_status"` } // OrderService 订单服务(依赖注入库存、金价服务) type OrderService struct { inventory *InventoryService price *PriceService } // NewOrderService 构造函数注入依赖 func NewOrderService(inv *InventoryService, price *PriceService) *OrderService { return &OrderService{ inventory: inv, price: price, } } // CreateGoldOrder 创建黄金珠宝订单 func (o *OrderService) CreateGoldOrder(userID string, weight float64, sku string) Order { fmt.Println("\n==================================================") fmt.Printf("[订单服务] 开始创建订单 | 用户:%s | 克重:%.1fg\n", userID, weight) // 1. 库存校验 stock := o.inventory.CheckGoldStock(weight) fmt.Printf("[库存服务] %+v\n", stock) // 2. 获取金价(带熔断) priceInfo := o.price.GetRealtimePrice() fmt.Printf("[金价服务] %+v\n", priceInfo) // 3. 计算总价 total := float64(int(weight*priceInfo.GoldPrice*100)) / 100 // 4. 生成订单 orderID := fmt.Sprintf("ORD%d", time.Now().Unix()) order := Order{ OrderID: orderID, UserID: userID, SKU: sku, Weight: weight, GoldPrice: priceInfo.GoldPrice, TotalAmount: total, OrderStatus: "PENDING_PAYMENT", } fmt.Printf("[订单服务] 订单创建成功:%+v\n", order) return order }

调用:

/* # 版权所有 2026 ©涂聚文有限公司™ ® # 许可信息查看:言語成了邀功盡責的功臣,還需要行爲每日來值班嗎 # 描述:Circuit-Breaker 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/28 21:43 # User : geovindu # Product : GoLand # Project : godesginpattern # File : circuitbreakerbll.go */ package bll import ( "fmt" "godesginpattern/circuitbreaker/service" "time" ) // CircuitBreakerBll 业务入口封装类 type CircuitBreakerBll struct{} // InitDependencies DI依赖注入容器 func (c *CircuitBreakerBll) InitDependencies() *service.OrderService { inv := service.NewInventoryService() price := service.NewPriceService() orderSvc := service.NewOrderService(inv, price) return orderSvc } // Demo 模拟连续下单测试 func (c *CircuitBreakerBll) Demo() { fmt.Println("=== 企业级珠宝订单系统(断路器模式保护)===\n") orderSvc := c.InitDependencies() // 循环10次下单 for i := 1; i <= 10; i++ { fmt.Printf("\n====== 第 %d 次下单请求 ======\n", i) order := orderSvc.CreateGoldOrder( fmt.Sprintf("USER_%d", i), 10.0, "GOLD_999_001", ) fmt.Printf("✅ 最终订单结果:%+v\n", order) time.Sleep(1 * time.Second) } } func CircuitBreakerMain() { bll := &CircuitBreakerBll{} bll.Demo() }

输出:

http://www.jsqmd.com/news/1089417/

相关文章:

  • SRC众测实战:从业务逻辑漏洞到IDOR敏感信息泄露的完整挖掘链
  • 3分钟搞定!让你的Windows任务栏变透明的TranslucentTB中文界面全攻略
  • 终极AMD Ryzen硬件调试实战:免费开源工具SMUDebugTool完整指南
  • Nucleus Co-Op:免费开源的终极分屏游戏工具,一台电脑实现多人同乐
  • Asterisk实战:打通电信IMS语音通道,让手机变身无卡座机
  • 实战解析:从EMA公式到MACD指标构建
  • RePKG深度技术解析:PKG资源提取与TEX图像转换的架构设计与性能优化
  • AMD Ryzen处理器终极调试指南:5分钟掌握SMU Debug Tool完整使用技巧
  • DNS域名系统介绍(将域名解析成IP地址)FQDN完整域名、完全限定域名、根域、TLD顶级域名、主域名、子域名、主机名(如www)、DNS查询、递归DNS、权威DNS、TTL缓存时间、DNSSEC
  • Unity Mod Manager:告别手动安装烦恼,开启游戏模组管理新时代
  • 如何快速清理重复图片:专业级存储优化工具实战指南
  • DAC53608评估板实战指南:从硬件连接到软件配置与高级测试
  • C语言实战:手把手构建RSA加密算法核心模块
  • 暗黑3终极自动化指南:D3KeyHelper免费技能循环助手完整配置
  • 如何用trackerslist彻底解决BT下载慢的问题:从龟速到极速的完整指南
  • Python操控AutoCAD终极指南:用代码解放你的设计工作
  • 为单片机通信安全选型:从算法原理到实战场景的加密方案指南
  • 智慧校园运维革新:智能锁身份核验+通断电联动,解决宿舍教室安全与成本难题
  • 东南大学学位论文LaTeX模板:从零配置到高效排版的实战指南
  • RapidOCR Docker部署实战:从零到生产环境的完整指南
  • 从实践案例解析Autosar网络管理的状态机与定时器
  • VQFN封装PCB与钢网设计实战:从热焊盘处理到焊接工艺优化
  • 3步轻松解密:RPG Maker MV游戏资源提取工具完全指南
  • 终极指南:一键掌握暗黑破坏神2角色编辑器的完整使用技巧
  • 【联盛德W806实战指南】一、搭建开发环境与一键烧录
  • O3模型冷启动延迟超2.3秒?揭秘内存预加载+权重分片预热的实时推理加速协议
  • Ubuntu NFS 共享实战:从零部署到跨主机文件访问
  • 从零开始,手把手教你玩转MSK调制(一)
  • 3分钟搞定RimWorld模组管理:RimSort终极使用指南
  • STATA绘图实战:从基础散点图到高级自定义