Golang Web项目最常崩在静态资源404、并发写共享变量panic、HTTP请求不设超时三处:需用http.StripPrefix修正路径,embed.FS替代http.Dir避免路径问题;map等非并发安全,应使用sync.RWMutex或sync/atomic;HTTP客户端和服务端必须设置超时并关闭resp.Body。

Golang Web项目最常崩在三处:静态资源404、并发写共享变量 panic、HTTP请求不设超时直接拖垮服务。
http.FileServer 为什么总返回 404?
不是文件不存在,而是路径没对上——http.FileServer(http.Dir("./static")) 默认把请求路径原样拼到目录后,比如访问 /static/main.css,它会去找 ./static/static/main.css,显然错了。
- 必须用
http.StripPrefix("/static/", ...)把前缀去掉,再交给http.FileServer - 开发期可用
http.Dir("./static"),但生产环境强烈推荐embed.FS:编译进二进制,彻底避开路径错乱和文件缺失 - 别直接传字符串路径给
http.FileServer,旧版 Go 有路径遍历风险(如/static/../../etc/passwd),新版虽加了限制,但不保险
goroutine 并发修改 map 或计数器就 panic?
Go 的 map 和普通变量都不是并发安全的。多个 goroutine 同时读写一个全局 map,运行时大概率直接 crash,且错误信息只报 fatal error: concurrent map writes,不指明哪行。
- 用
sync.RWMutex包裹读写操作,写多用Lock(),读多用RLock() - 高频计数场景,优先考虑
sync/atomic(如atomic.AddInt64),比锁更轻量 - 完全避免共享状态?用 channel 做事件聚合,或改用
sync.Map(仅适合读远多于写的场景,注意它不保证迭代一致性)
HTTP 客户端/服务端为啥卡死或连接耗尽?
默认的 http.DefaultClient 和 http.ListenAndServe 都没设超时,一次慢请求可能拖住整个连接池,甚至让服务不可用。
立即学习“go语言免费学习笔记(深入)”;
- 客户端必须自定义
http.Transport:设置MaxIdleConns、IdleConnTimeout,否则空闲连接不释放,TCP 端口被占满 - 服务端务必加
ReadTimeout和WriteTimeout,例如http.Server{ReadTimeout: 5 * time.Second} - 别忽略
resp.Body.Close()—— 即使你只取status code,不关 body,底层连接就不会归还到复用池
真正难的不是写出能跑的代码,而是预判哪些地方会在高并发、长时间运行、异常网络下突然失效。比如 embed.FS 看似只是打包工具,实则消除了部署时“文件在哪”的不确定性;sync.RWMutex 也不是加个锁就完事,得想清楚读写比例、锁粒度是否过粗。这些细节不显眼,但上线后第一个凌晨报警,八成出在这儿。










