这大约是一年之前的故事了。那时我图样图森破,由于各种各样的原因,用 Vert.x 框架写了一个充斥着反模式的消息队列。那时的我刚来到阿里云,唯一擅长的架构就是无状态的系统,数据全扔数据库里,数据库前面挡一层缓存,应用服务器完全对等水平扩缩容那种。Vert.x 也是我第一次用,完全异步的开发模式把我折腾坏了,即使用了 RxJava 成功规避了回调地狱,但也深深感受到用异步框架开发复杂业务基本是痴心妄想。
当我在本地调试完成,准备部署到测试环境的虚拟机上做演示的时候,发现 JVM 因为内存不足的原因无法启动。令我百思不得其解的是,虚拟机的空闲内存(7G)远大于 JVM 申请的内存(4G),为什么会申请不到内存呢?当时我请教了专门魔改 JDK 的同事,几个年轻人凑在一起搞了一晚上,甚至他们还用 C 写了一小段代码在我那台虚拟机上复现问题,但最终还是没能找到原因。后来主管让我去咨询一个 ECS 团队的高级专家,描述了现象之后,老司机让我看一个内核参数的值,然后就说这个值太大了,参数改小之后果然药到病除。
这个神奇的内核参数便是 vm.min_free_kbytes。知道具体的参数之后,学习参数的作用是很容易的,困难的地方在于,如何从「进程申请不到大块内存」这个现象,联系到「某个内核参数不对劲」这个可能性。其实,即使我们看了内核文档,知道了参数的作用,却不会知道参数不合适的时候会有什么现象,甚至即使把参数改改,跑几个命令看看也不一定出现效果。 很大程度上,经验丰富的工程师,都是掉过无数坑又爬出来的老司机,也许处理稀松平常的问题时,不见得比年轻的工程师强太多,但是真出现了那些需要丰富经验才能定位的问题,老司机依旧游刃有余,年轻的工程师们却连头绪都找不到,更别说拿出解决方案了。 那时候我才明白,有一些事情,靠努力工作是没用的,靠看书学习是没用的,得靠长年累月地积累沉淀,长年累月地去解决各种奇怪的问题,而这些需要的是时间和机会。
转自:jamespan
|