go run -race main.go grep -n 'make(chan' -r . grep -n 'go func' -r .
服务跑着跑着直接退出,最后一行是 `fatal error: all goroutines are asleep - deadlock!`,栈里只剩 main 和一个 send,别的协程一个都没有,本地小数据量却怎么都复现不出来。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。
原因不复杂,向无缓冲 channel 发送时没有其他协程在接收,运行时发现所有协程都阻塞且不可能被唤醒,就判定为整程序死锁并终止进程,这类 panic 不会给出更细的业务信息。
这次卡住的地方就在「channel 死锁定位」这一环,单独把它拎出来验证,别和其他改动混在同一次发布里。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。
处理上按这个顺序:先看栈里阻塞的那一行到底是发送还是接收;确认接收协程是不是已经退出或者从未启动过;把这次发送改成带缓冲或者加超时选择分支。
改完只确认一件事:同样的请求再跑一遍不再退出,导出协程栈里没有长期阻塞的发送点。
