用lsof+sed+uniq+sort+head正则 统计出连接Kafka连接最多的IP

继之前 《Kafka线上出口流量暴涨》一文的处理中,发现这个kafka连接数有点高。按照惯例,掐指一算,估计有程序没用线程池,或者没正确使用线程池。

tcp连接数

问题来了,我怎么知道kafka端口哪些IP的连接最多呢?

所以要找到这个问题,我们还得找出相关的连接,给它排序一下,好直观一点。

把问题拆解一下就是

  1. 找出所有连接到本机 kafka端口(这里是9093)的连接
  2. 从连接中提取出IP
  3. 统计出各个IP连接的数量
  4. 排序从高到低

由于案发现场没有留下截图,所以以下为非案发现场的数据,看个热闹行了。

找出所有连接到本机 kafka端口(这里是9093)的连接,并提取出IP

netstat -an|grep :9093 或者 lsof -i:9093

我比较偏爱lsof,所以就用它来做个演示,限于篇幅,我取个前10行。

-P :不打印端口名(就是显示成数字,好看点)

-n :不打印成主机名 (就是显示IP,而不是Hostname,好看点)

查看9093端口连接

从连接提取IP

正常的连接记录是这样的

java    2122 kafka  112u  IPv4 160272344      0t0  TCP xxx.xxx.3.141:9093->xxx.xxx.25.35:42488 (ESTABLISHED)
java    2122 kafka  113u  IPv4 166503245      0t0  TCP xxx.xxx.3.141:9093->xxx.xxx.25.35:52076 (ESTABLISHED)
java    2122 kafka  115u  IPv4 166503246      0t0  TCP xxx.xxx.3.141:9093->xxx.xxx.23.33:47160 (ESTABLISHED)

我们要提取出连接过来的IP,要注意以下几点:

  1. xxx.xxx.3.141 是我们本机的IP,无需统计
  2. 忽略掉端口,就提取IP出来统计

上面的例子,我们就要提出以下数据

xxx.xxx.25.35
xxx.xxx.25.35
xxx.xxx.23.33

由于每个客户端连接都是被 -> 和 : 夹着,如 ->:

所以我们用 **sed 's/.*->\([0-9|\.]*\):.*/\1/g'** 即可提取出来

[root@java_kafka_xxx.xxx.3.141 ~]#lsof -i:9093 -P -n | sed 's/.*->\([0-9|\.]*\):.*/\1/g' | head -10
COMMAND  PID  USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
xxx.xxx.8.70
xxx.xxx.25.35
xxx.xxx.8.125
xxx.xxx.7.101
xxx.xxx.23.33
xxx.xxx.4.101
xxx.xxx.7.34
xxx.xxx.24.32
xxx.xxx.4.101

统计出相同行的数量

统计相同行可以用 uniq -c 但是统计都是根据相邻行进行比较,所以最好还是先 sort 排序下

接上前面那些看起来如下:

[root@java_kafka_xxx.xxx.3.141 ~]#lsof -i:9093 -P -n|sed 's/.*->\([0-9|\.]*\):.*/\1/g' | sort | uniq -c 
     21 xxx.xxx.23.151
     13 xxx.xxx.23.152
      7 xxx.xxx.23.33
      7 xxx.xxx.24.32
      7 xxx.xxx.25.35
      7 xxx.xxx.25.46
      5 xxx.xxx.25.48
      2 xxx.xxx.25.49
      3 xxx.xxx.25.55
      2 xxx.xxx.25.56
      7 xxx.xxx.25.57
     20 xxx.xxx.31.151
     16 xxx.xxx.31.152
      2 xxx.xxx.3.140
      2 xxx.xxx.3.142
    193 xxx.xxx.31.77
    181 xxx.xxx.31.78
      8 xxx.xxx.3.84
      8 xxx.xxx.3.85
    453 xxx.xxx.4.101
    457 xxx.xxx.4.161
    468 xxx.xxx.7.101
    454 xxx.xxx.7.161
      5 xxx.xxx.7.34
      1 xxx.xxx.8.101
      2 xxx.xxx.8.109
      1 xxx.xxx.8.117
      1 xxx.xxx.8.125
      1 xxx.xxx.8.70
      1 COMMAND  PID  USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
      1 java    2122 kafka  409u  IPv4     26448      0t0  TCP xxx.xxx.3.141:9093 (LISTEN)

排序从高到低

sort -nr

-n 是按照数字从小到大排序

-r 是反向排序,这里是从大到小排序

[root@java_kafka_xxx.xxx.3.141 ~]#lsof -i:9093 -P -n|sed 's/.*->\([0-9|\.]*\):.*/\1/g' | sort | uniq -c |sort -nr
    468 xxx.xxx.7.101
    457 xxx.xxx.4.161
    454 xxx.xxx.7.161
    453 xxx.xxx.4.101
    193 xxx.xxx.31.77
    181 xxx.xxx.31.78
     21 xxx.xxx.23.151
     20 xxx.xxx.31.151
     16 xxx.xxx.31.152
     13 xxx.xxx.23.152
      8 xxx.xxx.3.85
      8 xxx.xxx.3.84
      7 xxx.xxx.25.57
      7 xxx.xxx.25.35
      7 xxx.xxx.24.32
      7 xxx.xxx.23.33
      6 xxx.xxx.25.46
      5 xxx.xxx.25.48
      4 xxx.xxx.25.55
      3 xxx.xxx.7.34
      2 xxx.xxx.8.109
      2 xxx.xxx.8.101
      2 xxx.xxx.3.142
      2 xxx.xxx.3.140
      2 xxx.xxx.25.56
      2 xxx.xxx.25.49
      1 java    2122 kafka  409u  IPv4     26448      0t0  TCP xxx.xxx.3.141:9093 (LISTEN)
      1 COMMAND  PID  USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
      1 xxx.xxx.8.70
      1 xxx.xxx.8.125
      1 xxx.xxx.8.117

如果有强迫症,觉得结果有参杂着非IP的行,不好看 可以在前面加个 grep "\->" 基本带 -> 都是连接的行

终极版

lsof -i:9093 -P -n | grep "\->" | sed 's/.*->\([0-9|\.]*\):.*/\1/g' | sort | uniq -c |sort -nr

[root@java_kafka_xxx.xxx.3.141 ~]#lsof -i:9093 -P -n | grep "\->" | sed 's/.*->\([0-9|\.]*\):.*/\1/g' | sort | uniq -c |sort -nr
    468 xxx.xxx.7.101
    457 xxx.xxx.4.161
    454 xxx.xxx.7.161
    453 xxx.xxx.4.101
    193 xxx.xxx.31.77
    181 xxx.xxx.31.78
     21 xxx.xxx.23.151
     20 xxx.xxx.31.151
     16 xxx.xxx.31.152
     13 xxx.xxx.23.152
      8 xxx.xxx.3.85
      8 xxx.xxx.3.84
      8 xxx.xxx.25.57
      8 xxx.xxx.25.35
      6 xxx.xxx.25.46
      6 xxx.xxx.24.32
      6 xxx.xxx.23.33
      5 xxx.xxx.25.48
      4 xxx.xxx.7.34
      4 xxx.xxx.25.55
      2 xxx.xxx.8.109
      2 xxx.xxx.8.101
      2 xxx.xxx.3.142
      2 xxx.xxx.3.140
      2 xxx.xxx.25.49
      1 xxx.xxx.8.70
      1 xxx.xxx.8.125
      1 xxx.xxx.8.117
      1 xxx.xxx.25.56

至此,基本找出是哪些IP的连接最多了。

后续处理

像上一篇一样,根据端口,找出是哪些程序在连接。

找到对应应用后,看了下源码,代码问题,反复创建对象来连接,没有复用到连接。

通知开发解决问题。

上线新版本后,前后连接数对比。

优化前后对比

公众号 尹安灿

Logo

Kafka开源项目指南提供详尽教程,助开发者掌握其架构、配置和使用,实现高效数据流管理和实时处理。它高性能、可扩展,适合日志收集和实时数据处理,通过持久化保障数据安全,是企业大数据生态系统的核心。

更多推荐