用 errgroup 控制并发任务的首错取消与信号传播
写 Go 并发的时候,最常踩的坑不是「不会起 goroutine」,而是「起了收不回来」。典型场景:一批 RPC 要并发发起,只要有一个失败就立刻停掉其余请求并返回第一个错误;或者一批 worker 在跑,用户在终端按下 Ctrl+C,需要让所有 worker 收到信号、优雅收尾。手写 sync.WaitGroup + context.WithCancel
FWDD.NET · 技术文档站
聚焦后端工程实践:语言教程、功能实现、面试题与运维脚本。每篇都从真实踩坑场景出发,给出可直接复用的代码与取舍依据。
写 Go 并发的时候,最常踩的坑不是「不会起 goroutine」,而是「起了收不回来」。典型场景:一批 RPC 要并发发起,只要有一个失败就立刻停掉其余请求并返回第一个错误;或者一批 worker 在跑,用户在终端按下 Ctrl+C,需要让所有 worker 收到信号、优雅收尾。手写 sync.WaitGroup + context.WithCancel
itertools.groupby 是 Python 标准库里最容易被误用的函数之一。它的签名看起来像 SQL 的 GROUP BY,但语义完全不同:它只合并相邻的相同键,不做全局汇总。于是「忘了先排序」成了高频事故——数据没报错、结果却悄悄少了行或者多了组。这篇教程把 groupby 的真实语义、四种常见翻车现场、排序键的挑选技巧,以及 sort + gr
日常运维里最容易出事的不是磁盘满,而是同一个备份脚本被 crontab 和手动执行同时拉起来两份。两份 rsync 抢同一个目标目录,两份 mysqldump 同时往同一个 .sql 里写,两份日志清理脚本同时 find -delete,结果往往是文件损坏、任务卡死、负载飙高,而排查时又抓不到现场。本文给出一个不依赖 flock 之外的额外软件、只用 She
线上服务起不来,最常见的报错之一是 bind: Address already in use。这时运维第一反应是 lsof -i:8080,但你是否遇到过:ss 明明显示端口被占用,lsof 却空空如也;或者反过来,lsof 列出一堆进程,ss 只给一个 LISTEN。两个工具走的是完全不同的内核数据源,理解差异才能写出靠谱的排查与清理脚本。本文给出一套可直
消息队列重投、用户连点两次提交、定时任务因为上一次超时被重新调度——这些场景都会让同一条业务数据被写入两次。如果写入逻辑是「先 SELECT 判断存在再 INSERT」,在并发下会稳定地漏判:两个事务同时 SELECT 都没查到,然后都去 INSERT,最后要么产生两条脏数据,要么撞唯一索引报 Duplicate entry。把判断和写入压进一条 SQL,交
面试里问到 Redis 缓存问题,最常见的失分点不是不知道三个名词,而是把三者的触发条件讲混。很多候选人能把「布隆过滤器」「互斥锁」「随机过期时间」背出来,但面试官追问一句「一个不存在的 user_id 反复打进来,命中率没掉但 DB 的 QPS 涨了,这算哪种」,就答不上来了。本文按「怎么判定 → 为什么会发生 → 具体对策 → 代码怎么写 → 线上怎么验
抓 500 个 URL,串行 requests 要跑七八分钟;直接 asyncio.gather(*tasks) 全量并发又容易被目标站限流、被本地文件描述符耗尽打回 OSError: [Errno 24] Too many open files。真正可用的做法是:协程模型 + asyncio.Semaphore 限流 + aiohttp.TCPConnec
线上 Go 服务跑着跑着 RSS 从 80MB 涨到 900MB,GOMAXPROCS 没变、QPS 没涨,runtime.NumGoroutine() 却在单调上升——这类问题十有八九和 context.WithCancel 用得不对有关。本文从一次真实的内存增长切入,讲清 WithCancel 的传播语义、四种最常见的泄漏写法、如何用 pprof 和 g
线上服务器经常出这种事:某个目录本该只读,结果被人手动改了个配置文件;或者 /etc/nginx/conf.d 下突然多出一个 .conf,reload 之后整站 502。事后翻 ~/.bash_history 往往已经断档,审计日志又重又慢。真正需要的是一层极轻的「哨兵」:目录内容一变,几秒内就把变更路径、事件类型、操作者推到你面前。 inotify 是