2020年1月

为什么 wireshark 里面看到的 tcp 包那么长

我们经常用 wireshark 去分析 tcp dump, 有时候, 我们会看到有些不符合我们直觉的事情, 比如下面的截图中, 你看到这个 tcp 包竟然有 36200 字节.
tcpSoLong.png

tcp 包的长度是由这个 tcp 连接在建立的时候, 2 端协商(通知更合适)而来的, 取其中小的值. 通常情况下我们接触到的都是以太网, 所以这个长度(MSS:maximum segment size)基本是 MTU(maximum transmission unit) 1500 - 20 -20 = 1460 字节. 如下图所示:
syn_mss.png

- 阅读剩余部分 -

监控指标的常见异常规则

我们收集各种层级的数据, 包括: 硬件层, hypervisor层, VM OS 层, JVM 层, 应用框架层, 应用层 或者基于 Docker 的 Node 数据, Pod 数据, Container 数据. 收集这么多数据大多数是为了出错时做分析, 不出错时做优化用. 把数据都转为时序数据后, 就可以对它们做异常检测和提前预知.
常见的异常检测是基于时间周期的, 比如每周的数据基本模式都是一样, 每天的数据模式也大致相同, 对比去年或前年的数据基本也可以用. 影响这些异常检测效果的一般有下面几种情况:

  1. 有些国家的冬令时和夏令时之间的转换;
  2. 有较大影响力的体育,政治事件, 比如美国超级碗会影响在线销售订单, 英国王室婴儿出生新闻会影响英国在线销售订单;
  3. 某些时间点的较大规模促销, 抢购会影响异常检测;
  4. 过年, 过节会影响, 这里有很大程度是因为无法发货, 或者发货也到不了导致的不购买;

- 阅读剩余部分 -

lsof 命令

lsof 是 *unx (Linux/Unix) 上的查看打开文件的命令. 由于在 Unix 体系中大部分都是文件, 所以它能查看打开的磁盘文件, 网络 socket, named pipe, 其他块设备(device)文件, 字符设备文件.
比如查看是哪个进程占用了某个端口:

sudo lsof -i :8080

比如查看某个进程打开的所有文件, 看看是不是有日志文件:

sudo lsof -p 30569

其他常见的命令例子:

lsof #显示所有打开的, 有时候你要加 sudo 去查看所有
lsof -u apache #显示用户 apache 打开的所有文件
lsof -i #显示打开的 Internet socket 文件
lsof -i 4 # IP v4
lsof -i 6 # IP v6
lsof -p <pid> #特定某个进程打开的文件
lsof -p ^<pid> #排除 非某个进程打开的所有文件
lsof -t /var/log/my.log # 显示打开这个文件的所有进程
lsof +D /var/log  #显示打开这个目录下目录或文件的所有进程
lsof -i :8080 # 显示打开端口 8080 的进程
lsof -i :80-1024 # 显示 80 到 1024 之间端口的所有进程
lsof -i udp #显示打开 udp 

如何快速确认由具体某个类引起的JVM内存泄漏

在流量大致稳定的情况下, JVM 运行一段时间之后, 它的内存使用会趋于稳定, 我们通常认为这个时候做完一次 Full GC 之后的使用内存为稳定使用内存, 一般我们对 JVM 堆(heap) 大小的设置通常对比这个值做参考, 设置年轻代, 老年代的值. 当发生内存泄漏的时候, FuLL GC 之后的内存使用量表现为逐渐增大, 直到内存全部耗尽, 频繁的发生 full GC. 对于内存泄漏的问题, 我们一般捕获 heap dump, 然后分析, 当一个或一类对象实例所直接或间接占用的内存比例非常高的时候, 或者占用巨大的时候, 我们就会怀疑该类或对象. 那么有没有在不做 heap dump 的情况下, 快速定位某个对象是不是发生内存泄漏的方法呢?

- 阅读剩余部分 -

解决 JVM AttachNotSupportedException 的问题

对于 JVM GC overhead 的问题, 通常要在 overhead 很高的时候做 heap dump, 这样捕获的 dump 文件才更有意义. 可是在 GC overhead 很高的时候, 它消耗的 CPU 也很高, 通常把机器的 CPU 全占满. 这个时候尝试去使用 jcmd, jmap 去做 heap dump, 很高的概率会得到这个异常:

com.sun.tools.attach.AttachNotSupportedException: Unable to open socket file: target process not responding or HotSpot VM not loaded
    at sun.tools.attach.LinuxVirtualMachine.<init>(LinuxVirtualMachine.java:106)
    at sun.tools.attach.LinuxAttachProvider.attachVirtualMachine(LinuxAttachProvider.java:63)
    at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:213)
    at sun.tools.jcmd.JCmd.executeCommandForPid(JCmd.java:140)
    at sun.tools.jcmd.JCmd.main(JCmd.java:129)

那么如何解决这个问题呢?

- 阅读剩余部分 -