你以为 sync.Map 无锁?它的锁藏在三个地方
这套对话,我在 code review 里见过很多次。
A 说:这个 map 读多写少,并发安全得处理一下。 B 说:那把 map + RWMutex 换成 sync.Map 吧,无锁的,更快。
第一句不完全错,第二句基本错了。 …
这套对话,我在 code review 里见过很多次。
A 说:这个 map 读多写少,并发安全得处理一下。 B 说:那把 map + RWMutex 换成 sync.Map 吧,无锁的,更快。
第一句不完全错,第二句基本错了。 …
你在 HTTP 服务最外层加了 recovery middleware,以为兜底已经做完。后来某个 handler 里随手起了一个 goroutine;它空指针了,整个进程还是退出。
这不是 middleware 没挂上,也不是 …
线上有一张设备状态表,用 sync.Map 存着。
读很多,写很少。平时接口很稳,一到定时刷新那几秒,读 p99 就会抖一下。你看代码,第一反应可能不是怀疑 sync.Map,而是怀疑刷新逻辑:是不是批量太大?是不是网络抖了?是不是 GC …
接口 p99 突然抖起来,pprof 里 mutex wait 很显眼。
会议上最容易出现的三个动作是:锁太粗,换成 RWMutex;分配太多,把 buffer 放进 sync.Pool;再不行,把临界区附近的代码拆一拆。
听起来都像优化。 …
上篇讲了 Go 为什么宁可让你多传一个 ctx 参数。
这篇往下走一步:既然 context 已经显式传进来了,为什么它自己没有 Cancel()?
这件事看起来很别扭。Context 明明能被取消,Done() 明明会关闭,Err() 明 …
你写一个接口,ctx 从 handler 传到 service,再传到 repo。
中间两层明明不关心超时,也不读取 trace id,却还是要把 ctx 原样递下去。
代码看起来像这样:
|
很多人聊 Go 调度器,开口就能背:G 是 goroutine,M 是 machine,P 是 processor。
背完以后,问题来了:为什么已经有 M 这个 OS 线程,还要多一个 P?
如果这个问题答不上来,GMP 其实还没真的理解。 …
很多 Go 开发者第一次系统用 context,都会嫌它啰嗦。
一个请求从 handler 进来,service 要传 ctx,repo 要传 ctx,RPC client 要传 ctx,连中间那些根本不关心超时和取消的函数,也要机械地把 …
线上接口开始超时,goroutine 数一路往上涨。
你第一反应可能是:不是已经传了 context.WithTimeout 吗?超时到了,goroutine 不就该停了吗?
这就是 Go context 最容易被误用的地方。 …