项目结构:
断路器模式是稳定性设计模式的核心之一,核心作用:当依赖服务持续失败时,自动切断请求调用,避免级联故障、耗尽系统资源,保护核心业务流程。
它有 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() }输出: