偶尔写点这种“小而美”的基础工具代码,其实非常解压(附代码)

张开发
2026/4/16 19:48:15 15 分钟阅读

分享文章

偶尔写点这种“小而美”的基础工具代码,其实非常解压(附代码)
写业务逻辑写累了偶尔写点这种“小而美”的基础工具代码其实非常解压。Go语言的魅力就在于它的克制。这里分享三段日常开发中极度舒适、开箱即用。1. 拯救API调用的“泛型重试机制”在对接各种不稳定的大模型API或第三方接口时写无数遍for循环和错误捕获极其劝退。自从Go 1.18引入泛型后我们可以用一段极其精简的代码把“重试”这件脏活给封装掉。舒适点泛型加持不管是返回string、struct还是啥都不返回一套代码全包容。packageutilsimport(fmttime)// Retry 泛型重试函数人生苦短绝不手写重复的重试逻辑funcRetry[T any](attemptsint,sleep time.Duration,fnfunc()(T,error))(T,error){varresult Tvarerrerrorfori:1;iattempts;i{result,errfn()iferrnil{returnresult,nil// 成功直接光荣退场}ifiattempts{fmt.Printf(调用失败正在进行第 %d 次重试: %v\n,i,err)time.Sleep(sleep)}}returnresult,fmt.Errorf(在 %d 次尝试后彻底放弃, 最终错误: %w,attempts,err)}/* 使用姿势 res, err : Retry(3, 2*time.Second, func() (string, error) { return callUnstableLLM_API(给我讲个笑话) }) */2. 告别臃肿结构的“函数式选项模式”Functional Options当你的配置项越来越多比如一个AI Client有Timeout、MaxRetries、Proxy、APIKey等如果每次都传一个巨大无比的Config结构体代码会非常难看。这也是Go官方和许多知名开源库如gRPC最推崇的初始化设计模式。舒适点扩展性拉满调用时像拼乐高一样流畅默认值处理得极其优雅。packageclientimporttime// AIClient 假设这是我们的核心客户端typeAIClientstruct{baseURLstringapiKeystringtimeout time.Duration retriesint}// Option 定义了一个改变客户端状态的函数闭包typeOptionfunc(*AIClient)// WithTimeout 选项设置超时funcWithTimeout(d time.Duration)Option{returnfunc(c*AIClient){c.timeoutd}}// WithRetries 选项设置重试次数funcWithRetries(rint)Option{returnfunc(c*AIClient){c.retriesr}}// NewAIClient 组装工厂funcNewAIClient(apiKeystring,opts...Option)*AIClient{// 1. 设置稳妥的默认值client:AIClient{baseURL:https://api.openai.com/v1,apiKey:apiKey,timeout:30*time.Second,retries:3,}// 2. 按需应用自定义选项for_,opt:rangeopts{opt(client)}returnclient}/* 使用姿势 // 极简调用全用默认值 c1 : NewAIClient(sk-123) // 高级调用按需定制不用关心参数顺序 c2 : NewAIClient(sk-123, WithTimeout(60 * time.Second), WithRetries(5), ) */3. 下班要体面极简的“优雅停机”捕获器很多系统上线后一发版就报502通常是因为服务被强杀正在处理的请求直接断了。在Go里结合os/signal和context我们只需要不到20行代码就能做到从容下线。舒适点拦截操作系统的退出信号给业务留出收尾比如保存状态、断开数据库连接的喘息时间。packageserverimport(contextfmtosos/signalsyscalltime)// WaitGracefulShutdown 阻塞等待系统信号随后执行清理动作funcWaitGracefulShutdown(cleanupFuncfunc(ctx context.Context)){// 创建一个只接收一个信号的通道sigChan:make(chanos.Signal,1)// 监听 CTRLC (SIGINT) 和 容器终止信号 (SIGTERM)signal.Notify(sigChan,syscall.SIGINT,syscall.SIGTERM)// 阻塞直到有信号砸进来sig:-sigChan fmt.Printf(\n[系统通知] 接收到退出信号: %v, 正在进入优雅停机流程...\n,sig)// 给清理工作设定一个死亡倒计时比如10秒防止清理代码死锁ctx,cancel:context.WithTimeout(context.Background(),10*time.Second)defercancel()// 执行传入的清理逻辑cleanupFunc(ctx)fmt.Println([系统通知] 清理完毕安全下线。周末愉快)}/* 使用姿势 func main() { go startMyWebServer() WaitGracefulShutdown(func(ctx context.Context) { // 在这里关闭数据库停止接收新请求等 db.Close() redis.Close() }) } */在真实的企业环境里Python让AI变聪明 Go让AI活下来如果你正在做企业级AI系统我非常建议试一次Go Python 的组合架构。

更多文章