Home

tcpkit 介绍

一年即将过去,翻了一下博客发现更新频率比月经还来得稀疏,内疚到前列腺都萎缩了。 转入正题,本篇博客主要是分享一个自己日常用的比较多工具 tcpkit, 该工具用途主要是用来抓包和快速的分析数据包。 代码地址: git-hulk/tcpkit 1) 为什么要用它 现在抓包不有 tcpdump 么? 分析包不是有很牛逼和方便的 wireshark 么? 当然我也不是闲到前列腺发炎,浪费时间造出这么个正方形的轮子。 造这个轮子的原因是这样,我们偶尔会遇到线上访问资源(redis, mc..) 出现耗时比较长的情况。如果是 tcpdump 可以用来抓包,但如果请求量很大又是偶发,我要这么知道哪个连接慢了? 这个时候 wireshark 也是帮不上忙的(因为它不知道哪个数据是请求,那个...

Read more

beanstalkd 设计与实现

beanstalkd 是单机版本的任务队列服务, 任务队列跟消息队列在使用场景上最大的区别是: 任务之间是没有顺序约束而消息要求顺序(FIFO),且可能会对任务的状态更新而消息一般只会消费不会更新。 类似 Kafka 利用消息 FIFO 和不需要更新(不需要对消息做索引)的特性来设计消息存储,将消息读写变成磁盘的顺序读写来实现比较好的性能。而任务队列需要能够任务状态进行更新则需要对每个消息进行索引,如果把两者放到一起实现则很难实现在功能和性能上兼得。在美图内部选型上,如果是异步消息模型一般会选择消息队列,比如类似日志上报,抢购等。而对于需要延时/定时下发或者修改状态任务则是使用任务队列。 比如在以下几种场景会使用任务队列: 定时任务,如每天早上 8 点开始推送消息,定期删除过期数据等...

Read more

getaddressinfo 引发的血案

DBA 发现同一组 Redis 从库中有实例 QPS 比较高,对比发现只是其中一个从库偏高而其他从库是正常的,分布如下: 那么问题就是: 「为什么会 QPS 不均匀?」, 由于我们先上 php 业务都是长连接,QPS 不均匀应该是连接数不均带来的。然后让运维大侠统计了一下四个实例的连接数,发现确实请求量跟连接数是成线性正相关的。 2) 连接数为何不均匀? 因为这四个实例是通过域名来访问,理论上连接数应该是要比较均匀(DNS ip 轮循)。 接着当然是统计多出来的连接数是来自哪些 ip。使用 lsof 或者 redis 的 client list 都可以得到。 为什么要统计 ip 呢 确定是不是有业务有固定 ip 直连导致 确定是不是所有业务机器连接资源不均匀还是个...

Read more

oom killer 实现

作为一个不合格的开发人员多多少少都被 OOM(Out of memory) x 过,只是一般大家对于为什么被选中,可能没太考究。 简单来说之所以会出现 OOM, 就是已分配的虚拟内存大于物理内存和 Swap 分区大小,导致需要内存无法分配。如果 overcommit = 2, 在申请虚拟内存时,如果超过限制的内存比例 + Swap 空间会直接返回失败,只要分配虚拟内存不超过物理内存,也就不会有 OOM。 2) 进程选择 既然无法分配内存,就有两种下面的两种选择: 向申请内存报告申请内存失败 选择一个杀掉其他的进程来释放内存 内核 2.4 版本之前是第一种做法(走在路上听别人说的), 后面的内核版本才采用第二种。我们这里要来看的是第二种,原因很简单,因为第一种做法没...

Read more

谈谈 overcommit memory

春节前几天运维大侠说要扩容 Redis 从库但同步一直失败,看日志发现在做 bgsave 的时候一直失败。 日志如下: [41738] 04 Feb 11:16:39.859 * Full resync requested by slave. [41738] 04 Feb 11:16:39.859 * Starting BGSAVE for SYNC [41738] 04 Feb 11:16:39.860 # Can't save in background: fork: Cannot allocate memory [41738] 04 Feb 11:16:39.860 * Replication failed, can't BGSAVE 从日志可以看到 fork 的时候内存分...

Read more

php 如何检查 TCP 连接是否关闭

长连接可以减少建立连接的过程, 使用长连接可以提高服务的性能。php 很多扩展都支持长连接,如 redis, memcache, mysql 的主流扩展都支持。 我们知道长连接就是一次建立连接,使用之后不会马上释放,而是把这个连接放到连接池。那么引发的一个问题就是,我们下次使用时如何知道这个连接是否已经被关闭。 我们来看看 phpredis 是如何来判断,连接是否可用。 phpredis 检查的函数在 library.c 的 redis_check_eof 的方法,而这个方法调用的是 php 内部的方法 php_stream_eof, 我们来看这个方法的具体实现。 PHPAPI int _php_stream_eof(php_stream *stream TSRMLS_DC) {...

Read more