在Linux下搜索包含特定字符串的文件列表
这篇讲的是在Linux下搜索文件内容时,一个很实际的踩坑经历。作者原本习惯用 `find . |xargs grep` 来查找包含目标文字的文件,这个组合拳在大多数情况下都很好用。但最近他发现了一个盲区:当要搜索的字符串是Unicode编码时,这个方法会失效,导致查找不到。 问题的根因在于,`grep` 默认处理的是本地编码(如ANSI),对于以Unicode形式存储的字符串无能为力。作者分享了他的解决方案:将命令替换为 `find . |xargs strings -e l -f |grep "文字"`。这里的关键是利用了 `strings` 命令。其中,`-e l` 参数专门用于从二进制文件中提取Unicode字符串,而 `-f` 参数则会在每个匹配的字符串前打印出文件名,方便直接定位。这样,通过一个巧妙的管道组合,就解决了原先的编码识别问题,让文件内容搜索在混合编码环境下依然可靠。
NodeJS服务监控报警系统的核心实现和开源共建
这篇文章讲述了一个NodeJS开发者如何从实际需求出发,独立打造了一套名为PM25的服务监控报警系统。作者观察到,随着NodeJS服务的增多,团队迫切需要一个能统一管理集群状态、及时发现内存泄露、慢路由等异常的监控平台。商业方案如Keymetrics成本高且涉及数据外传,直接调用PM2 API又不利于多机管理和安全,于是他决定基于PM2进行二次开发。 PM25系统实现了多项实用功能:支持用户登录与服务分桶管理,提供主机与进程的实时CPU、内存等关键指标,并能整合Falcon进行历史图表查看和报警配置。它还创新性地通过扩展包收集慢路由数据,并支持云端对进程进行重启等远程控制。文章详细介绍了项目的开源结构(包含CLI、云端控制台、服务端等模块)、数据库设计以及部署拓扑。 项目的初衷是分享并推动Node生态的建设,作者期望通过代码开源,吸引更多开发者共同完善这个工具。目前,完整代码已在Github上开源。
如何从Linux系统中获取带宽、流量网络数据
这篇讲的是如何在Linux系统中,把系统记录的原始网络流量数据,转换成我们更常用的带宽指标。作者从国外云厂商(如AWS)以流量(Bytes)为单位监控网络的场景切入,引出了带宽与流量的换算关系:带宽 = 单位时间内的流量 × 8 / 时间段。核心是利用Linux系统 `/proc/net/dev` 文件,它详细记录了每块网卡收发的字节数、数据包数等信息。 文章不仅解释了字段含义,还提供了一个清晰的Shell脚本示例。这个脚本通过两次读取 `/proc/net/dev` 中的流量数据,计算差值,再结合采样时间间隔(如60秒),就能得出入向与出向的带宽(Mbps)。作者还提到,如果想简化计算,有个近似方法:直接将AWS流量数值后7位去掉,就能粗略得到带宽(单位:Mbps),虽有误差但很方便。 最后,文章做了延伸:除了整机网络数据,通过 `/proc/$PID/net/dev` 路径,还可以获取特定进程(包括虚拟机或Docker容器)的网络统计信息,为更细粒度的监控提供了思路。对于需要编写监控脚本或理解Linux网络底层数据的工程师,这是一篇很实用的指南。
Docker基础技术:DeviceMapper
这篇讲的是,当Docker首选的AUFS文件系统因为不在Linux内核主干里而无法在CentOS等发行版上使用时,DeviceMapper是如何作为第二方案来实现镜像分层的。 作者首先从内核技术入手,解释了DeviceMapper是一个高度模块化的框架,其核心是Mapped Device、Mapping Table和Target device这三个对象概念。重点在于,Docker使用了该框架中的一个关键插件——Thin Provisioning Snapshot。 文章把Thin Provisioning类比为“虚拟内存”,即逻辑上提供无限空间,但实际按需分配。Docker正是利用其Snapshot技术,通过一系列内核命令(如dmsetup)来创建精简配置池(Thin Pool)和卷,从而高效地构建和管理容器镜像的分层结构。演示部分详细展示了如何用loopback文件搭建一个Thin环境,从创建元数据和数据文件,到最终格式化并挂载一个1GB的逻辑卷,过程非常具体。 通过DeviceMapper这套基于内核块设备的机制,Docker在非Ubuntu的Linux发行版上获得了可靠的分层存储能力。
Docker基础技术:AUFS
这篇讲的是 Docker 底层存储的关键技术之一:AUFS。它是一种联合文件系统,可以把多个目录合并挂载到一个统一的视图中。文章从 AUFS 的历史八卦切入——它由冈岛顺治郎开发,却因代码量庞大(3万行)而屡次被 Linus 拒绝合入 Linux 主线,但 Ubuntu 等发行版依然广泛采用了它。 核心价值在于它的分层与合并思想。作者通过一个“水果与蔬菜”目录的生动示例,演示了 AUFS 如何将多个目录联合,并通过权限设置(最左侧目录默认可读写,其余只读)来实现修改的隔离。当修改一个文件时,改动会“写”到可写层,而不会影响只读层的原始文件,这就为快照和模板提供了基础。 这个特性正是 Docker 镜像分层的基石。文章清晰地解释了 Docker 如何利用 AUFS(以及 Btrfs、Devicemapper 等其他存储驱动)构建出只读的基础镜像层和上层可写的工作层。你甚至可以查看 Docker 实际运行时的挂载点(如 /sys/fs/aufs/),直观看到多个只读层(ro+wh)和一个可写层(rw)的组合。 最后,文章还介绍了 AUFS 的具体权限类型(rw、ro、rr)以及 whiteout 机制——如何在只读层上“删除”文件。这不仅仅是理论讲解,更提供了从内核文件系统特性到容器实践完整的技术脉络。
使用reposync同步yum源
这篇技术博客源于一个实际痛点:国内服务器同步Openstack RDO源(repos.fedorapeople.org)时面临速度慢、易中断的窘境。作者尝试使用rsync但发现源服务器未开放该服务后,找到了系统自带的`reposync`命令作为替代方案。 文章清晰地拆解了整个操作流程。首先需要安装`yum-utils`等工具包,其中包含了`reposync`这个Python脚本。接着配置好需要同步的源(如RDO源),通过`yum repolist`获取准确的源ID。核心步骤是使用`reposync --repoid=xxx`命令直接拉取,实测能在本地生成与远程源完全一致的目录结构。最后,作者提到可用Nginx将同步好的本地源对外服务。 这是一个典型的“发现工具-验证解决”的实践记录,对于需要在内网构建私有镜像源或解决跨国仓库同步问题的运维人员来说,提供了一个具体、可复现的命令行级解决方案。
《火星救援》中你应该知道的5个高可用系统故障恢复原则
这篇文章从电影《火星救援》出发,将主角马克·沃特尼的火星生存挑战,与互联网高可用系统的故障恢复实践做了精彩类比,提炼出了五条关键原则。 作者指出,故障发生时应秉持信息透明原则,及时向内部与外部同步状态,这比隐瞒问题更能赢得理解与支援。面对紧迫的恢复时限,技术负责人需在信息不全的情况下快速决策。在解决过程中,既要鼓励工程师发挥主观能动性积极尝试,也要善于利用系统预留的“救生锤”——比如那些99.9%时间不用的功能开关或旧接口。最后,当常规手段失效时,可能需要像电影里抛弃所有负重一样,采取一些简单粗暴但有效的方法来快速恢复服务,事后再进行数据修复。 文章没有停留在抽象理论,而是紧扣电影情节与技术场景的对应点,比如NASA的新闻发布会对应故障公告,探路者号对应遗留系统,让这些工程原则变得生动可感。文末那个马克在地球喝咖啡的比喻,也巧妙点出了运维人员平凡日常中的珍贵。
用GDB排查Python程序故障
这篇讲的是一个团队在Python程序非预期退出时,尝试用GDB调试解释器,但作者提供了更高效的排查思路。 团队开发的Python程序涉及子进程管理,遇到了非预期退出。最初的调试方向是用GDB追踪Python解释器中的`exit()`调用,但作者认为有更合适的切入点。文章通过一个精简的代码案例(`DebugPythonWithGDB_6.py`)重现了问题:父进程在信号处理函数`on_SIGCHLD`中尝试用`os.waitpid()`回收子进程时,抛出了`OSError: [Errno 10] No child processes`。 作者深入剖析了根因。问题出在复杂的信号与进程交互时序上:当`os.system()`产生的子进程退出并触发`SIGCHLD`信号时,该信号处理器正中断另一个子进程的处理流程。此时在信号处理器中再次调用`waitpid()`,可能因子进程已被其他地方的`wait()`回收,导致系统调用失败,Python将其封装为异常。 文章不仅展示了问题现象,还通过伪代码梳理了`os.system()`底层(从`posix_system`到`do_system`)对信号的处理逻辑,揭示了`SIGCHLD`信号在关键路径被阻塞又释放的微妙过程。它提供了一个可复现的竞争条件案例,对于理解Python子进程管理、信号处理陷阱有很好的参考价值。
Linux lsof命令使用小结
这篇讲的是 Linux 系统中一个非常实用的诊断工具——lsof 命令。作者从“一切皆文件”的Linux设计哲学出发,点明了lsof能通过查看进程打开的文件列表,来实现对系统运行状态的监控与排错。 文章首先解释了lsof能查看到常规文件、网络连接(如TCP/UDP套接字)乃至硬件设备等各类“文件”,并拆解了其输出中COMMAND、PID、FD、TYPE、NAME等关键字段的含义,让读者能看懂命令返回的信息。 其核心价值在于提供了大量排查场景的实例命令。例如,可以用来查看哪个进程占用了特定文件(如/etc/passwd)、设备(如光驱)或端口(如80端口);也能反过来根据进程名(如sendmail)或用户(如tony)来查看其打开的所有文件资源。这些用法直击运维和开发中的常见痛点。 总的来说,文章从概念到输出解读,再到丰富的实战用例,系统性地小结了lsof的使用方法,为读者提供了一份即查即用的参考。
CentOS关机与重启命令小结
这篇讲的是 CentOS 系统中那些容易混淆的关机与重启命令。作者系统地梳理了 `shutdown`、`halt`、`reboot` 等核心命令的用法和区别,重点在于帮助管理员根据实际场景选择最安全、最合适的操作方式。 文章指出,`shutdown` 是最安全、最灵活的选择。它不仅能立刻或定时重启(`-r`)与关机(`-h`),还会在执行前通知所有登录用户,并冻结新的登录请求,从而避免强制断电可能导致的数据丢失或硬件损坏。更重要的是,计划中的关机重启可以通过 `shutdown -c` 随时取消。 相比之下,`halt` 命令默认就是关机(相当于 `shutdown -h`),而 `reboot` 则用于重启。它们功能相对单一,但执行直接。文章还提到了通过 `init` 运行级别来控制系统的高级方法,比如 `init 0` 关机,`init 6` 重启。 对于系统管理员而言,理解这些命令的细微差别至关重要。需要安全关机时,优先使用 `shutdown`;需要快速重启或关机时,`reboot` 和 `halt` 更为直接。掌握这些基础但关键的命令,是进行稳定、安全的系统维护的第一步。
弹性伸缩部署
业务快速发展时流量暴增导致超时限流,业务收缩期又闲置大量服务器——这篇讲的是如何用弹性伸缩让资源“活”起来。 作者从实际运维痛点切入,介绍了弹性伸缩中间件的设计逻辑。系统通过监控集群水位、CPU队列等指标自动决策扩容缩容,并提供了观察、自动、计划三种伸缩模式。其中自动伸缩给出了具体策略:比如设置集群水位超过40%且CPU负载持续升高2分钟时扩容,低于13%且空闲持续5分钟时缩容,期望水位控制在35%左右。 文章还拆解了弹性伸缩的运维架构,包含监控大盘、成本分析和自动化部署等模块,并通过架构图和流程图展示了计算资源的动态调度模型。对于大促等可预见高峰,则支持基于业务预估的计划伸缩。 整体方案旨在让无状态应用能根据负载自动伸缩机器,既应对流量洪峰又避免资源闲置,把运维同事从反复扩缩容中解放出来。
非侵入式监控PHP应用性能监控分析
这篇讲的是如何在不触碰业务代码的前提下,对PHP应用进行性能监控。作者从“非侵入”这个实际需求出发,给出了从易到难的两种可行路径。 对于基础的请求耗时监控,最简单的方式是分析Nginx日志。文章清晰解读了日志中两个关键字段的区别:`$request_time`是端到端的总耗时,而`$upstream_response_time`则精准反映后端PHP处理的耗时。只需关注后者,就能快速定位PHP服务本身的性能瓶颈。 如果要深入分析单个请求内部的性能热点,文章详细介绍了使用xhprof扩展的完整方案。它不仅提供了xhprof的安装与配置步骤,其亮点在于展示了一套“无侵入”的部署技巧:通过Nginx的`auto_prepend_file`或php.ini配置,让监控脚本自动加载,实现了对业务代码的零修改。同时,方案还内置了按URL和超时时间智能采样的逻辑,避免了全量监控带来的性能开销。 整篇文章从日志层面的快速概览,到代码执行层面的精准剖析,形成了一套层次分明的监控方法论,为PHP开发者提供了实用的性能分析工具箱。
让我们来谈谈分工
这篇谈的是分工在技术和组织中的利弊与选择。作者从雅虎取消QA团队的新闻出发,引出一个根本问题:我们习以为常的“专职分工”,究竟是效率之源还是视野之锁? 文章回溯了亚当·斯密在《国富论》中对分工的赞许——它通过提升熟练度、减少转换损耗、催化工具创新,极大地解放了生产力,福特的流水线就是经典例证。但分工也有代价:它可能将人固化为“不思考的机器”,滋生厌倦,并带来高昂的沟通协同成本。 更深刻的剖析来自全球化视角。分工的逻辑在商业中常滑向“比较优势”,即选择成本最低者而非最合适者。这解释了外包浪潮的迁移路径,也警示了单一技能岗位的脆弱性——你的工作可能因更廉价的劳动力而消失,与你是否“全栈”无关。 最终,作者将讨论引向技术管理层面,指出理想的分工应从“基于技能的控制型”转向“基于责任心的承诺型”。技术本身既是分工的天敌(自动化可替代重复劳动),也是解决分工难题的关键。文章最后留给读者关于个人职业选择的思考:是甘为体系中一枚精密的螺丝钉,还是努力成为能应对复杂挑战的多面手?
[坑]打rpm包时,注意%post和%postun的执行顺序
这篇讲的是RPM打包中一个容易被忽略的坑:升级软件包时,错误的脚本执行顺序会导致配置被意外修改。作者在打包PHP扩展时发现,每次执行`yum update`升级成功后,新扩展在php.ini中的配置项就会被自动注释掉。 问题出在spec文件的`%postun`段。升级时,系统会先执行新包的`%post`段(安装后),再执行旧包的`%postun`段(卸载后)。作者旧包的`%postun`脚本原本是为卸载准备的,会用sed注释掉扩展配置,这就在升级过程中被误触发了。 根本原因在于`%postun`段接收的参数:参数0代表卸载,1代表升级。解决方案很直接——在`%postun`脚本中增加判断,只有当参数为0时才执行注释操作。这样升级时配置就能完好保留。文章还清晰梳理了`%pre`、`%post`、`%preun`、`%postun`在不同场景(安装、升级、卸载)下接收的参数含义,对编写可靠的spec文件很有参考价值。
看不见的成本
这篇文章从一个春节买火车票的故事说起:是花时间去排队,还是多花100块钱找黄牛?作者用这个选择引出“看不见的成本”这个核心观点——排队消耗的时间、承受的寒冷、以及最终可能一无所获的风险,都是隐藏的代价,而多付的100元可能换回更宝贵的半天自由时间和更高的确定性。 围绕这个洞见,作者进一步举了几个实际场景:招人时,主动在预期薪资上多给几千块,这笔“额外”成本带来的员工激励和价值创造,远超一次效果平平的市场投放;通勤时,为了确保准时而选择挤地铁,是用身体不适的确定成本,规避了堵车这种高风险、不可控的代价。对刚入行的年轻人,最宝贵的“成本”是时间,应优先投资于技能成长而非琐碎事务。 文章最终指向一种决策思维:在追求目标(“要赢”)的信念下,学会重新评估那些不易察觉的成本,放下眼前的执念,选择在长期看来价值最大化的路径。这不只是一本经济账,更是一种对个人时间和价值认知的清醒判断。
从构建和测试的效率说起
这篇文章从作者在EMR上执行Spark job的真实工作流出发,探讨了软件开发中一个常被忽视却极其重要的话题:构建与测试的效率优化。作者反思了自己初期因跳过本地测试阶段,直接在耗时较长的Workflow上集成测试而导致效率低下的经历,提炼出一个关键教训:测试应当分层,在成本最低的阶段尽早覆盖尽可能多的验证项,跳过大步骤往往事倍功半。 文章进一步将这种“等待的痛苦”延伸到更复杂的场景,例如将新package合并进现有版本集(version set)时,可能遭遇的依赖冲突、环境差异和调试难题,揭示了工业化软件开发中维护成本高昂的现实。 最后,作者对比了两种常见的代码分支管理策略(单分支模式与双分支模式),基于效率考量表达了对单分支模式的倾向,并点出许多团队在实践中也会不自觉地回归至此。作者以一幅经典的“程序员为何看起来很闲”的漫画作为比喻,指出频繁的上下文切换与长时间的编译等待是一种无奈的“低效勤奋”,呼吁团队将构建效率的提升置于更重要的位置——这或许比某些纯技术问题更能切实解放生产力。
ubuntu设置开机后台自动运行
这篇讲的是在Ubuntu系统中设置脚本开机自动后台运行时遇到的典型路径问题。作者从创建一个简单的Shell脚本开始,通过编辑`/etc/rc.local`文件实现开机自启,但重启后却发现日志提示“sslocal:command not found”。 问题根源在于,虽然`sslocal`命令实际存在于`/usr/local/bin/`下,但`rc.local`执行环境的PATH变量并未包含该目录,导致系统无法定位到命令。作者的解决思路很直接:将需要调用的命令文件从`/usr/local/bin/`直接移动到系统标准路径`/bin`下,从而让任何执行环境都能找到它。 这个案例清晰展示了Linux后台任务管理中容易忽略的环境差异问题。对于需要自动化运行的脚本,确保依赖的命令位于系统标准路径,或在脚本中明确指定其绝对路径,是避免此类“命令未找到”错误的关键。
git术语解释staging,index,cache
这篇讲的是Git里三个让人头疼的术语:staging、index和cache。作者从自己的困惑出发——为什么《Pro Git》里叫staging area,`git-reset`的文档里叫index,而`git-rm`的参数却是`-cached`?这三个词到底是不是一回事? 文章追溯了问题的根源,发现这其实是Linus Torvalds当年的“一念之差”。在开发Git初期,为了管理Linux内核的补丁,他设计了一个“目录缓存”来保存完整的目录树快照。这个缓存的内容结构,在源码里被存储在一个叫`index`的文件中。因此,在Git的底层实现(源码)里,操作这个缓冲区的变量都带着“cache”前缀;而“index”这个名字则因为它作为文件直观地出现在了`.git`目录里。 随着时间推移,普通用户更多通过文档而非源码接触Git,“index”成为了更通用的称呼。而“cache”一词则逐渐退居幕后,仅在讨论内部实现时使用,其过去分词“cached”则作为一个形容词保留下来,用于描述“已通过`git add`放入暂存区”的状态。通过引用git核心维护者Junio C Hamano的解释,文章理清了这三个术语的历史脉络和细微差别,帮你理解为什么同一个东西会有这么多名字。
使用Smem精确显示Linux下内存使用情况
Linux系统管理员常被“内存到底被谁吃了”这个问题困扰,尤其是当应用内存占用高但系统监控工具显示不清晰时。这篇文章介绍了一个利器——Smem。 Smem能提供比传统工具更精确的内存视图,它直接读取内核的内存映射,输出包括USS(进程独占内存)、PSS(按比例分摊的内存)和RSS等关键指标,让你一眼看清每个进程的真实“食量”。文中通过实际命令演示了它的多种用法:默认列出所有进程、用`-w`查看整体内存分布、或用`-up`按用户汇总内存占比。 文章还贴心地用图表和文字解释了VSS、RSS、PSS、USS的区别,点明了数值一般满足 VSS ≥ RSS ≥ PSS ≥ USS 的规律,帮你理解这些指标的实际意义。无论你是想排查内存泄漏,还是做容量规划,Smem都能提供更可靠的数据支撑。
SVN为什么比git更好
这篇文章的作者个人偏爱Git,但他从团队实际出发,提出了一个反向思考:在什么情况下,SVN可能是比Git更“好”的选择? 作者以一家拥有约20名程序员、使用多种语言的创业公司为背景,坦率地分析了SVN的优势。它拥有广泛的群众基础,几乎所有人都能快速上手;跨平台支持优异,尤其以Windows下的TortoiseSVN著称;核心优点是简单易用,甚至能被误用作“云端文件夹”也未引发大问题;经过十五年打磨,其功能完善且流程稳定,非常适合传统的公司制研发团队管理。 相对地,作者指出Git的主要短板在于高昂的学习成本(尤其对新人和非核心技术人员),对Windows平台支持不佳,其分布式概念和存储原理构成了一定的抽象门槛,并且过高的自由度容易因误操作给团队带来混乱。 结论是,对于研发规模中等偏上、人员背景多样的创业公司而言,如果团队协作并不涉及高频次的跨地域开源协作,SVN在降低团队协作摩擦和上手成本方面,可能是一个更务实、更稳妥的选择。