IT技术博客大学习 共学习 共进步
首页 / 神仙的仙居
IT 2021-05-26 22:41:36 / 累计浏览 1,820

实现 go 的 goroutine 本地存储又一种方式

这篇讲的是Go语言中goroutine本地存储的一种新颖实现方案。 作者指出,Go本身没有提供便捷的goroutine本地存储,虽然可以通过`context`传递数据,但这要求在调用链上处处传递,侵入性较强。他发现Go标准库中用于性能剖析的`pprof`包里,隐藏着一个可以携带数据的`label`机制。 基于此,作者设计了一个巧妙的方案:利用其中一个label,通过一些底层技巧将一个`map`结构“塞”进去,从而在单个goroutine中携带所需的本地数据。同时,为了与标准库中基于`context`操作label的逻辑兼容,还做了相应的处理,防止数据被意外覆盖。 通过这种方式,作者将对原有pprof功能的干扰降到了最低。为此,他编写并开源了一个简洁的库:`github.com/xiezhenye/gls`,为需要goroutine本地状态的场景提供了一个侵入性较低的新选择。

IT 2016-07-17 23:52:37 / 累计浏览 2,820

一次连接超时问题排查的历程

这是一次典型的、从迷茫到顿悟的故障排查历程。作者从一个Java应用启动时偶尔发生、且目标服务器不固定的数据库连接超时问题出发,展开了一场层层深入的调查。 排查始于网络抓包,但发现了更怪异的现象:部分TCP连接的SYN包似乎从未发出,而另一些则在收到服务器SYN/ACK后被客户端立即RST。通过strace工具,作者确认了所有connect系统调用均已执行,超时发生在内核的poll等待阶段,这解释了RST的由来,但问题的源头——从系统调用到网络发包之间那段莫名的“延迟”——依然成谜。 对内核网络栈的初步探索未果后,一次未过滤ARP包的抓包带来了转机。作者发现,连接失败的IP地址对应的ARP请求首次均无响应,需等待1秒后重试才成功。这1秒的延迟,足以让设定为50毫秒的连接超时大量失败。根因在于局域网存在广播限流,导致启动时ARP请求被丢弃,而一旦应用启动成功,持续的通信就会维持ARP缓存,故运行时再无此问题。 从复杂内核栈排查到基础的ARP缓存,作者也感慨这个原因“如此操蛋没技术含量”。但这个过程生动地说明,面对诡异的系统问题,保持开放的排查思路,并扎实地追踪数据流的每一环,是定位真相的关键。

IT 2016-04-02 13:49:03 / 累计浏览 1,800

MySQL relay_log_purge=0 时的风险

这篇讲的是当MySQL设置`relay_log_purge=0`时,一个容易被忽略的数据一致性风险。很多DBA为了在高可用切换后能用上relay log补齐数据,会选择禁止自动清除,但官方文档提示这在使用`relay_log_recovery=1`时并非“崩溃安全”。 文章深入剖析了这个“地雷”的成因:在崩溃重启后,由于IO线程位置可能不准,`relay_log_recovery`会从已执行的位置重新拉取binlog并开启新的relay log。若旧的relay log被保留(`purge=0`),就可能在两个场景下出问题。一是崩溃时最后一个relay log未执行完,重启后这部分数据被重新下载,导致重复;二是如果SQL线程追赶过快,可能在IO线程尚未将relay log刷盘时就已读取执行,造成新旧文件间出现一段数据空缺。 因此,若因特殊需求必须保留relay log,在解析时务必通过binlog头信息来校验,确保数据准确无误。文章还附上了配置crash safe复制的相关参考,帮助读者从根源上稳固复制架构。

IT 2016-03-21 23:44:45 / 累计浏览 1,860

设置 linux 命令缓冲模式

这篇文章讲的是Linux系统中一个容易被忽略但很实用的细节:命令行工具在管道或重定向时的缓冲模式问题。作者从实际场景出发,点明了在使用管道处理实时数据时,命令默认的全缓冲行为会导致输出延迟,影响即时分析。 文章的核心方案是利用`stdbuf`命令来灵活控制标准输入输出的缓冲策略。作者不仅解释了`-oL`(行缓冲)、`-iL`、`-e0`(无缓冲)等参数的具体含义,还通过`stdbuf -oL tcpdump | grep`这个实例,展示了如何为本身不提供缓冲设置的命令“强行”加上行缓冲,从而实现实时输出。 这个工具的价值在于其通用性,无论目标命令是否支持缓冲参数,都能通过它来调整,解决了数据处理流水线中的阻塞等待问题,让调试和监控更即时高效。

IT 2016-03-21 13:56:01 / 累计浏览 2,800

获取 MySQL 崩溃时的 core file

这篇讲的是如何让 MySQL 在崩溃时可靠地生成 core file 用于调试。文章作者从一个常见痛点切入:即使运维人员设置了 `ulimit -c unlimited` 并且在配置中开启了 `core-file`,mysqld 在实际 crash 时可能还是不会留下核心转储文件,给故障排查带来很大障碍。 作者点明了问题的关键在于几个容易被忽略的 Linux 系统参数。因为 MySQL 进程通常以 suid 方式运行,系统默认禁止为这类进程生成 core 文件,所以需要将 `/proc/sys/fs/suid_dumpable` 的值设为 2。此外,还需要确保 `core_pattern` 指向一个明确的、有写入权限的绝对路径(例如 `/var/crash/core`),并启用 `core_uses_pid` 以方便识别。 文章没有停留在理论,而是直接给出了一套可执行的修改命令和验证方法:通过 `kill -SEGV` 主动触发崩溃,然后检查目标路径。这套从问题定位、原因剖析到具体操作验证的完整思路,对于需要处理 MySQL 底层故障的开发者和 DBA 来说非常实用。按这个流程配置并验证,就能确保获得崩溃时的诊断数据。