Linux 下常用的命令 lsof
和 netstat
都可以用来列出端口以及运行在端口上的服务。
验证环境 为了验证这两个命令,在本地的一台 Ununtun 机器上部署了一个简单的 Kafka broker,端口为 9092,局域网 ip 为 192.168.31.188。在我的开发环境中,ip 为 192.168.31.51 启动了一个 kafka 生产者,在每一次生产消息后会进行休眠一段时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 public class KafkaUtil { public static void main (String[] args) { System.out.println("pid:" + getPid()); KafkaProducer<String, String> producer = createProducer(); for (int i = 0 ; i < 10 ; i++) { String time = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME); String message = "message at " + time; System.out.println("message: " + message); ProducerRecord<String, String> record = new ProducerRecord<>("test" , message); producer.send(record, (r, e) -> { if (r != null ) { System.out.printf("topic:%s, partition:%s, offset:%s\n" , r.topic(), r.partition(), r.offset()); } if (e != null ) { e.printStackTrace(); } }); threadSleep(Duration.ofMinutes(10 )); } producer.flush(); } private static KafkaProducer<String, String> createProducer () { Properties properties = new Properties(); properties.put("bootstrap.servers" , "192.168.31.188:9092" ); properties.put("key.serializer" , "org.apache.kafka.common.serialization.StringSerializer" ); properties.put("value.serializer" , "org.apache.kafka.common.serialization.StringSerializer" ); properties.put("acks" , "all" ); KafkaProducer<String, String> producer = new KafkaProducer<>(properties); return producer; } public static void threadSleep (Duration duration) { try { long millis = duration.toMillis(); Thread.sleep(millis); } catch (InterruptedException e) { } } public static int getPid () { RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); String name = runtime.getName(); try { return Integer.parseInt(name.substring(0 , name.indexOf('@' ))); } catch (Exception e) { return -1 ; } } }
启动时打印出了该程序的进程 PID: pid:23264, 此过程也可以通过 Windos 下的任务管理器查看,如果是 IDEA 中运行的,可以在 进程
的选项卡下的 IntelliJ IDEA 子进程下查看
Windos 下也有 netstat
命令来查看端口占用和相关的进程,我们找到进程 ID 为 23264 的所有连接,可以看到目标列,即为 Kafka 的 broker 监听的地址 (192.168.31.188:9092)
1 2 3 4 5 6 7 8 C:\Users\guo>netstat -ano | findstr "23264" 协议 本地地址 外部地址 状态 PID TCP 127.0 .0.1 :50281 127.0 .0.1 :50280 ESTABLISHED 23264 TCP 127.0 .0.1 :50282 127.0 .0.1 :50283 ESTABLISHED 23264 TCP 127.0 .0.1 :50283 127.0 .0.1 :50282 ESTABLISHED 23264 TCP 192.168 .31.51 :50286 192.168 .31.188 :9092 ESTABLISHED 23264 TCP 192.168 .31.51 :50288 192.168 .31.188 :9092 ESTABLISHED 23264
lsof Linux 下的 lsof
, 即 list open files, 列出已打开的文件, -i
选项列出打开的网络接口文件 ( -i select IPv[46] files)。在 kafka broker 所在机器下查看 9092 端口的使用情况,可以找到与之对应的连接:
1 2 3 4 5 6 ph@guo-lenovo:~$ sudo lsof -i -n | grep 9092 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 174961 root 95u IPv6 2748921 0t0 TCP *:9092 (LISTEN) java 174961 root 100u IPv6 2854156 0t0 TCP 192.168.31.188:9092->192.168.31.51:50286 (ESTABLISHED) java 174961 root 101u IPv6 2854157 0t0 TCP 192.168.31.188:9092->192.168.31.51:50288 (ESTABLISHED)
192.168.31.188:9092->192.168.31.51:50286
箭头前表示本地地址(Source/Local),箭头后表示外部地址(Target/Foreign)
打印所有开放的端口 根据输出的形式,可以以一个简单的脚本实现打印出当前所有的开放端口:
1 sudo lsof -i | grep -Eo ":[0-9a-zA-Z]+->" | grep -Eo "[0-9a-zA-Z]+" | sort | uniq
netstat Linux 下的 netstat
与 Windos 下的命令效果一样的:
1 2 3 4 5 6 7 8 ph@guo-lenovo:~$ netstat -tnp | grep 9092 (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) tcp6 0 0 192.168.31.188:9092 192.168.31.51:50288 ESTABLISHED - tcp6 0 0 192.168.31.188:9092 192.168.31.51:50286 ESTABLISHED -